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