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>
11 #include "exo-wrap-table.h"
16 GType register_plugin() { return stuffkeeper_plugin_mb_get_type();}
20 typedef enum _ImportFields {
29 const char *field_names[IF_NUM_FIELDS] =
37 /* hack to get config file */
38 extern GKeyFile *config_file;
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;
56 mapping_update(self, GtkComboBox *combo)
59 GtkWidget *frame = glade_xml_get_widget(self->_priv->xml, "sw_mapping");
60 GList *list = gtk_container_get_children(GTK_CONTAINER(frame));
64 for(node = g_list_first(list); node; node = g_list_next(node))
66 gtk_widget_destroy(GTK_WIDGET(node->data));
71 if(self->_priv->import_mapping)
73 g_list_free(self->_priv->import_mapping);
74 self->_priv->import_mapping = NULL;
77 if(gtk_combo_box_get_active_iter(combo, &iter))
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);
88 gchar **retv = stuffkeeper_data_schema_get_fields(schema,&size);
89 GtkSizeGroup *group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
92 int type = stuffkeeper_data_schema_get_field_type(schema, retv[i]);
93 if( type < FIELD_TYPE_EXPANDER)
96 GtkCellRenderer *renderer;
97 GtkWidget *wid, *label;
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);
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);
130 g_object_unref(group);
131 gtk_widget_show(exo);
138 search(self, GtkWidget *button_find)
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")));
145 MbArtistFilter filter;
148 gtk_list_store_clear(self->_priv->album_list);
150 query = mb_query_new(NULL, NULL);
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);
160 printf("No artist returned.\n");
161 mb_release_filter_free(filter);
162 mb_query_free(query);
165 m = mb_result_list_get_size(list);
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];
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,
183 mb_release_free(release);
185 mb_result_list_free(list);
190 close(self, gint arg,GtkWidget *dialog)
195 StuffkeeperDataSchema *schema = 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));
201 if(gtk_combo_box_get_active_iter(GTK_COMBO_BOX(glade_xml_get_widget(self->_priv->xml, "combo_types")), &iter))
203 gtk_tree_model_get(GTK_TREE_MODEL(self->_priv->schema_list), &iter, 0, &schema, -1);
207 if(gtk_tree_selection_get_selected(sel, &model, &iter))
209 gtk_tree_model_get(model, &iter, 0, &id, -1);
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);
230 printf("Improting: %s\n", id);
231 StuffkeeperDataItem *item = stuffkeeper_data_backend_new_item(self->_priv->skdb, schema);
235 for(node = g_list_first(self->_priv->import_mapping);node; node = g_list_next(node))
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)
243 if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
245 MbArtist artist = mb_release_get_artist(release);
246 printf("Adding name\n");
250 mb_artist_get_name(artist, buffer, 256);
252 stuffkeeper_data_item_set_string(item, field,buffer);
256 else if (import_type == IF_ALBUM_NAME)
258 if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT)
261 mb_release_get_title(release, buffer, 256);
262 stuffkeeper_data_item_set_string(item, field,buffer);
264 } else if (import_type == IF_NUM_TRACKS)
266 if(ftype == FIELD_TYPE_STRING || ftype == FIELD_TYPE_TEXT || ftype == FIELD_TYPE_INTEGER)
268 int fields = mb_release_get_num_tracks(release);
269 stuffkeeper_data_item_set_integer(item, field, fields);
272 } else if (import_type == IF_ALBUM_COVER)
274 if(ftype == FIELD_TYPE_IMAGE)
276 const gchar *path = stuffkeeper_data_backend_get_path(self->_priv->skdb);
278 mb_release_get_asin(release, buffer,256);
279 if(strlen(buffer) > 0)
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);
290 if(g_file_copy(source, destination, G_FILE_COPY_OVERWRITE,NULL, NULL,NULL, NULL))
292 stuffkeeper_data_item_set_string(item, field, value);
300 /* Get track listing */
301 else if (import_type == IF_TRACK_LIST)
303 if(ftype == FIELD_TYPE_LIST)
306 gsize fields = mb_release_get_num_tracks(release);
309 gchar **list = g_malloc0((fields+1)*sizeof(gchar *));
310 for(i=0;i<fields;i++)
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);
319 stuffkeeper_data_item_set_list(item,field, (const char **)list, fields);
326 mb_release_free(release);
327 mb_query_free(query);
332 if(self->_priv->import_mapping)
335 for(node = g_list_first(self->_priv->import_mapping);node;node = g_list_next(node))
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);
341 g_list_free(self->_priv->import_mapping);
342 self->_priv->import_mapping = NULL;
344 gtk_widget_destroy(dialog);
345 g_object_unref(self->_priv->xml);
346 self->_priv->xml = NULL;
350 override (Stuffkeeper:Plugin)
352 run_menu(StuffkeeperPlugin *plugin, StuffkeeperDataBackend *skdb)
355 Self *self = SELF(plugin);
356 GtkCellRenderer *renderer;
357 GtkWidget *wid, *tree;
358 /* if there is allready a gui, move it to front */
362 if(!self->_priv->import_list)
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++)
372 gtk_list_store_insert_with_values(self->_priv->import_list, &iter, -1, 0, i, 1, field_names[i],-1);
376 self->_priv->xml = glade_xml_new(GLADE_PATH"mb.glade","mb_import", NULL);
378 if(!self->_priv->xml)
381 self->_priv->skdb = skdb;
382 if(!self->_priv->album_list)
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 */
390 if(!self->_priv->schema_list)
392 self->_priv->schema_list = gtk_list_store_new(2, G_TYPE_POINTER, G_TYPE_STRING);
394 gtk_list_store_clear( self->_priv->schema_list);
395 list = stuffkeeper_data_backend_get_schemas(self->_priv->skdb);
399 for(node = g_list_first(list);node ; node = g_list_next(node))
402 gtk_list_store_insert_with_values(self->_priv->schema_list, &iter, -1,
404 1, stuffkeeper_data_schema_get_title(STUFFKEEPER_DATA_SCHEMA(node->data)),
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");
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);
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 */
428 g_signal_connect_swapped(
429 glade_xml_get_widget(self->_priv->xml, "button_find"),
431 G_CALLBACK(self_search),
433 /* ComboBox:Changed */
434 g_signal_connect_swapped(
435 glade_xml_get_widget(self->_priv->xml, "combo_types"),
437 G_CALLBACK(self_mapping_update),
439 /* Dialog:Response */
440 g_signal_connect_swapped(
441 glade_xml_get_widget(self->_priv->xml, "mb_import"),
443 G_CALLBACK(self_close),
446 /* Show the window */
447 gtk_widget_show(glade_xml_get_widget(self->_priv->xml, "mb_import"));
457 printf("Creating mb plugin\n");
458 return STUFFKEEPER_PLUGIN(GET_NEW);
463 finalize(G:Object *obj)
465 Self *self = SELF(obj);
466 printf("Finalizing Musicbrainz plugin\n");
469 if(self->_priv->album_list) {
470 g_object_unref(self->_priv->album_list);
471 self->_priv->album_list = NULL;
473 if(self->_priv->schema_list) {
474 g_object_unref(self->_priv->schema_list);
475 self->_priv->schema_list = NULL;
477 if(self->_priv->import_list) {
478 g_object_unref(self->_priv->import_list);
479 self->_priv->import_list = NULL;
481 if(self->_priv->import_mapping) {
482 g_list_free(self->_priv->import_mapping);
483 self->_priv->import_mapping = NULL;
488 * Information for the plugin manager
490 override (Stuffkeeper:Plugin)
491 StuffkeeperPluginType
492 get_plugin_type(StuffkeeperPlugin *plugin)
497 override (Stuffkeeper:Plugin)
499 get_name(StuffkeeperPlugin *plugin)
501 return "query MusicBrainz";
504 /*I Get the icon, and use buffering */
505 override (Stuffkeeper:Plugin)
507 get_icon(Stuffkeeper:Plugin *plug)
509 GdkPixbuf *pb = NULL;
510 Self *self = SELF(plug);
512 if(self->_priv->icon)
514 return self->_priv->icon;
517 pb = gdk_pixbuf_new_from_file(GLADE_PATH"musicbrainz.png", NULL);
520 self->_priv->icon = pb;
521 /* add a reference to it */
522 g_object_ref(self->_priv->icon);