Support new api (20)
[gmpc-lyricwiki.git] / src / plugin.c
blob43139c6d3c1490ac1db307282b276fe260c4a213
1 #include <stdio.h>
2 #include <string.h>
3 #include <gtk/gtk.h>
4 #include <libxml/parser.h>
5 #include <libxml/tree.h>
6 #include <libmpd/debug_printf.h>
7 #include <gmpc/plugin.h>
8 #include <glib.h>
9 #include <gio/gio.h>
10 #include <config.h>
12 /**
13 * Get/Set enabled
15 static int lyricwiki_get_enabled()
17 return cfg_get_single_value_as_int_with_default(config, "lyricwiki-plugin", "enable", TRUE);
19 static void lyricwiki_set_enabled(int enabled)
21 cfg_set_single_value_as_int(config, "lyricwiki-plugin", "enable", enabled);
24 /* Get priority */
25 static int lyricwiki_fetch_cover_priority(void){
26 return cfg_get_single_value_as_int_with_default(config, "lyricwiki-plugin", "priority", 80);
28 static void lyricwiki_fetch_cover_priority_set(int priority){
29 cfg_set_single_value_as_int(config, "lyricwiki-plugin", "priority", priority);
31 static int lyricwiki_fetch_get_lyric(mpd_Song *song,MetaDataType type, char **path)
33 int result = 0;
34 /* Check if enabled */
35 if(lyricwiki_get_enabled() == FALSE)
37 return META_DATA_UNAVAILABLE;
39 /* Can I fetch this type? */
40 if(type != META_SONG_TXT)
42 return META_DATA_UNAVAILABLE;
44 /* Check available fields */
45 if(song->artist == NULL || song->title == NULL)
47 return META_DATA_UNAVAILABLE;
49 gchar *artist, *title;
50 int retv = META_DATA_UNAVAILABLE;
51 /* escape, for html query */
52 artist = g_uri_escape_string(song->artist, NULL, TRUE);
53 title = g_uri_escape_string(song->title, NULL, TRUE);
55 if(artist && title)
57 GFile *file = NULL;
58 GInputStream *stream = NULL;
59 /* create the uri */
60 gchar *uri_path = g_strdup_printf("http://lyricwiki.org/api.php?artist=%s&song=%s&fmt=xml",
61 artist, title);
62 printf("%s\n", uri_path);
63 file = g_file_new_for_uri(uri_path);
64 GError *error = NULL;
65 stream = (GInputStream *)g_file_read(file,NULL,&error);
66 if(stream)
68 char buffer[1024];
69 gssize size;
70 xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL);
72 printf("trying to read stream\n");
73 while((size = g_input_stream_read(stream, buffer, 1024, NULL, NULL)) > 0)
75 printf("read chunk of %i bytes\n", size);
76 xmlParseChunk(ctxt, buffer, (int)size, FALSE);
78 /* Parse last chunk */
79 if(xmlParseChunk(ctxt, "",0,TRUE)==0)
81 xmlDocPtr doc = ctxt->myDoc;
82 if(doc)
84 xmlNodePtr root = xmlDocGetRootElement(doc);
85 xmlNodePtr cur = root->xmlChildrenNode;
86 for(;cur;cur = cur->next){
87 if(xmlStrEqual(cur->name, (xmlChar *)"lyrics")){
88 xmlChar *lyric = xmlNodeGetContent(cur);
89 if(lyric && strcmp(lyric,"Not found")!= 0)
91 /* now we want to store it somewhere */
92 gchar *full_path = gmpc_get_metadata_filename(META_SONG_TXT, song, NULL);
93 /* don't need fancy writers/loaders, just dump the file. */
94 if(g_file_set_contents(full_path, lyric, -1, NULL))
96 *path = full_path;
97 retv = META_DATA_AVAILABLE;
99 else
100 g_free(full_path);
102 xmlFree(lyric);
106 xmlFreeDoc(doc);
110 g_input_stream_close(stream,NULL, NULL);
111 xmlFreeParserCtxt(ctxt);
113 else if (error)
115 printf("Failed to create stream: %s\n", error->message);
116 g_error_free(error);
117 error = NULL;
119 g_object_unref(file);
120 g_free(uri_path);
121 xmlCleanupParser();
123 else
124 printf("Failed to create stream\n");
126 if(artist) g_free(artist);
127 if(title) g_free(title);
128 return retv;
132 * Preferences
134 static void preferences_enable_cb_callback(GtkToggleButton *button, gpointer data)
136 lyricwiki_set_enabled(gtk_toggle_button_get_active(button));
138 static void preferences_construct(GtkWidget *container)
140 GtkWidget *vbox = gtk_vbox_new(FALSE, 6);
141 GtkWidget *checkbox = gtk_check_button_new_with_mnemonic("_Enable lyricwiki.org as lyric source.");
142 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), lyricwiki_get_enabled());
144 g_signal_connect(G_OBJECT(checkbox), "toggled", G_CALLBACK(preferences_enable_cb_callback), NULL);
145 gtk_box_pack_start(GTK_BOX(vbox), checkbox, FALSE, FALSE,0);
147 gtk_widget_show_all(vbox);
148 gtk_container_add(GTK_CONTAINER(container), vbox);
152 * Generic de-construct function
154 static void preferences_destroy(GtkWidget *container)
156 GtkWidget *widget = gtk_bin_get_child(GTK_BIN(container));
157 if(widget)
159 gtk_container_remove(GTK_CONTAINER(container),widget);
163 gmpcMetaDataPlugin lw_cover = {
164 .get_priority = lyricwiki_fetch_cover_priority,
165 .set_priority = lyricwiki_fetch_cover_priority_set,
166 .get_image = lyricwiki_fetch_get_lyric
169 gmpcPrefPlugin lw_pref = {
170 .construct = preferences_construct,
171 .destroy = preferences_destroy
174 int plugin_api_version = PLUGIN_API_VERSION;
176 gmpcPlugin plugin = {
177 .name = "LyricWiki.org lyric source",
178 .version = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
179 .plugin_type = GMPC_PLUGIN_META_DATA,
180 .metadata = &lw_cover,
181 .get_enabled = lyricwiki_get_enabled,
182 .set_enabled = lyricwiki_set_enabled,
183 .pref = &lw_pref