Cleanups
[stuffkeeper-musicbrainz.git] / src / stuffkeeper-plugin-mb.gob
blob572752f54219d95daeb4c99cdf0bcd2c0f4c1751
1 requires 2.0.10
2 %h{
3 #include <gtk/gtk.h>
4 #include <glade/glade.h>
5 #include <stuffkeeper/stuffkeeper-plugin.h>
6 #include <stuffkeeper/stuffkeeper-data-backend.h>
7 #include <stuffkeeper/stuffkeeper-data-item.h>
8 #include <stuffkeeper/stuffkeeper-data-schema.h>    
9 #include <musicbrainz3/mb_c.h>
10 #include <gio/gio.h>
11 #include <exo-wrap-table.h>
16     GType register_plugin() { return stuffkeeper_plugin_mb_get_type();}
17 %}    
19 %ph{
20     typedef enum _ImportFields {
21         IF_ARTIST_NAME,
22         IF_ALBUM_NAME,
23         IF_TRACK_LIST,
24         IF_NUM_TRACKS,
25         IF_ALBUM_COVER,
26         IF_NUM_FIELDS
27     }ImportFields;
29     const char *field_names[IF_NUM_FIELDS] = 
30     {
31         "Artist",
32         "Album",
33         "Track list",
34         "Num. of tracks",
35         "Album Cover"
36     };
38 %}    
40 class Stuffkeeper:Plugin:Mb from Stuffkeeper:Plugin
42     private StuffkeeperDataBackend *skdb = {NULL};
43     private GladeXML *xml = {NULL};
44     private GtkListStore *album_list = {NULL};
46     private GtkListStore *schema_list = {NULL};
47     private GtkListStore *import_list = {NULL};
48     private GList *import_mapping = {NULL};
49    
50     
51     /* mapping */
52     private
53     void
54     mapping_update(self, GtkComboBox *combo)
55     {
56         GtkTreeIter iter; 
57         GtkWidget *frame = glade_xml_get_widget(self->_priv->xml, "vbox_mapping");
58         GList *list = gtk_container_get_children(GTK_CONTAINER(frame));
59         if(list)
60         {
61             GList *node;
62             for(node = g_list_first(list); node; node = g_list_next(node))
63             {
64                 gtk_widget_destroy(GTK_WIDGET(node->data));
65             }
66             g_list_free(list);
67         }
68         if(self->_priv->import_mapping)
69         {
70             g_list_free(self->_priv->import_mapping);
71             self->_priv->import_mapping = NULL;
72         }
73         
74         if(gtk_combo_box_get_active_iter(combo, &iter))
75         {
76             StuffkeeperDataSchema *schema;
77             GtkWidget *exo = exo_wrap_table_new(FALSE);
78             gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
80             gtk_box_pack_start(GTK_BOX(frame), exo, FALSE, TRUE, 0);
81             if(schema)
82             {
83                 gsize size =0;
84                 int i;
85                 gchar **retv = stuffkeeper_data_schema_get_fields(schema,&size);
86                 GtkSizeGroup *group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
87                 for(i=0;i<size;i++)
88                 {
89                     int type = stuffkeeper_data_schema_get_field_type(schema, retv[i]);
90                     if( type < FIELD_TYPE_EXPANDER)
91                     {
92                         GtkWidget *hbox = gtk_hbox_new(FALSE, 6);
93                         gchar *name = stuffkeeper_data_schema_get_field_name(schema, retv[i]);
94                         GtkWidget *label = gtk_label_new(name);
95                         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
96                         gtk_size_group_add_widget(group, label);
97                         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
98                         GtkWidget *wid = gtk_combo_box_new();
99                         gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->import_list));
100                         GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
101                         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
102                         gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
103                         gtk_box_pack_start(GTK_BOX(hbox), wid, FALSE, TRUE, 0);
104                         gtk_combo_box_set_active(GTK_COMBO_BOX(wid), 0);
106                         gtk_container_add(GTK_CONTAINER(exo), hbox);
107                         g_object_set_data_full(G_OBJECT(wid), "field-id", g_strdup(retv[i]), g_free);
109                         self->_priv->import_mapping = g_list_append(self->_priv->import_mapping, wid);
111                         gtk_widget_show_all(hbox);
112                         g_free(name);
113                     }
114                 }
115                 g_strfreev(retv);
116                 g_object_unref(group);
117                 gtk_widget_show(exo);
118             }
119         }
120     }
121         /* */
122     private
123     void
124     search(self, GtkWidget *button_find)
125     {
126         int i,m;
127         const gchar *artist = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_artist")));
128         const gchar *album = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_album")));
129         MbQuery query;
130         MbResultList list;
131         MbArtistFilter filter;
134         gtk_list_store_clear(self->_priv->album_list);
135         /* Create query */
136         query = mb_query_new(NULL, NULL);
138         /* Artist filter */
139         filter = mb_release_filter_new();
140         mb_release_filter_limit(filter,15); 
141         mb_release_filter_artist_name(filter,artist);
142         mb_release_filter_title(filter, album);
144         list = mb_query_get_releases(query,filter); 
145         if (!list) {
146             printf("No artist returned.\n");
147             mb_release_filter_free(filter);
148             mb_query_free(query);
149             return ;
150         }
151         m = mb_result_list_get_size(list);
152         for(i=0;i<m;i++)
153         {
154             MbRelease release = mb_result_list_get_release(list, i); 
155             MbArtist artist = mb_release_get_artist(release); 
156             char id[256],artist_r[256],album_r[256];
157             GtkTreeIter iter;
159             mb_artist_get_name(artist, artist_r, 256);
160             mb_release_get_id(release, id, 256);
161             mb_release_get_title(release, album_r,256);
162             printf("title: %s:%s\n", artist_r,album_r);
163             gtk_list_store_insert_with_values(self->_priv->album_list, &iter, -1, 
164                     0, id,
165                     1, artist_r,
166                     2,album_r,
167                     3, FALSE,
168                     -1);
170             mb_release_free(release);
171         }
172         mb_result_list_free(list);
173     }
175     private
176     void
177     close(self, gint arg,GtkWidget *dialog)
178     {
179         if(arg == -2)
180         {
181             StuffkeeperDataSchema *schema = NULL;
182             gchar *id = NULL;
183             GtkWidget *tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
184             GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
185             GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
186             GtkTreeIter iter;
187             if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(glade_xml_get_widget(self->_priv->xml, "combo_types")), &iter))
188             {
189                 gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
190             }
191             if(!schema) return;
193             if(gtk_tree_selection_get_selected(sel, &model, &iter))
194             {
195                 gtk_tree_model_get(model, &iter, 0, &id, -1);
197             }
198             if(!id) return;
199             MbQuery query;
200             MbReleaseIncludes inc;
201             query = mb_query_new(NULL, NULL);
202             inc = mb_release_includes_new();
203             mb_release_includes_tracks(inc);
204             mb_release_includes_artist(inc);
205             mb_release_includes_discs(inc);
206             mb_release_includes_counts(inc);
207             mb_release_includes_release_events(inc);
209             MbRelease release = mb_query_get_release_by_id(query, id, inc);
210             mb_release_includes_free(inc);
211             if(!release) return;
214             printf("Improting: %s\n", id);
215             StuffkeeperDataItem *item = stuffkeeper_data_backend_new_item(self->_priv->skdb, schema);
216             if(item)
217             {
218                 GList *node;
219                 for(node = g_list_first(self->_priv->import_mapping);node; node = g_list_next(node))
220                 {
221                     GtkWidget *combo = node->data;
222                     gchar *field = g_object_get_data(G_OBJECT(combo), "field-id");
223                     FieldType ftype = stuffkeeper_data_schema_get_field_type(schema, field);
224                     int import_type = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) -1;
225                     if(import_type == IF_ARTIST_NAME)
226                     {
227                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
228                         {
229                             MbArtist artist = mb_release_get_artist(release);
230                             printf("Adding name\n");
231                             if(artist)
232                             {
233                                 char buffer[256];
234                                 mb_artist_get_name(artist, buffer, 256);
236                                 stuffkeeper_data_item_set_string(item, field,buffer); 
237                             }
238                         }
239                     }
240                     else if (import_type == IF_ALBUM_NAME)
241                     {
242                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
243                         {
244                             char buffer[256];
245                             mb_release_get_title(release, buffer, 256);
246                             stuffkeeper_data_item_set_string(item, field,buffer); 
247                         }
248                     } else if (import_type == IF_NUM_TRACKS)
249                     {
250                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT || ftype == FIELD_TYPE_INTEGER)
251                         {
252                             int fields = mb_release_get_num_tracks(release);
253                             stuffkeeper_data_item_set_integer(item, field, fields);
254                         }
256                     } else if (import_type == IF_ALBUM_COVER)
257                     {
258                         if(ftype == FIELD_TYPE_IMAGE)
259                         {
260                             const gchar *path = stuffkeeper_data_backend_get_path(self->_priv->skdb);
261                             gchar buffer[256];
262                             mb_release_get_asin(release, buffer,256);
263                             if(strlen(buffer) > 0)
264                             {
265                                 gchar *value= g_strdup_printf("%i-%s.jpg", stuffkeeper_data_item_get_id(item), field);
266                                 gchar *uri = g_strdup_printf("http://images.amazon.com/images/P/%s.01.LZZZZZZZ.jpg", buffer);
267                                 gchar *dest = g_build_path(G_DIR_SEPARATOR_S, path, "images", value,NULL);
268                                 GFile *source = g_file_new_for_uri(uri);
269                                 GFile *destination = g_file_new_for_path(dest);
270                                 g_free(uri);
271                                 g_free(dest);
272                                 
273                             
274                                 if(g_file_copy(source, destination, G_FILE_COPY_OVERWRITE,NULL, NULL,NULL, NULL))
275                                 {
276                                     stuffkeeper_data_item_set_string(item, field, value);
277                                 }
278                                 g_free(value);
280                             }
281                         }
283                     } 
285                     /* Get track listing */
286                     else if (import_type == IF_TRACK_LIST)
287                     {
288                         if(ftype == FIELD_TYPE_LIST)
289                         {
290                             int i=0;
291                             gsize fields = mb_release_get_num_tracks(release);
292                             if(fields)
293                             {
294                                 gchar **list = g_malloc0((fields+1)*sizeof(gchar *));
295                                 for(i=0;i<fields;i++)
296                                 {
297                                     gchar buffer[256];
298                                     int duration = 0;
299                                     MbTrack track = mb_release_get_track(release, i);
300                                     duration = mb_track_get_duration(track)/1000;
301                                     mb_track_get_title(track, buffer, 256);
302                                     list[i] = g_strdup_printf("%02i: %s (%02i:%02i)", i+1, buffer, (int)(duration/60), duration%60);
303                                 }
304                                 stuffkeeper_data_item_set_list(item,field, (const char **)list, fields);
305                                 g_strfreev(list);
306                             }
307                         }
308                     }
310                 
311                 }
312             }
313             mb_release_free(release);
314             mb_query_free(query);
315             g_free(id);
316             return;
317         }
318         gtk_widget_destroy(dialog);
319         g_object_unref(self->_priv->xml);
320         self->_priv->xml = NULL;
322     }
324     override (Stuffkeeper:Plugin)
325     void
326     run_menu(StuffkeeperPlugin *plugin, StuffkeeperDataBackend *skdb)
327     {
328         Self *self = SELF(plugin);
329         GtkCellRenderer *renderer;
330         /* if there is allready a gui, move it to front */
331         if(self->_priv->xml)
332         {
334             return;
335         }
336         if(!self->_priv->import_list)
337         {
338             int i;
339             GtkTreeIter iter;
340             self->_priv->import_list = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
342             gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, -1, 1, "None",-1);
343             for(i=0;i<IF_NUM_FIELDS;i++)
344             {
346                 gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, i, 1, field_names[i],-1);
347             }
348         }
350         self->_priv->xml = glade_xml_new(GLADE_PATH"mb.glade","mb_import", NULL);
351         if(!self->_priv->xml)
352         {
353             printf("Failed to open glade file\n");
354             return;
355         }
357         self->_priv->skdb = skdb;
358         if(!self->_priv->album_list)
359         {
360             self->_priv->album_list = gtk_list_store_new(4,
361                     G_TYPE_STRING, /* id */
362                     G_TYPE_STRING, /* artist */
363                     G_TYPE_STRING, /* album */
364                     G_TYPE_BOOLEAN ); /* import */
365         }
366         {
367             if(!self->_priv->schema_list)
368             {
369                 self->_priv->schema_list = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING);
370             }
371             gtk_list_store_clear( self->_priv->schema_list);
372             GList *list = stuffkeeper_data_backend_get_schemas(self->_priv->skdb);
373             if(list)
374             {
375                 GList *node;
376                 for(node = g_list_first(list);node ; node = g_list_next(node))
377                 {
378                     GtkTreeIter iter;
379                     gtk_list_store_insert_with_values(self->_priv->schema_list, &iter, -1, 
380                             0, node->data,
381                             1, stuffkeeper_data_schema_get_title(STUFFKEEPER_DATA_SCHEMA(node->data)),
382                             -1);
383                 }
384                 g_list_free(list);
385             }
386             GtkWidget *wid = glade_xml_get_widget(self->_priv->xml, "combo_types");
387             gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->schema_list));
388             renderer = gtk_cell_renderer_text_new();
389             gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
390             gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
391         }
393         GtkWidget *tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
394         renderer = gtk_cell_renderer_text_new();
395         gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Artist", renderer, "text", 1, NULL);
396         renderer = gtk_cell_renderer_text_new();                                                                         
397         gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Album", renderer, "text", 2, NULL);
398         gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(self->_priv->album_list));
401         /* Connect signals */
402         /* Button:Clicked */
403         g_signal_connect_swapped(
404                 glade_xml_get_widget(self->_priv->xml, "button_find"), 
405                 "clicked",
406                 G_CALLBACK(self_search),
407                 self);
408         /* ComboBox:Changed */
409         g_signal_connect_swapped(
410                 glade_xml_get_widget(self->_priv->xml, "combo_types"), 
411                 "changed",
412                 G_CALLBACK(self_mapping_update),
413                 self);
416         /* Dialog:Response */
417         g_signal_connect_swapped(
418                 glade_xml_get_widget(self->_priv->xml, "mb_import"), 
419                 "response",
420                 G_CALLBACK(self_close),
421                 self);
423         /* Show the window */
424         gtk_widget_show(glade_xml_get_widget(self->_priv->xml, "mb_import"));
425     }
430     public
431     StuffkeeperPlugin *
432         new(void)
433         {
434                 printf("Creating mb plugin\n");
435                 return STUFFKEEPER_PLUGIN(GET_NEW);
436         }
438    override (G:Object)
439    void
440    finalize(G:Object *obj)
441    {
442            Self *self = SELF(obj);
443            printf("Finalizing\n");
445            if(self->_priv->album_list)
446            {
447                    g_object_unref(self->_priv->album_list);
448                    self->_priv->album_list = NULL;
449            }
450            if(self->_priv->schema_list)
451            {
452                    g_object_unref(self->_priv->schema_list);
453                    self->_priv->schema_list = NULL;
454            }
455            if(self->_priv->import_list)
456            {
457                    g_object_unref(self->_priv->import_list);
458                    self->_priv->import_list = NULL;
459            }
460            if(self->_priv->import_mapping)
461            {
462                    g_list_free(self->_priv->import_mapping);
463                    self->_priv->import_mapping = NULL;
464            }
465    }
467    /**
468     * Information for the plugin manager
469     **/
470    override (Stuffkeeper:Plugin)
471    PluginType 
472    get_plugin_type(StuffkeeperPlugin *plugin)
473    {
474         return PLUGIN_MENU;
475    }
477    override (Stuffkeeper:Plugin)
478    const char *
479    get_name(StuffkeeperPlugin *plugin)
480    {
481         return "query MusicBrainz";
482    }