5 #include <gmpc/plugin.h>
6 #include <gmpc/gmpc_easy_download.h>
8 #include <libmpd/libmpd-internal.h>
11 static void magnatune_cleanup_xml();
12 static axlDoc
*magnatune_xmldoc
= NULL
;
13 GMutex
*mt_db_lock
= NULL
;
18 * Makes a copy with all &#<id>; decoded
20 static char * url_decode(const char *string
)
23 if(string
&& string
[0] != '\0')
26 const gchar
*a
= string
;
28 b
= retv
= g_malloc0((strlen(string
)+1)*sizeof(char));
47 void magnatune_db_destroy(void)
51 g_mutex_lock(mt_db_lock
);
52 g_mutex_unlock(mt_db_lock
);
53 g_mutex_free(mt_db_lock
);
57 axl_doc_free(magnatune_xmldoc
);
59 magnatune_xmldoc
= NULL
;
63 /* run this before using the other fucntions */
64 void magnatune_db_init()
66 mt_db_lock
= g_mutex_new();
70 void magnatune_db_open()
72 gchar
*path
= gmpc_get_user_path("magnatune.xml");
74 g_mutex_lock(mt_db_lock
);
76 * if the db doesn't exists exit
78 if(!g_file_test(path
, G_FILE_TEST_EXISTS
))
81 g_mutex_unlock(mt_db_lock
);
89 axl_doc_free(magnatune_xmldoc
);
90 magnatune_xmldoc
= NULL
;
92 magnatune_xmldoc
= axl_doc_parse_from_file(path
, NULL
);
94 g_mutex_unlock(mt_db_lock
);
98 gboolean
magnatune_db_has_data()
100 gboolean data
= FALSE
;
101 g_mutex_lock(mt_db_lock
);
102 data
= (magnatune_xmldoc
!= NULL
)? TRUE
:FALSE
;
103 g_mutex_unlock(mt_db_lock
);
107 MpdData
* magnatune_db_get_genre_list()
109 MpdData
*list
= NULL
;
112 /** check if there is data */
113 g_mutex_lock(mt_db_lock
);
114 if(magnatune_xmldoc
== NULL
)
116 g_mutex_unlock(mt_db_lock
);
120 root
= axl_doc_get_root(magnatune_xmldoc
);
121 cur
= axl_node_get_first_child(root
);
125 if(NODE_CMP_NAME(cur
, "Album"))
127 const char *genre
= NULL
;
128 cur2
= axl_node_get_first_child(cur
);
131 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
133 gchar
**tokens
= NULL
;
134 genre
= axl_node_get_content(cur2
,NULL
);
138 tokens
= g_strsplit(genre
,",",0);
139 for(i
=0; tokens
[i
];i
++)
141 list
= mpd_new_data_struct_append(list
);
142 list
->type
= MPD_DATA_TYPE_TAG
;
143 list
->tag_type
= MPD_TAG_ITEM_GENRE
;
144 list
->tag
= url_decode(tokens
[i
]);
149 cur2
= axl_node_get_next(cur2
);
153 cur
= axl_node_get_next(cur
);
155 g_mutex_unlock(mt_db_lock
);
156 return misc_mpddata_remove_duplicate_songs(list
);
159 gchar
*magnatune_db_get_value(const char *artist
, const char *album
, int type
)
161 gchar
*retval
= NULL
;
164 /** check if there is data */
165 g_mutex_lock(mt_db_lock
);
166 if(magnatune_xmldoc
== NULL
|| !artist
)
168 g_mutex_unlock(mt_db_lock
);
172 root
= axl_doc_get_root(magnatune_xmldoc
);
173 cur
= axl_node_get_first_child(root
);
174 while(cur
!= NULL
&& !retval
)
177 if(NODE_CMP_NAME(cur
, "Album"))
179 const char *gartist
= NULL
;
180 const char *galbum
= NULL
;
181 const char *gvalue
= NULL
;
182 cur2
= axl_node_get_first_child(cur
);
183 while(cur2
!= NULL
&& !retval
)
185 if(!gartist
&& NODE_CMP_NAME(cur2
, "artist"))
187 gartist
= axl_node_get_content(cur2
,NULL
);
189 else if(!galbum
&& NODE_CMP_NAME(cur2
, "albumname"))
191 galbum
= axl_node_get_content(cur2
,NULL
);
193 else if(!gvalue
&& NODE_CMP_NAME(cur2
, ((type
== META_ARTIST_ART
)?"artistphoto":"cover_small")))
195 gvalue
= axl_node_get_content(cur2
,NULL
);
197 cur2
= axl_node_get_next(cur2
);
199 if(gvalue
&& artist
&& !strncmp(gartist
, artist
,strlen(artist
)))
201 if(type
== META_ARTIST_ART
)
203 retval
= url_decode(gvalue
);
205 else if(galbum
&& !strcmp(galbum
, album
)){
206 retval
= url_decode(gvalue
);
211 cur
= axl_node_get_next(cur
);
214 g_mutex_unlock(mt_db_lock
);
218 * This removes duplicate/unused fields from every Track entry,
219 * This remove around 1/2 the file size
220 * NOT THREAD SAFE, USE INTERNALLY
222 static void magnatune_cleanup_xml()
226 if(!magnatune_xmldoc
)
228 root
= axl_doc_get_root(magnatune_xmldoc
);
229 cur
= axl_node_get_first_child(root
);
233 if(NODE_CMP_NAME(cur
, "Album"))
235 cur2
= axl_node_get_first_child(cur
);
238 if(NODE_CMP_NAME(cur2
, "Track"))
240 axlNode
*cur3
= axl_node_get_first_child(cur2
) ;
242 if(NODE_CMP_NAME(cur3
, "albumname") ||
243 NODE_CMP_NAME(cur3
, "artist") ||
244 NODE_CMP_NAME(cur3
, "artistdesc") ||
245 NODE_CMP_NAME(cur3
, "home") ||
246 NODE_CMP_NAME (cur3
, "artistphoto") ||
247 NODE_CMP_NAME (cur3
, "mp3lofi") ||
248 NODE_CMP_NAME (cur3
, "albumsku") ||
249 NODE_CMP_NAME (cur3
, "mp3genre") ||
250 NODE_CMP_NAME (cur3
, "magnatunegenres") ||
251 NODE_CMP_NAME (cur3
, "license") ||
252 NODE_CMP_NAME (cur3
, "album_notes") ||
253 NODE_CMP_NAME (cur3
, "launchdate") ||
254 NODE_CMP_NAME (cur3
, "buy") ||
255 NODE_CMP_NAME (cur3
, "moods") )
258 axl_node_remove(cur3
,TRUE
);
260 cur3
= axl_node_get_first_child(cur2
) ;
262 cur3
= axl_node_get_next(cur3
);
265 cur2
= axl_node_get_next(cur2
);
267 else if(NODE_CMP_NAME(cur2
, "album_notes") ||
268 NODE_CMP_NAME (cur2
, "buy") ||
269 NODE_CMP_NAME (cur2
, "launchdate"))
271 axl_node_remove(cur2
,TRUE
);
272 cur2
= axl_node_get_first_child(cur
);
274 cur2
= axl_node_get_next(cur2
);
278 cur
= axl_node_get_next(cur
);
283 void magnatune_db_download_xml_thread(gpointer data
)
285 gmpc_easy_download_struct
*dld
= data
;
287 g_mutex_lock(mt_db_lock
);
291 axl_doc_free(magnatune_xmldoc
);
293 magnatune_xmldoc
= NULL
;
295 g_mutex_unlock(mt_db_lock
);
296 if(gmpc_easy_download("http://www.magnatune.com/info/album_info.xml", dld
))
298 g_mutex_lock(mt_db_lock
);
300 magnatune_xmldoc
= axl_doc_parse(dld
->data
, dld
->size
, NULL
);
301 magnatune_cleanup_xml();
302 path
= gmpc_get_user_path("magnatune.xml");
303 axl_doc_dump_to_file(magnatune_xmldoc
, path
);
305 g_mutex_unlock(mt_db_lock
);
309 g_mutex_lock(mt_db_lock
);
311 gchar
*path
= gmpc_get_user_path("magnatune.xml");
312 if(g_file_test(path
, G_FILE_TEST_EXISTS
))
314 magnatune_xmldoc
= axl_doc_parse_from_file(path
, NULL
);
317 g_mutex_unlock(mt_db_lock
);
322 gmpc_easy_download_clean(dld
);
327 magnatune_end_download();
330 void magnatune_db_download_xml(ProgressCallback cb
, gpointer data
)
332 gmpc_easy_download_struct
*dld
= g_malloc0(sizeof(*dld
));
333 dld
->callback_data
= data
;
338 g_thread_create(magnatune_db_download_xml_thread
, dld
,FALSE
, NULL
);
342 MpdData
* magnatune_db_get_artist_list(char *wanted_genre
)
344 MpdData
*list
= NULL
;
347 /** check if there is data */
348 g_mutex_lock(mt_db_lock
);
349 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
351 g_mutex_unlock(mt_db_lock
);
355 root
= axl_doc_get_root(magnatune_xmldoc
);
356 cur
= axl_node_get_first_child(root
);
360 if(NODE_CMP_NAME(cur
, "Album"))
362 const char *genre
= NULL
;
363 const char *artist
= NULL
;
364 cur2
= axl_node_get_first_child(cur
);
367 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
369 genre
= axl_node_get_content(cur2
,NULL
);
371 else if(NODE_CMP_NAME(cur2
, "artist"))
373 artist
= axl_node_get_content(cur2
,NULL
);
375 cur2
= axl_node_get_next(cur2
);
377 if(genre
&& artist
&& strstr(genre
, wanted_genre
))
379 list
= mpd_new_data_struct_append(list
);
380 list
->type
= MPD_DATA_TYPE_TAG
;
381 list
->tag_type
= MPD_TAG_ITEM_ARTIST
;
382 list
->tag
= url_decode(artist
);
387 cur
= axl_node_get_next(cur
);
389 g_mutex_unlock(mt_db_lock
);
390 return misc_mpddata_remove_duplicate_songs(list
);
393 MpdData
*magnatune_db_get_album_list(char *wanted_genre
,char *wanted_artist
)
395 MpdData
*list
= NULL
;
398 /** check if there is data */
399 g_mutex_lock(mt_db_lock
);
400 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
|| wanted_artist
== NULL
)
402 g_mutex_unlock(mt_db_lock
);
406 root
= axl_doc_get_root(magnatune_xmldoc
);
407 cur
= axl_node_get_first_child(root
);
411 if(NODE_CMP_NAME(cur
, "Album"))
413 const char *genre
= NULL
;
414 const char *album
= NULL
;
415 const char *artist
= NULL
;
416 cur2
= axl_node_get_first_child(cur
);
419 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
421 genre
= axl_node_get_content(cur2
,NULL
);
423 else if(NODE_CMP_NAME(cur2
, "artist"))
425 artist
= axl_node_get_content(cur2
,NULL
);
427 else if(NODE_CMP_NAME(cur2
, "albumname"))
429 album
= axl_node_get_content(cur2
,NULL
);
431 cur2
= axl_node_get_next(cur2
);
433 if(genre
&& artist
&&album
&& strstr(genre
, wanted_genre
) && !strcmp(artist
, wanted_artist
))
435 list
= mpd_new_data_struct_append(list
);
436 list
->type
= MPD_DATA_TYPE_TAG
;
437 list
->tag_type
= MPD_TAG_ITEM_ALBUM
;
438 list
->tag
= url_decode(album
);
441 cur
= axl_node_get_next(cur
);
443 g_mutex_unlock(mt_db_lock
);
444 return mpd_data_get_first(list
);
448 GList
* magnatune_db_get_url_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
)
453 /** check if there is data */
454 g_mutex_lock(mt_db_lock
);
455 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
457 g_mutex_unlock(mt_db_lock
);
461 root
= axl_doc_get_root(magnatune_xmldoc
);
462 cur
= axl_node_get_first_child(root
);
466 if(NODE_CMP_NAME(cur
, "Album"))
468 const char *genre
= NULL
;
469 const char *album
= NULL
;
470 const char *artist
= NULL
;
471 gboolean add_urls
= FALSE
;
473 cur2
= axl_node_get_first_child(cur
);
476 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
478 genre
= axl_node_get_content(cur2
,NULL
);
480 else if(NODE_CMP_NAME(cur2
, "artist"))
482 artist
= axl_node_get_content(cur2
,NULL
);
484 else if(NODE_CMP_NAME(cur2
, "albumname"))
486 album
= axl_node_get_content(cur2
,NULL
);
488 cur2
= axl_node_get_next(cur2
);
490 if(genre
&& strstr(genre
, wanted_genre
))
492 if(wanted_artist
&& wanted_album
) {
493 if(!strcmp(wanted_artist
,artist
) && !strcmp(wanted_album
, album
)) {
496 }else if(wanted_artist
) {
497 if(!strcmp(wanted_artist
, artist
)) {
506 cur2
= axl_node_get_first_child(cur
);
509 if (NODE_CMP_NAME(cur2
, "Track"))
511 tracks
= axl_node_get_first_child(cur2
);
514 if (NODE_CMP_NAME(tracks
, "url"))
516 const char *url
= axl_node_get_content(tracks
,NULL
);
517 list
= g_list_append(list
, url_decode(url
));
519 tracks
= axl_node_get_next(tracks
);
522 cur2
= axl_node_get_next(cur2
);
526 cur
= axl_node_get_next(cur
);
528 g_mutex_unlock(mt_db_lock
);
534 MpdData
* magnatune_db_get_song_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
)
536 MpdData
*data
= NULL
;
539 /** check if there is data */
540 g_mutex_lock(mt_db_lock
);
541 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
543 g_mutex_unlock(mt_db_lock
);
547 root
= axl_doc_get_root(magnatune_xmldoc
);
548 cur
= axl_node_get_first_child(root
);
552 if(NODE_CMP_NAME(cur
, (const char *)"Album"))
554 const char *year
= NULL
;
555 const char *temp
= NULL
;
556 const char *genre
= NULL
;
557 const char *album
= NULL
;
558 const char *artist
= NULL
;
560 gboolean add_urls
= FALSE
;
562 cur2
= axl_node_get_first_child(cur
);
565 if(NODE_CMP_NAME(cur2
, (const char *)"magnatunegenres"))
567 genre
= axl_node_get_content(cur2
,NULL
);
569 else if(NODE_CMP_NAME(cur2
, (const char *)"artist"))
571 artist
= axl_node_get_content(cur2
,NULL
);
573 else if(NODE_CMP_NAME(cur2
, (const char *)"albumname"))
575 album
= axl_node_get_content(cur2
,NULL
);
578 cur2
= axl_node_get_next(cur2
);
580 if(genre
&& strstr(genre
, wanted_genre
))
582 if(wanted_artist
&& wanted_album
) {
583 if(!strcmp(wanted_artist
,artist
) && !strcmp(wanted_album
, album
)) {
586 }else if(wanted_artist
) {
587 if(!strcmp(wanted_artist
, artist
)) {
597 cur2
= axl_node_get_first_child(cur
);
600 if (NODE_CMP_NAME(cur2
, (const char *)"Track"))
602 const char *tn
= NULL
;
604 const char *url
= NULL
;
605 const char *name
= NULL
;
607 tracks
= axl_node_get_first_child(cur2
);
612 if (NODE_CMP_NAME(tracks
, (const char *)"url")&& !url
)
614 url
= axl_node_get_content(tracks
,NULL
);
616 else if (NODE_CMP_NAME(tracks
, (const char *)"trackname")&& !name
)
618 name
= axl_node_get_content(tracks
,NULL
);
621 else if (NODE_CMP_NAME(tracks
, (const char *)"tracknum")&& !tn
)
623 tn
= axl_node_get_content(tracks
,NULL
);
625 else if (NODE_CMP_NAME(tracks
, "seconds")&& !stime
)
627 const char *eurl
= axl_node_get_content(tracks
, NULL
);
630 else if (NODE_CMP_NAME(tracks
, (const char *)"year")&& !year
)
632 year
= axl_node_get_content(tracks
,NULL
);
634 tracks
= axl_node_get_next(tracks
);
638 data
= (MpdData
*)mpd_new_data_struct_append((MpdData
*)data
);
639 data
->type
= MPD_DATA_TYPE_SONG
;
640 data
->song
= mpd_newSong();
641 data
->song
->file
= url_decode(url
);
642 data
->song
->title
= url_decode(name
);
643 data
->song
->album
= url_decode(album
);
644 data
->song
->artist
= url_decode(artist
);
645 data
->song
->genre
= url_decode(genre
);
646 data
->song
->date
= url_decode(year
);
647 data
->song
->track
= url_decode(tn
);
648 data
->song
->time
= stime
;
651 cur2
= axl_node_get_next(cur2
);
655 cur
= axl_node_get_next(cur
);
657 g_mutex_unlock(mt_db_lock
);