3 /* gtk and lib stuff */
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>
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
;
38 xmlNodePtr c
= xml
->xmlChildrenNode
;
40 if(c
->name
&& xmlStrEqual(c
->name
, (xmlChar
*) name
))
46 static int __discogs_art_get_artist_image(mpd_Song
*song
,char *nartist
, char **path
)
48 gchar
*secondary
= NULL
;
49 gchar
*primary
= NULL
;
53 gchar
*artist_uri
= NULL
;
54 gmpc_easy_download_struct data
= {NULL
, 0,-1,NULL
, NULL
};
55 int found
= META_DATA_UNAVAILABLE
;
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
))
65 doc
= xmlParseMemory(data
.data
,data
.size
);
66 gmpc_easy_download_clean(&data
);
69 xmlNodePtr root
= xmlDocGetRootElement(doc
);
72 /* loop through all albums */
73 xmlNodePtr cur
= get_first_node_by_name(root
,"exactresults");
76 xmlNodePtr cur2
= get_first_node_by_name(cur
,"result");
78 xmlNodePtr cur3
= get_first_node_by_name(cur2
,"uri");
80 xmlChar
*xurl
= xmlNodeGetContent(cur3
);
81 artist_uri
= g_strdup((char *)xurl
);
91 snprintf(furl
,1024,"%s?f=xml&api_key=%s", artist_uri
,DISCOGS_API_KEY
);
92 if(gmpc_easy_download(furl
, &data
))
95 doc
= xmlParseMemory(data
.data
,data
.size
);
96 gmpc_easy_download_clean(&data
);
99 xmlNodePtr root
= xmlDocGetRootElement(doc
);
102 /* loop through all albums */
103 xmlNodePtr cur
= get_first_node_by_name(root
,"artist");
106 xmlNodePtr cur2
= get_first_node_by_name(cur
,"images");
108 xmlNodePtr cur3
= get_first_node_by_name(cur2
,"image");
109 while(cur3
&& *path
== NULL
){
110 xmlChar
*temp
= xmlGetProp(cur3
, (xmlChar
*)"type");
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);
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);
131 if(secondary
) g_free(secondary
);
132 secondary
= g_strdup((gchar
*)xurl
);
134 if(xurl
) xmlFree(xurl
);
135 if(size
) xmlFree(size
);
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
);
156 char *imgpath
= NULL
;
157 imgpath
= gmpc_get_metadata_filename(META_ARTIST_ART
, song
, "jpg");
158 fp
= fopen(imgpath
, "wb");
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");
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
);
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
;
187 gchar
*artist_uri
= NULL
;
188 gmpc_easy_download_struct data
= {NULL
, 0,-1,NULL
, NULL
};
189 int found
= META_DATA_UNAVAILABLE
;
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
))
200 doc
= xmlParseMemory(data
.data
,data
.size
);
201 gmpc_easy_download_clean(&data
);
204 xmlNodePtr root
= xmlDocGetRootElement(doc
);
207 /* loop through all albums */
208 xmlNodePtr cur
= get_first_node_by_name(root
,"searchresults");
211 xmlNodePtr cur2
= get_first_node_by_name(cur
,"result");
213 xmlNodePtr cur4
= get_first_node_by_name(cur2
,"title");
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");
221 xmlChar
*xurl
= xmlNodeGetContent(cur3
);
222 artist_uri
= g_strdup((char *)xurl
);
226 if(title
)xmlFree(title
);
235 snprintf(furl
,1024,"%s?f=xml&api_key=%s", artist_uri
,DISCOGS_API_KEY
);
237 if(gmpc_easy_download(furl
, &data
))
241 doc
= xmlParseMemory(data
.data
,data
.size
);
242 gmpc_easy_download_clean(&data
);
245 xmlNodePtr root
= xmlDocGetRootElement(doc
);
248 /* loop through all albums */
249 xmlNodePtr cur
= get_first_node_by_name(root
,"release");
252 xmlNodePtr cur2
= get_first_node_by_name(cur
,"images");
254 xmlNodePtr cur3
= get_first_node_by_name(cur2
,"image");
255 while(cur3
&& *path
== NULL
){
256 xmlChar
*temp
= xmlGetProp(cur3
, (xmlChar
*)"type");
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);
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);
278 if(secondary
) g_free(secondary
);
279 secondary
= g_strdup((char *)xurl
);
281 if(xurl
) xmlFree(xurl
);
282 if(size
) xmlFree(size
);
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
);
303 char *imgpath
= NULL
;
304 imgpath
= gmpc_get_metadata_filename(META_ALBUM_ART
, song
, "jpg");
305 fp
= fopen(imgpath
, "wb");
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");
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
);
327 static int discogs_fetch_cover_album_art(mpd_Song
*song
, char **path
)
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
);
339 static int discogs_fetch_cover_art(mpd_Song
*song
, char **path
)
342 char *artist
= g_uri_escape_string(song
->artist
, NULL
, TRUE
);
343 retval
= __discogs_art_get_artist_image(song
,artist
,path
);
348 static int discogs_fetch_get_image(mpd_Song
*song
,MetaDataType type
, char **path
)
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
);
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
);
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