Fix compiling.
[stuffkeeper-musicbrainz.git] / src / stuffkeeper-plugin-mb.gob
blob7be3a87ae85c5dd3694b19eae38fd9ab7d500f1e
1 requires 2.0.10
2 %h{
3 #include <gtk/gtk.h>
4 #include <glade/glade.h>
5 #include <stuffkeeper-plugin.h>
6 #include <stuffkeeper-data-backend.h>
7 #include <stuffkeeper-data-item.h>
8 #include <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_NUM_TRACKS,
24         IF_TRACK_LIST,
25         IF_ALBUM_COVER,
26         IF_NUM_FIELDS
27     }ImportFields;
29     const char *field_names[IF_NUM_FIELDS] = 
30     {
31         "Artist",
32         "Album",
33         "Num. of tracks",
34         "Track list",
35         "Album Cover"
36     };
37         /* hack to get config file */
38         extern GKeyFile *config_file;
39 %}    
41 class Stuffkeeper:Plugin:Mb from Stuffkeeper:Plugin
43     private StuffkeeperDataBackend *skdb = {NULL};
44     private GladeXML *xml = {NULL};
45     private GtkListStore *album_list = {NULL};
47     private GtkListStore *schema_list = {NULL};
48     private GtkListStore *import_list = {NULL};
49     private GList *import_mapping = {NULL};
51     private GdkPixbuf *icon = {NULL} destroywith g_object_unref;
53     /* mapping */
54     private
55     void
56     mapping_update(self, GtkComboBox *combo)
57     {
58         GtkTreeIter iter; 
59         GtkWidget *frame = glade_xml_get_widget(self->_priv->xml, "sw_mapping");
60         GList *list = gtk_container_get_children(GTK_CONTAINER(frame));
61         if(list)
62         {
63             GList *node;
64             for(node = g_list_first(list); node; node = g_list_next(node))
65             {
66                 gtk_widget_destroy(GTK_WIDGET(node->data));
67             }
68             g_list_free(list);
69         }
71         if(self->_priv->import_mapping)
72         {
73             g_list_free(self->_priv->import_mapping);
74             self->_priv->import_mapping = NULL;
75         }
77         if(gtk_combo_box_get_active_iter(combo, &iter))
78         {
79             StuffkeeperDataSchema *schema;
80             GtkWidget *exo = exo_wrap_table_new(FALSE);
81             gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
83             gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(glade_xml_get_widget(self->_priv->xml, "sw_mapping")),exo);
84             if(schema)
85             {
86                 gsize size =0;
87                 int i;
88                 gchar **retv = stuffkeeper_data_schema_get_fields(schema,&size);
89                 GtkSizeGroup *group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
90                 for(i=0;i<size;i++)
91                 {
92                     int type = stuffkeeper_data_schema_get_field_type(schema, retv[i]);
93                     if( type < FIELD_TYPE_EXPANDER)
94                     {
95                         gint value;
96                         GtkCellRenderer *renderer;
97                         GtkWidget *wid, *label;
98                         GError *error = NULL;
99                         GtkWidget *hbox = gtk_hbox_new(FALSE, 6);
100                         gchar *name = stuffkeeper_data_schema_get_field_name(schema, retv[i]);
102                         label = gtk_label_new(name);
103                         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
104                         gtk_size_group_add_widget(group, label);
105                         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
106                         wid = gtk_combo_box_new();
107                         gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->import_list));
108                         renderer = gtk_cell_renderer_text_new();
109                         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
110                         gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
111                         gtk_box_pack_start(GTK_BOX(hbox), wid, FALSE, TRUE, 0);
113                         value = g_key_file_get_integer(config_file, "Musicbrainz plugin", retv[i], &error);
114                         if(error) {
115                             g_error_free(error);
116                             value = 0;
117                         }
118                         gtk_combo_box_set_active(GTK_COMBO_BOX(wid), value);
120                         gtk_container_add(GTK_CONTAINER(exo), hbox);
121                         g_object_set_data_full(G_OBJECT(wid), "field-id", g_strdup(retv[i]), g_free);
123                         self->_priv->import_mapping = g_list_append(self->_priv->import_mapping, wid);
125                         gtk_widget_show_all(hbox);
126                         g_free(name);
127                     }
128                 }
129                 g_strfreev(retv);
130                 g_object_unref(group);
131                 gtk_widget_show(exo);
132             }
133         }
134     }
135     /* */
136     private
137     void
138     search(self, GtkWidget *button_find)
139     {
140         int             i,m;
141         const gchar     *artist = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_artist")));
142         const gchar     *album = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_album")));
143         MbQuery         query;
144         MbResultList    list;
145         MbArtistFilter  filter;
148         gtk_list_store_clear(self->_priv->album_list);
149         /* Create query */
150         query = mb_query_new(NULL, NULL);
152         /* Artist filter */
153         filter = mb_release_filter_new();
154         mb_release_filter_limit(filter,15); 
155         mb_release_filter_artist_name(filter,artist);
156         mb_release_filter_title(filter, album);
158         list = mb_query_get_releases(query,filter); 
159         if (!list) {
160             printf("No artist returned.\n");
161             mb_release_filter_free(filter);
162             mb_query_free(query);
163             return ;
164         }
165         m = mb_result_list_get_size(list);
166         for(i=0;i<m;i++)
167         {
168             MbRelease release = mb_result_list_get_release(list, i); 
169             MbArtist artist = mb_release_get_artist(release); 
170             char id[256],artist_r[256],album_r[256];
171             GtkTreeIter iter;
173             mb_artist_get_name(artist, artist_r, 256);
174             mb_release_get_id(release, id, 256);
175             mb_release_get_title(release, album_r,256);
176             gtk_list_store_insert_with_values(self->_priv->album_list, &iter, -1, 
177                     0, id,
178                     1, artist_r,
179                     2,album_r,
180                     3, FALSE,
181                     -1);
183             mb_release_free(release);
184         }
185         mb_result_list_free(list);
186     }
188     private
189     void
190     close(self, gint arg,GtkWidget *dialog)
191     {
193         if(arg == -2)
194         {
195             StuffkeeperDataSchema *schema = NULL;
196             gchar *id = NULL;
197             GtkWidget *tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
198             GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
199             GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
200             GtkTreeIter iter;
201             if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(glade_xml_get_widget(self->_priv->xml, "combo_types")), &iter))
202             {
203                 gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
204             }
205             if(!schema) return;
207             if(gtk_tree_selection_get_selected(sel, &model, &iter))
208             {
209                 gtk_tree_model_get(model, &iter, 0, &id, -1);
211             }
212             if(!id) return;
213             MbQuery query;
214             MbReleaseIncludes inc;
215             query = mb_query_new(NULL, NULL);
216             inc = mb_release_includes_new();
219             mb_release_includes_tracks(inc);
220             mb_release_includes_artist(inc);
221             mb_release_includes_discs(inc);
222             mb_release_includes_counts(inc);
223             mb_release_includes_release_events(inc);
225             MbRelease release = mb_query_get_release_by_id(query, id, inc);
226             mb_release_includes_free(inc);
227             if(!release) return;
230             printf("Improting: %s\n", id);
231             StuffkeeperDataItem *item = stuffkeeper_data_backend_new_item(self->_priv->skdb, schema);
232             if(item)
233             {
234                 GList *node;
235                 for(node = g_list_first(self->_priv->import_mapping);node; node = g_list_next(node))
236                 {
237                     GtkWidget *combo = node->data;
238                     gchar *field = g_object_get_data(G_OBJECT(combo), "field-id");
239                     FieldType ftype = stuffkeeper_data_schema_get_field_type(schema, field);
240                     int import_type = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) -1;
241                     if(import_type == IF_ARTIST_NAME)
242                     {
243                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
244                         {
245                             MbArtist artist = mb_release_get_artist(release);
246                             printf("Adding name\n");
247                             if(artist)
248                             {
249                                 char buffer[256];
250                                 mb_artist_get_name(artist, buffer, 256);
252                                 stuffkeeper_data_item_set_string(item, field,buffer); 
253                             }
254                         }
255                     }
256                     else if (import_type == IF_ALBUM_NAME)
257                     {
258                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
259                         {
260                             char buffer[256];
261                             mb_release_get_title(release, buffer, 256);
262                             stuffkeeper_data_item_set_string(item, field,buffer); 
263                         }
264                     } else if (import_type == IF_NUM_TRACKS)
265                     {
266                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT || ftype == FIELD_TYPE_INTEGER)
267                         {
268                             int fields = mb_release_get_num_tracks(release);
269                             stuffkeeper_data_item_set_integer(item, field, fields);
270                         }
272                     } else if (import_type == IF_ALBUM_COVER)
273                     {
274                         if(ftype == FIELD_TYPE_IMAGE)
275                         {
276                             const gchar *path = stuffkeeper_data_backend_get_path(self->_priv->skdb);
277                             gchar buffer[256];
278                             mb_release_get_asin(release, buffer,256);
279                             if(strlen(buffer) > 0)
280                             {
281                                 gchar *value= g_strdup_printf("%i-%s.jpg", stuffkeeper_data_item_get_id(item), field);
282                                 gchar *uri = g_strdup_printf("http://images.amazon.com/images/P/%s.01.LZZZZZZZ.jpg", buffer);
283                                 gchar *dest = g_build_path(G_DIR_SEPARATOR_S, path, "images", value,NULL);
284                                 GFile *source = g_file_new_for_uri(uri);
285                                 GFile *destination = g_file_new_for_path(dest);
286                                 g_free(uri);
287                                 g_free(dest);
288                                 
289                             
290                                 if(g_file_copy(source, destination, G_FILE_COPY_OVERWRITE,NULL, NULL,NULL, NULL))
291                                 {
292                                     stuffkeeper_data_item_set_string(item, field, value);
293                                 }
294                                 g_free(value);
296                             }
297                         }
299                     } 
300                     /* Get track listing */
301                     else if (import_type == IF_TRACK_LIST)
302                     {
303                         if(ftype == FIELD_TYPE_LIST)
304                         {
305                             int i=0;
306                             gsize fields = mb_release_get_num_tracks(release);
307                             if(fields)
308                             {
309                                 gchar **list = g_malloc0((fields+1)*sizeof(gchar *));
310                                 for(i=0;i<fields;i++)
311                                 {
312                                     gchar buffer[256];
313                                     int duration = 0;
314                                     MbTrack track = mb_release_get_track(release, i);
315                                     duration = mb_track_get_duration(track)/1000;
316                                     mb_track_get_title(track, buffer, 256);
317                                     list[i] = g_strdup_printf("%02i: %s (%02i:%02i)", i+1, buffer, (int)(duration/60), duration%60);
318                                 }
319                                 stuffkeeper_data_item_set_list(item,field, (const char **)list, fields);
320                                 g_strfreev(list);
321                             }
322                         }
323                     }
324                 }
325             }
326             mb_release_free(release);
327             mb_query_free(query);
328             g_free(id);
329             return;
330         }
332                 if(self->_priv->import_mapping)
333                 {
334                         GList *node;
335                         for(node = g_list_first(self->_priv->import_mapping);node;node = g_list_next(node))
336                         {
337                                 gchar *field = g_object_get_data(G_OBJECT(node->data), "field-id");
338                                 int import_type = gtk_combo_box_get_active(GTK_COMBO_BOX(node->data));
339                                 g_key_file_set_integer(config_file, "Musicbrainz plugin", field, import_type);
340                         }
341                         g_list_free(self->_priv->import_mapping);
342                         self->_priv->import_mapping = NULL;
343                 }
344         gtk_widget_destroy(dialog);
345         g_object_unref(self->_priv->xml);
346         self->_priv->xml = NULL;
348     }
350     override (Stuffkeeper:Plugin)
351     void
352     run_menu(StuffkeeperPlugin *plugin, StuffkeeperDataBackend *skdb)
353     {
354         GList *list  = NULL;
355         Self *self = SELF(plugin);
356         GtkCellRenderer *renderer;
357         GtkWidget *wid, *tree;
358         /* if there is allready a gui, move it to front */
359         if(self->_priv->xml)
360             return;
362         if(!self->_priv->import_list)
363         {
364             int i;
365             GtkTreeIter iter;
366             self->_priv->import_list = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
368             gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, -1, 1, "None",-1);
369             for(i=0;i<IF_NUM_FIELDS;i++)
370             {
372                 gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, i, 1, field_names[i],-1);
373             }
374         }
376         self->_priv->xml = glade_xml_new(GLADE_PATH"mb.glade","mb_import", NULL);
378         if(!self->_priv->xml)
379             return;
381         self->_priv->skdb = skdb;
382         if(!self->_priv->album_list)
383         {
384             self->_priv->album_list = gtk_list_store_new(4,
385                     G_TYPE_STRING, /* id */
386                     G_TYPE_STRING, /* artist */
387                     G_TYPE_STRING, /* album */
388                     G_TYPE_BOOLEAN ); /* import */
389         }
390         if(!self->_priv->schema_list)
391         {
392             self->_priv->schema_list = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING);
393         }
394         gtk_list_store_clear( self->_priv->schema_list);
395         list = stuffkeeper_data_backend_get_schemas(self->_priv->skdb);
396         if(list)
397         {
398             GList *node;
399             for(node = g_list_first(list);node ; node = g_list_next(node))
400             {
401                 GtkTreeIter iter;
402                 gtk_list_store_insert_with_values(self->_priv->schema_list, &iter, -1, 
403                         0, node->data,
404                         1, stuffkeeper_data_schema_get_title(STUFFKEEPER_DATA_SCHEMA(node->data)),
405                         -1);
406             }
407             g_list_free(list);
408         }
409         wid = glade_xml_get_widget(self->_priv->xml, "combo_types");
410         gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->schema_list));
411         renderer = gtk_cell_renderer_text_new();
412         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
413         gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
415         tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
416         /* artist */
417         renderer = gtk_cell_renderer_text_new();
418         gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Artist", renderer, "text", 1, NULL);
419         /* Album */
420         renderer = gtk_cell_renderer_text_new();                                                                         
421         gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Album", renderer, "text", 2, NULL);
422         /* Add to treeview */
423         gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(self->_priv->album_list));
426         /* Connect signals */
427         /* Button:Clicked */
428         g_signal_connect_swapped(
429                 glade_xml_get_widget(self->_priv->xml, "button_find"), 
430                 "clicked",
431                 G_CALLBACK(self_search),
432                 self);
433         /* ComboBox:Changed */
434         g_signal_connect_swapped(
435                 glade_xml_get_widget(self->_priv->xml, "combo_types"), 
436                 "changed",
437                 G_CALLBACK(self_mapping_update),
438                 self);
439         /* Dialog:Response */
440         g_signal_connect_swapped(
441                 glade_xml_get_widget(self->_priv->xml, "mb_import"), 
442                 "response",
443                 G_CALLBACK(self_close),
444                 self);
446         /* Show the window */
447         gtk_widget_show(glade_xml_get_widget(self->_priv->xml, "mb_import"));
448     }
453     public
454     StuffkeeperPlugin *
455         new(void)
456         {
457                 printf("Creating mb plugin\n");
458                 return STUFFKEEPER_PLUGIN(GET_NEW);
459         }
461    override (G:Object)
462    void
463    finalize(G:Object *obj)
464    {
465            Self *self = SELF(obj);
466            printf("Finalizing Musicbrainz plugin\n");
468        /* Clear lists */
469            if(self->_priv->album_list) {
470                    g_object_unref(self->_priv->album_list);
471                    self->_priv->album_list = NULL;
472            }
473            if(self->_priv->schema_list) {
474                    g_object_unref(self->_priv->schema_list);
475                    self->_priv->schema_list = NULL;
476            }
477            if(self->_priv->import_list) {
478                    g_object_unref(self->_priv->import_list);
479                    self->_priv->import_list = NULL;
480            }
481            if(self->_priv->import_mapping) {
482                    g_list_free(self->_priv->import_mapping);
483                    self->_priv->import_mapping = NULL;
484            }
485    }
487    /**
488     * Information for the plugin manager
489     **/
490    override (Stuffkeeper:Plugin)
491    StuffkeeperPluginType 
492    get_plugin_type(StuffkeeperPlugin *plugin)
493    {
494         return PLUGIN_MENU;
495    }
497    override (Stuffkeeper:Plugin)
498    const char *
499    get_name(StuffkeeperPlugin *plugin)
500    {
501         return "query MusicBrainz";
502    }
504    /*I Get the icon, and use buffering */
505    override (Stuffkeeper:Plugin)
506    GdkPixbuf *
507    get_icon(Stuffkeeper:Plugin *plug)
508    {
509        GdkPixbuf *pb = NULL;
510        Self *self = SELF(plug);
512        if(self->_priv->icon)
513        {
514            return self->_priv->icon;
515        }
517        pb = gdk_pixbuf_new_from_file(GLADE_PATH"musicbrainz.png", NULL);
518        if(pb)
519        {
520            self->_priv->icon = pb;
521            /* add a reference to it */
522            g_object_ref(self->_priv->icon);
523            return pb;
524        }
525        return NULL;
526    }