Cleanups
[gmpc-discogs.git] / src / plugin.c
blob61fcbafdf66d1e3bec85a0969c8565f952a21372
1 #include <stdio.h>
2 #include <string.h>
3 /* gtk and lib stuff */
4 #include <gtk/gtk.h>
5 #include <glib.h>
7 #include <libxml/parser.h>
8 #include <libxml/tree.h>
9 #include <libmpd/debug_printf.h>
11 #include <gmpc/plugin.h>
12 #include <gmpc/gmpc_easy_download.h>
13 #include <gmpc/metadata.h>
15 #include <config.h>
17 #define DISCOGS_API_KEY "332020810c"
18 #define DISCOGS_API_ROOT "http://www.discogs.com/"
20 static int discogs_get_enabled()
22 return cfg_get_single_value_as_int_with_default(config, "cover-discogs", "enable", TRUE);
24 static void discogs_set_enabled(int enabled)
26 cfg_set_single_value_as_int(config, "cover-discogs", "enable", enabled);
28 static int discogs_fetch_cover_priority(void){
29 return cfg_get_single_value_as_int_with_default(config, "cover-discogs", "priority", 80);
31 static void discogs_fetch_cover_priority_set(int priority){
32 cfg_set_single_value_as_int(config, "cover-discogs", "priority", priority);
35 static xmlNodePtr get_first_node_by_name(xmlNodePtr xml, gchar *name) {
36 if(name == NULL) return NULL;
37 if(xml) {
38 xmlNodePtr c = xml->xmlChildrenNode;
39 for(;c;c=c->next) {
40 if(c->name && xmlStrEqual(c->name, (xmlChar *) name))
41 return c;
44 return NULL;
46 static int __discogs_art_get_artist_image(mpd_Song *song,char *nartist, char **path)
48 gchar *secondary = NULL;
49 gchar *primary = NULL;
50 glong psize = 0;
51 glong ssize = 0;
53 gchar *artist_uri = NULL;
54 gmpc_easy_download_struct data= {NULL, 0,-1,NULL, NULL};
55 int found = META_DATA_UNAVAILABLE;
56 char furl[1024];
58 snprintf(furl,1024,DISCOGS_API_ROOT"search?type=all&f=xml&q=%s&api_key=%s", nartist,DISCOGS_API_KEY);
59 if(gmpc_easy_download(furl, &data))
61 xmlDocPtr doc;
62 /**
63 * Get artist name
65 doc = xmlParseMemory(data.data,data.size);
66 gmpc_easy_download_clean(&data);
67 if(doc)
69 xmlNodePtr root = xmlDocGetRootElement(doc);
70 if(root)
72 /* loop through all albums */
73 xmlNodePtr cur = get_first_node_by_name(root,"exactresults");
74 if(cur)
76 xmlNodePtr cur2 = get_first_node_by_name(cur,"result");
77 if(cur2) {
78 xmlNodePtr cur3 = get_first_node_by_name(cur2,"uri");
79 if(cur3){
80 xmlChar *xurl = xmlNodeGetContent(cur3);
81 artist_uri = g_strdup((char *)xurl);
82 xmlFree(xurl);
90 if(artist_uri) {
91 snprintf(furl,1024,"%s?f=xml&api_key=%s", artist_uri,DISCOGS_API_KEY);
92 if(gmpc_easy_download(furl, &data))
94 xmlDocPtr doc;
95 doc = xmlParseMemory(data.data,data.size);
96 gmpc_easy_download_clean(&data);
97 if(doc)
99 xmlNodePtr root = xmlDocGetRootElement(doc);
100 if(root)
102 /* loop through all albums */
103 xmlNodePtr cur = get_first_node_by_name(root,"artist");
104 if(cur)
106 xmlNodePtr cur2 = get_first_node_by_name(cur,"images");
107 if(cur2) {
108 xmlNodePtr cur3 = get_first_node_by_name(cur2,"image");
109 while(cur3 && *path == NULL){
110 xmlChar *temp = xmlGetProp(cur3, (xmlChar *)"type");
111 if(temp){
112 if(xmlStrEqual(temp, (xmlChar *)"primary"))
114 xmlChar *xurl = xmlGetProp(cur3, (xmlChar *)"uri");
115 xmlChar *size = xmlGetProp(cur3, (xmlChar *)"height");
116 glong s = (gulong)g_ascii_strtoll((gchar *)size,NULL, 10);
117 if(s > psize) {
118 psize = s;
119 if(primary) g_free(secondary);
120 primary = g_strdup((gchar *)xurl);
122 if(xurl) xmlFree(xurl);
123 if(size) xmlFree(size);
124 } else if(xmlStrEqual(temp, (xmlChar *)"secondary"))
126 xmlChar *xurl = xmlGetProp(cur3, (xmlChar *)"uri");
127 xmlChar *size = xmlGetProp(cur3, (xmlChar *)"height");
128 glong s = (gulong)g_ascii_strtoll((gchar *)size,NULL, 10);
129 if(s > ssize) {
130 ssize = s;
131 if(secondary) g_free(secondary);
132 secondary = g_strdup((gchar *)xurl);
134 if(xurl) xmlFree(xurl);
135 if(size) xmlFree(size);
138 xmlFree(temp);
140 cur3 = cur3->next;
147 gmpc_easy_download_clean(&data);
150 if(artist_uri) g_free(artist_uri);
151 if(primary || secondary)
153 gmpc_easy_download((const char *)(primary)?primary:secondary, &data);
154 if(data.size){
155 FILE *fp = NULL;
156 char *imgpath = NULL;
157 imgpath = gmpc_get_metadata_filename(META_ARTIST_ART, song, "jpg");
158 fp = fopen(imgpath, "wb");
159 if(fp)
161 size_t size;
162 size = fwrite(data.data, sizeof(char), data.size,fp);
163 if(size != data.size){
164 debug_printf(DEBUG_ERROR, "Something went wrong writing image to file");
166 fclose(fp);
168 *path = imgpath;
169 found = META_DATA_AVAILABLE;
170 debug_printf(DEBUG_INFO,"Found cover art, returning\n");
172 gmpc_easy_download_clean(&data);
174 if(primary) g_free(primary);
175 if(secondary) g_free(secondary);
176 return found;
179 static int __discogs_art_get_album_image(mpd_Song *song,char *nartist,char *nalbum, char **path)
181 gchar *secondary = NULL;
182 gchar *primary = NULL;
183 glong psize = 0;
184 glong ssize = 0;
187 gchar *artist_uri = NULL;
188 gmpc_easy_download_struct data= {NULL, 0,-1,NULL, NULL};
189 int found = META_DATA_UNAVAILABLE;
190 char furl[1024];
193 snprintf(furl,1024,DISCOGS_API_ROOT"search?type=all&f=xml&q=%s%%20%s&api_key=%s", nartist,nalbum,DISCOGS_API_KEY);
194 if(gmpc_easy_download(furl, &data))
196 xmlDocPtr doc;
198 * Get artist name
200 doc = xmlParseMemory(data.data,data.size);
201 gmpc_easy_download_clean(&data);
202 if(doc)
204 xmlNodePtr root = xmlDocGetRootElement(doc);
205 if(root)
207 /* loop through all albums */
208 xmlNodePtr cur = get_first_node_by_name(root,"searchresults");
209 if(cur)
211 xmlNodePtr cur2 = get_first_node_by_name(cur,"result");
212 if(cur2) {
213 xmlNodePtr cur4 = get_first_node_by_name(cur2,"title");
214 if(cur4){
215 xmlChar *title = xmlNodeGetContent(cur4);
216 /** Todo make this check fuzzy */
217 if(title && strstr((char *)title, song->album))
219 xmlNodePtr cur3 = get_first_node_by_name(cur2,"uri");
220 if(cur3){
221 xmlChar *xurl = xmlNodeGetContent(cur3);
222 artist_uri = g_strdup((char *)xurl);
223 xmlFree(xurl);
226 if(title)xmlFree(title);
234 if(artist_uri) {
235 snprintf(furl,1024,"%s?f=xml&api_key=%s", artist_uri,DISCOGS_API_KEY);
237 if(gmpc_easy_download(furl, &data))
239 xmlDocPtr doc;
241 doc = xmlParseMemory(data.data,data.size);
242 gmpc_easy_download_clean(&data);
243 if(doc)
245 xmlNodePtr root = xmlDocGetRootElement(doc);
246 if(root)
248 /* loop through all albums */
249 xmlNodePtr cur = get_first_node_by_name(root,"release");
250 if(cur)
252 xmlNodePtr cur2 = get_first_node_by_name(cur,"images");
253 if(cur2) {
254 xmlNodePtr cur3 = get_first_node_by_name(cur2,"image");
255 while(cur3 && *path == NULL){
256 xmlChar *temp = xmlGetProp(cur3, (xmlChar *)"type");
258 if(temp){
259 if(xmlStrEqual(temp, (xmlChar *)"primary"))
261 xmlChar *xurl = xmlGetProp(cur3, (xmlChar *)"uri");
262 xmlChar *size = xmlGetProp(cur3, (xmlChar *)"height");
263 glong s = (gulong)g_ascii_strtoll((char *)size,NULL, 10);
264 if(s > psize) {
265 psize = s;
266 if(primary) g_free(primary);
267 primary = g_strdup((char *)xurl);
269 if(xurl) xmlFree(xurl);
270 if(size) xmlFree(size);
271 } else if(xmlStrEqual(temp, (xmlChar *)"secondary"))
273 xmlChar *xurl = xmlGetProp(cur3, (xmlChar *)"uri");
274 xmlChar *size = xmlGetProp(cur3, (xmlChar *)"height");
275 glong s = (gulong)g_ascii_strtoll((char *)size,NULL, 10);
276 if(s > ssize) {
277 ssize = s;
278 if(secondary) g_free(secondary);
279 secondary = g_strdup((char *)xurl);
281 if(xurl) xmlFree(xurl);
282 if(size) xmlFree(size);
285 xmlFree(temp);
287 cur3 = cur3->next;
294 gmpc_easy_download_clean(&data);
297 if(artist_uri) g_free(artist_uri);
298 if(primary || secondary)
300 gmpc_easy_download((const char *)(primary)?primary:secondary, &data);
301 if(data.size){
302 FILE *fp = NULL;
303 char *imgpath = NULL;
304 imgpath = gmpc_get_metadata_filename(META_ALBUM_ART, song, "jpg");
305 fp = fopen(imgpath, "wb");
306 if(fp)
308 size_t size;
309 size = fwrite(data.data, sizeof(char), data.size,fp);
310 if(size != data.size){
311 debug_printf(DEBUG_ERROR, "Something went wrong writing image to file");
313 fclose(fp);
315 *path = imgpath;
316 found = META_DATA_AVAILABLE;
317 debug_printf(DEBUG_INFO,"Found cover art, returning\n");
319 gmpc_easy_download_clean(&data);
321 if(primary) g_free(primary);
322 if(secondary) g_free(secondary);
323 return found;
326 /** other */
327 static int discogs_fetch_cover_album_art(mpd_Song *song, char **path)
329 int retval;
330 char *artist = g_uri_escape_string(song->artist, NULL, TRUE);
331 char *album = g_uri_escape_string(song->album, NULL, TRUE);
332 debug_printf(DEBUG_INFO, "Trying to fetch: %s:%s\n", artist, album);
333 retval = __discogs_art_get_album_image(song,artist,album, path);
334 g_free(artist);
335 g_free(album);
336 return retval;
339 static int discogs_fetch_cover_art(mpd_Song *song, char **path)
341 int retval;
342 char *artist = g_uri_escape_string(song->artist, NULL, TRUE);
343 retval = __discogs_art_get_artist_image(song,artist,path);
344 g_free(artist);
345 return retval;
348 static int discogs_fetch_get_image(mpd_Song *song,MetaDataType type, char **path)
350 int result = 0;
351 if(song->artist == NULL || discogs_get_enabled() == FALSE)
353 return META_DATA_UNAVAILABLE;
355 if(type == META_ARTIST_ART)
357 result = discogs_fetch_cover_art(song, path);
358 return result;
360 else if (type == META_ALBUM_ART && cfg_get_single_value_as_int_with_default(config, "cover-discogs", "fetch-album", TRUE))
362 result = discogs_fetch_cover_album_art(song, path);
363 return result;
366 return META_DATA_UNAVAILABLE;
369 gmpcMetaDataPlugin lf_cover = {
370 .get_priority = discogs_fetch_cover_priority,
371 .set_priority = discogs_fetch_cover_priority_set,
372 .get_image = discogs_fetch_get_image
375 int plugin_api_version = PLUGIN_API_VERSION;
377 gmpcPlugin plugin = {
378 .name = "DiscoGS Artist and Album Image Fetcher",
379 .version = {PLUGIN_MAJOR_VERSION,PLUGIN_MINOR_VERSION,PLUGIN_MICRO_VERSION},
380 .plugin_type = GMPC_PLUGIN_META_DATA,
381 .metadata = &lf_cover,
382 .get_enabled = discogs_get_enabled,
383 .set_enabled = discogs_set_enabled