Store mapping
[stuffkeeper-musicbrainz.git] / src / stuffkeeper-plugin-mb.gob
blobf9ffb9199b85881f142c7a8d7b741ebfd80bd706
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_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     };
38         /* hack to get config file */
39         extern GKeyFile *config_file;
41 %}    
43 class Stuffkeeper:Plugin:Mb from Stuffkeeper:Plugin
45     private StuffkeeperDataBackend *skdb = {NULL};
46     private GladeXML *xml = {NULL};
47     private GtkListStore *album_list = {NULL};
49     private GtkListStore *schema_list = {NULL};
50     private GtkListStore *import_list = {NULL};
51     private GList *import_mapping = {NULL};
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, "vbox_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         }
70         if(self->_priv->import_mapping)
71         {
72             g_list_free(self->_priv->import_mapping);
73             self->_priv->import_mapping = NULL;
74         }
75         
76         if(gtk_combo_box_get_active_iter(combo, &iter))
77         {
78             StuffkeeperDataSchema *schema;
79             GtkWidget *exo = exo_wrap_table_new(FALSE);
80             gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
82             gtk_box_pack_start(GTK_BOX(frame), exo, FALSE, TRUE, 0);
83             if(schema)
84             {
85                 gsize size =0;
86                 int i;
87                 gchar **retv = stuffkeeper_data_schema_get_fields(schema,&size);
88                 GtkSizeGroup *group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
89                 for(i=0;i<size;i++)
90                 {
91                     int type = stuffkeeper_data_schema_get_field_type(schema, retv[i]);
92                     if( type < FIELD_TYPE_EXPANDER)
93                     {
94                                                 gint value;
95                                                 GError *error = NULL;
96                         GtkWidget *hbox = gtk_hbox_new(FALSE, 6);
97                         gchar *name = stuffkeeper_data_schema_get_field_name(schema, retv[i]);
98                         GtkWidget *label = gtk_label_new(name);
99                         gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
100                         gtk_size_group_add_widget(group, label);
101                         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
102                         GtkWidget *wid = gtk_combo_box_new();
103                         gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->import_list));
104                         GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
105                         gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
106                         gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
107                         gtk_box_pack_start(GTK_BOX(hbox), wid, FALSE, TRUE, 0);
109                                                 value = g_key_file_get_integer(config_file, "Musicbrainz plugin", retv[i], &error);
110                                                 if(error) {
111                                                         g_error_free(error);
112                                                         value = 0;
113                                                 }
114                         gtk_combo_box_set_active(GTK_COMBO_BOX(wid), value);
116                         gtk_container_add(GTK_CONTAINER(exo), hbox);
117                         g_object_set_data_full(G_OBJECT(wid), "field-id", g_strdup(retv[i]), g_free);
119                         self->_priv->import_mapping = g_list_append(self->_priv->import_mapping, wid);
121                         gtk_widget_show_all(hbox);
122                         g_free(name);
123                     }
124                 }
125                 g_strfreev(retv);
126                 g_object_unref(group);
127                 gtk_widget_show(exo);
128             }
129         }
130     }
131         /* */
132     private
133     void
134     search(self, GtkWidget *button_find)
135     {
136         int i,m;
137         const gchar *artist = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_artist")));
138         const gchar *album = gtk_entry_get_text(GTK_ENTRY(glade_xml_get_widget(self->_priv->xml, "entry_album")));
139         MbQuery query;
140         MbResultList list;
141         MbArtistFilter filter;
144         gtk_list_store_clear(self->_priv->album_list);
145         /* Create query */
146         query = mb_query_new(NULL, NULL);
148         /* Artist filter */
149         filter = mb_release_filter_new();
150         mb_release_filter_limit(filter,15); 
151         mb_release_filter_artist_name(filter,artist);
152         mb_release_filter_title(filter, album);
154         list = mb_query_get_releases(query,filter); 
155         if (!list) {
156             printf("No artist returned.\n");
157             mb_release_filter_free(filter);
158             mb_query_free(query);
159             return ;
160         }
161         m = mb_result_list_get_size(list);
162         for(i=0;i<m;i++)
163         {
164             MbRelease release = mb_result_list_get_release(list, i); 
165             MbArtist artist = mb_release_get_artist(release); 
166             char id[256],artist_r[256],album_r[256];
167             GtkTreeIter iter;
169             mb_artist_get_name(artist, artist_r, 256);
170             mb_release_get_id(release, id, 256);
171             mb_release_get_title(release, album_r,256);
172             printf("title: %s:%s\n", artist_r,album_r);
173             gtk_list_store_insert_with_values(self->_priv->album_list, &iter, -1, 
174                     0, id,
175                     1, artist_r,
176                     2,album_r,
177                     3, FALSE,
178                     -1);
180             mb_release_free(release);
181         }
182         mb_result_list_free(list);
183     }
185     private
186     void
187     close(self, gint arg,GtkWidget *dialog)
188     {
190         if(arg == -2)
191         {
192             StuffkeeperDataSchema *schema = NULL;
193             gchar *id = NULL;
194             GtkWidget *tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
195             GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
196             GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree));
197             GtkTreeIter iter;
198             if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(glade_xml_get_widget(self->_priv->xml, "combo_types")), &iter))
199             {
200                 gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
201             }
202             if(!schema) return;
204             if(gtk_tree_selection_get_selected(sel, &model, &iter))
205             {
206                 gtk_tree_model_get(model, &iter, 0, &id, -1);
208             }
209             if(!id) return;
210             MbQuery query;
211             MbReleaseIncludes inc;
212             query = mb_query_new(NULL, NULL);
213             inc = mb_release_includes_new();
214             mb_release_includes_tracks(inc);
215             mb_release_includes_artist(inc);
216             mb_release_includes_discs(inc);
217             mb_release_includes_counts(inc);
218             mb_release_includes_release_events(inc);
220             MbRelease release = mb_query_get_release_by_id(query, id, inc);
221             mb_release_includes_free(inc);
222             if(!release) return;
225             printf("Improting: %s\n", id);
226             StuffkeeperDataItem *item = stuffkeeper_data_backend_new_item(self->_priv->skdb, schema);
227             if(item)
228             {
229                 GList *node;
230                 for(node = g_list_first(self->_priv->import_mapping);node; node = g_list_next(node))
231                 {
232                     GtkWidget *combo = node->data;
233                     gchar *field = g_object_get_data(G_OBJECT(combo), "field-id");
234                     FieldType ftype = stuffkeeper_data_schema_get_field_type(schema, field);
235                     int import_type = gtk_combo_box_get_active(GTK_COMBO_BOX(combo)) -1;
236                     if(import_type == IF_ARTIST_NAME)
237                     {
238                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
239                         {
240                             MbArtist artist = mb_release_get_artist(release);
241                             printf("Adding name\n");
242                             if(artist)
243                             {
244                                 char buffer[256];
245                                 mb_artist_get_name(artist, buffer, 256);
247                                 stuffkeeper_data_item_set_string(item, field,buffer); 
248                             }
249                         }
250                     }
251                     else if (import_type == IF_ALBUM_NAME)
252                     {
253                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
254                         {
255                             char buffer[256];
256                             mb_release_get_title(release, buffer, 256);
257                             stuffkeeper_data_item_set_string(item, field,buffer); 
258                         }
259                     } else if (import_type == IF_NUM_TRACKS)
260                     {
261                         if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT || ftype == FIELD_TYPE_INTEGER)
262                         {
263                             int fields = mb_release_get_num_tracks(release);
264                             stuffkeeper_data_item_set_integer(item, field, fields);
265                         }
267                     } else if (import_type == IF_ALBUM_COVER)
268                     {
269                         if(ftype == FIELD_TYPE_IMAGE)
270                         {
271                             const gchar *path = stuffkeeper_data_backend_get_path(self->_priv->skdb);
272                             gchar buffer[256];
273                             mb_release_get_asin(release, buffer,256);
274                             if(strlen(buffer) > 0)
275                             {
276                                 gchar *value= g_strdup_printf("%i-%s.jpg", stuffkeeper_data_item_get_id(item), field);
277                                 gchar *uri = g_strdup_printf("http://images.amazon.com/images/P/%s.01.LZZZZZZZ.jpg", buffer);
278                                 gchar *dest = g_build_path(G_DIR_SEPARATOR_S, path, "images", value,NULL);
279                                 GFile *source = g_file_new_for_uri(uri);
280                                 GFile *destination = g_file_new_for_path(dest);
281                                 g_free(uri);
282                                 g_free(dest);
283                                 
284                             
285                                 if(g_file_copy(source, destination, G_FILE_COPY_OVERWRITE,NULL, NULL,NULL, NULL))
286                                 {
287                                     stuffkeeper_data_item_set_string(item, field, value);
288                                 }
289                                 g_free(value);
291                             }
292                         }
294                     } 
296                     /* Get track listing */
297                     else if (import_type == IF_TRACK_LIST)
298                     {
299                         if(ftype == FIELD_TYPE_LIST)
300                         {
301                             int i=0;
302                             gsize fields = mb_release_get_num_tracks(release);
303                             if(fields)
304                             {
305                                 gchar **list = g_malloc0((fields+1)*sizeof(gchar *));
306                                 for(i=0;i<fields;i++)
307                                 {
308                                     gchar buffer[256];
309                                     int duration = 0;
310                                     MbTrack track = mb_release_get_track(release, i);
311                                     duration = mb_track_get_duration(track)/1000;
312                                     mb_track_get_title(track, buffer, 256);
313                                     list[i] = g_strdup_printf("%02i: %s (%02i:%02i)", i+1, buffer, (int)(duration/60), duration%60);
314                                 }
315                                 stuffkeeper_data_item_set_list(item,field, (const char **)list, fields);
316                                 g_strfreev(list);
317                             }
318                         }
319                     }
321                 
322                 }
323             }
324             mb_release_free(release);
325             mb_query_free(query);
326             g_free(id);
327             return;
328         }
330                 if(self->_priv->import_mapping)
331                 {
332                         GList *node;
333                         for(node = g_list_first(self->_priv->import_mapping);node;node = g_list_next(node))
334                         {
335                                 gchar *field = g_object_get_data(G_OBJECT(node->data), "field-id");
336                                 int import_type = gtk_combo_box_get_active(GTK_COMBO_BOX(node->data));
337                                 g_key_file_set_integer(config_file, "Musicbrainz plugin", field, import_type);
338                         }
339                         g_list_free(self->_priv->import_mapping);
340                         self->_priv->import_mapping = NULL;
341                 }
342         gtk_widget_destroy(dialog);
343         g_object_unref(self->_priv->xml);
344         self->_priv->xml = NULL;
346     }
348     override (Stuffkeeper:Plugin)
349     void
350     run_menu(StuffkeeperPlugin *plugin, StuffkeeperDataBackend *skdb)
351     {
352         Self *self = SELF(plugin);
353         GtkCellRenderer *renderer;
354         /* if there is allready a gui, move it to front */
355         if(self->_priv->xml)
356         {
358             return;
359         }
360         if(!self->_priv->import_list)
361         {
362             int i;
363             GtkTreeIter iter;
364             self->_priv->import_list = gtk_list_store_new(2, G_TYPE_INT, G_TYPE_STRING);
366             gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, -1, 1, "None",-1);
367             for(i=0;i<IF_NUM_FIELDS;i++)
368             {
370                 gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, i, 1, field_names[i],-1);
371             }
372         }
374         self->_priv->xml = glade_xml_new(GLADE_PATH"mb.glade","mb_import", NULL);
375         if(!self->_priv->xml)
376         {
377             printf("Failed to open glade file\n");
378             return;
379         }
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         {
391             if(!self->_priv->schema_list)
392             {
393                 self->_priv->schema_list = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING);
394             }
395             gtk_list_store_clear( self->_priv->schema_list);
396             GList *list = stuffkeeper_data_backend_get_schemas(self->_priv->skdb);
397             if(list)
398             {
399                 GList *node;
400                 for(node = g_list_first(list);node ; node = g_list_next(node))
401                 {
402                     GtkTreeIter iter;
403                     gtk_list_store_insert_with_values(self->_priv->schema_list, &iter, -1, 
404                             0, node->data,
405                             1, stuffkeeper_data_schema_get_title(STUFFKEEPER_DATA_SCHEMA(node->data)),
406                             -1);
407                 }
408                 g_list_free(list);
409             }
410             GtkWidget *wid = glade_xml_get_widget(self->_priv->xml, "combo_types");
411             gtk_combo_box_set_model(GTK_COMBO_BOX(wid), GTK_TREE_MODEL(self->_priv->schema_list));
412             renderer = gtk_cell_renderer_text_new();
413             gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(wid),renderer, TRUE);
414             gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(wid),renderer, "text",1 );
415         }
417         GtkWidget *tree = glade_xml_get_widget(self->_priv->xml, "treeview1");
418         renderer = gtk_cell_renderer_text_new();
419         gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(tree), -1, "Artist", renderer, "text", 1, NULL);
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         gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(self->_priv->album_list));
425         /* Connect signals */
426         /* Button:Clicked */
427         g_signal_connect_swapped(
428                 glade_xml_get_widget(self->_priv->xml, "button_find"), 
429                 "clicked",
430                 G_CALLBACK(self_search),
431                 self);
432         /* ComboBox:Changed */
433         g_signal_connect_swapped(
434                 glade_xml_get_widget(self->_priv->xml, "combo_types"), 
435                 "changed",
436                 G_CALLBACK(self_mapping_update),
437                 self);
440         /* Dialog:Response */
441         g_signal_connect_swapped(
442                 glade_xml_get_widget(self->_priv->xml, "mb_import"), 
443                 "response",
444                 G_CALLBACK(self_close),
445                 self);
447         /* Show the window */
448         gtk_widget_show(glade_xml_get_widget(self->_priv->xml, "mb_import"));
449     }
454     public
455     StuffkeeperPlugin *
456         new(void)
457         {
458                 printf("Creating mb plugin\n");
459                 return STUFFKEEPER_PLUGIN(GET_NEW);
460         }
462    override (G:Object)
463    void
464    finalize(G:Object *obj)
465    {
466            Self *self = SELF(obj);
467            printf("Finalizing\n");
469            if(self->_priv->album_list)
470            {
471                    g_object_unref(self->_priv->album_list);
472                    self->_priv->album_list = NULL;
473            }
474            if(self->_priv->schema_list)
475            {
476                    g_object_unref(self->_priv->schema_list);
477                    self->_priv->schema_list = NULL;
478            }
479            if(self->_priv->import_list)
480            {
481                    g_object_unref(self->_priv->import_list);
482                    self->_priv->import_list = NULL;
483            }
484            if(self->_priv->import_mapping)
485            {
486                    g_list_free(self->_priv->import_mapping);
487                    self->_priv->import_mapping = NULL;
488            }
489    }
491    /**
492     * Information for the plugin manager
493     **/
494    override (Stuffkeeper:Plugin)
495    PluginType 
496    get_plugin_type(StuffkeeperPlugin *plugin)
497    {
498         return PLUGIN_MENU;
499    }
501    override (Stuffkeeper:Plugin)
502    const char *
503    get_name(StuffkeeperPlugin *plugin)
504    {
505         return "query MusicBrainz";
506    }