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
;
16 int magnatune_end_download();
19 * Makes a copy with all &#<id>; decoded
21 static char * url_decode(const char *string
)
24 if(string
&& string
[0] != '\0')
27 const gchar
*a
= string
;
29 b
= retv
= g_malloc0((strlen(string
)+1)*sizeof(char));
48 void magnatune_db_destroy(void)
52 g_mutex_lock(mt_db_lock
);
53 g_mutex_unlock(mt_db_lock
);
54 g_mutex_free(mt_db_lock
);
58 axl_doc_free(magnatune_xmldoc
);
60 magnatune_xmldoc
= NULL
;
64 /* run this before using the other fucntions */
65 void magnatune_db_init()
67 mt_db_lock
= g_mutex_new();
71 void magnatune_db_open()
73 gchar
*path
= gmpc_get_user_path("magnatune.xml");
75 g_mutex_lock(mt_db_lock
);
77 * if the db doesn't exists exit
79 if(!g_file_test(path
, G_FILE_TEST_EXISTS
))
82 g_mutex_unlock(mt_db_lock
);
90 axl_doc_free(magnatune_xmldoc
);
91 magnatune_xmldoc
= NULL
;
93 magnatune_xmldoc
= axl_doc_parse_from_file(path
, NULL
);
95 g_mutex_unlock(mt_db_lock
);
99 gboolean
magnatune_db_has_data()
101 gboolean data
= FALSE
;
102 g_mutex_lock(mt_db_lock
);
103 data
= (magnatune_xmldoc
!= NULL
)? TRUE
:FALSE
;
104 g_mutex_unlock(mt_db_lock
);
108 MpdData
* magnatune_db_get_genre_list()
110 MpdData
*list
= NULL
;
113 /** check if there is data */
114 g_mutex_lock(mt_db_lock
);
115 if(magnatune_xmldoc
== NULL
)
117 g_mutex_unlock(mt_db_lock
);
121 root
= axl_doc_get_root(magnatune_xmldoc
);
122 cur
= axl_node_get_first_child(root
);
126 if(NODE_CMP_NAME(cur
, "Album"))
128 const char *genre
= NULL
;
129 cur2
= axl_node_get_first_child(cur
);
132 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
134 gchar
**tokens
= NULL
;
135 genre
= axl_node_get_content(cur2
,NULL
);
139 tokens
= g_strsplit(genre
,",",0);
140 for(i
=0; tokens
[i
];i
++)
142 list
= mpd_new_data_struct_append(list
);
143 list
->type
= MPD_DATA_TYPE_TAG
;
144 list
->tag_type
= MPD_TAG_ITEM_GENRE
;
145 list
->tag
= url_decode(tokens
[i
]);
150 cur2
= axl_node_get_next(cur2
);
154 cur
= axl_node_get_next(cur
);
156 g_mutex_unlock(mt_db_lock
);
157 return misc_mpddata_remove_duplicate_songs(list
);
160 gchar
*magnatune_db_get_value(const char *artist
, const char *album
, int type
)
162 gchar
*retval
= NULL
;
165 /** check if there is data */
166 g_mutex_lock(mt_db_lock
);
167 if(magnatune_xmldoc
== NULL
|| !artist
)
169 g_mutex_unlock(mt_db_lock
);
173 root
= axl_doc_get_root(magnatune_xmldoc
);
174 cur
= axl_node_get_first_child(root
);
175 while(cur
!= NULL
&& !retval
)
178 if(NODE_CMP_NAME(cur
, "Album"))
180 const char *gartist
= NULL
;
181 const char *galbum
= NULL
;
182 const char *gvalue
= NULL
;
183 cur2
= axl_node_get_first_child(cur
);
184 while(cur2
!= NULL
&& !retval
)
186 if(!gartist
&& NODE_CMP_NAME(cur2
, "artist"))
188 gartist
= axl_node_get_content(cur2
,NULL
);
190 else if(!galbum
&& NODE_CMP_NAME(cur2
, "albumname"))
192 galbum
= axl_node_get_content(cur2
,NULL
);
194 else if(!gvalue
&& NODE_CMP_NAME(cur2
, ((type
== META_ARTIST_ART
)?"artistphoto":"cover_small")))
196 gvalue
= axl_node_get_content(cur2
,NULL
);
198 cur2
= axl_node_get_next(cur2
);
200 if(gvalue
&& artist
&& !strncmp(gartist
, artist
,strlen(artist
)))
202 if(type
== META_ARTIST_ART
)
204 retval
= url_decode(gvalue
);
206 else if(galbum
&& !strcmp(galbum
, album
)){
207 retval
= url_decode(gvalue
);
212 cur
= axl_node_get_next(cur
);
215 g_mutex_unlock(mt_db_lock
);
219 * This removes duplicate/unused fields from every Track entry,
220 * This remove around 1/2 the file size
221 * NOT THREAD SAFE, USE INTERNALLY
223 static void magnatune_cleanup_xml()
227 if(!magnatune_xmldoc
)
229 root
= axl_doc_get_root(magnatune_xmldoc
);
230 cur
= axl_node_get_first_child(root
);
234 if(NODE_CMP_NAME(cur
, "Album"))
236 cur2
= axl_node_get_first_child(cur
);
239 if(NODE_CMP_NAME(cur2
, "Track"))
241 axlNode
*cur3
= axl_node_get_first_child(cur2
) ;
243 if(NODE_CMP_NAME(cur3
, "albumname") ||
244 NODE_CMP_NAME(cur3
, "artist") ||
245 NODE_CMP_NAME(cur3
, "artistdesc") ||
246 NODE_CMP_NAME(cur3
, "home") ||
247 NODE_CMP_NAME (cur3
, "artistphoto") ||
248 NODE_CMP_NAME (cur3
, "mp3lofi") ||
249 NODE_CMP_NAME (cur3
, "albumsku") ||
250 NODE_CMP_NAME (cur3
, "mp3genre") ||
251 NODE_CMP_NAME (cur3
, "magnatunegenres") ||
252 NODE_CMP_NAME (cur3
, "license") ||
253 NODE_CMP_NAME (cur3
, "album_notes") ||
254 NODE_CMP_NAME (cur3
, "launchdate") ||
255 NODE_CMP_NAME (cur3
, "buy") ||
256 NODE_CMP_NAME (cur3
, "moods") )
259 axl_node_remove(cur3
,TRUE
);
261 cur3
= axl_node_get_first_child(cur2
) ;
263 cur3
= axl_node_get_next(cur3
);
266 cur2
= axl_node_get_next(cur2
);
268 else if(NODE_CMP_NAME(cur2
, "album_notes") ||
269 NODE_CMP_NAME (cur2
, "buy") ||
270 NODE_CMP_NAME (cur2
, "launchdate"))
272 axl_node_remove(cur2
,TRUE
);
273 cur2
= axl_node_get_first_child(cur
);
275 cur2
= axl_node_get_next(cur2
);
279 cur
= axl_node_get_next(cur
);
284 void magnatune_db_download_xml_thread(gpointer data
)
286 gmpc_easy_download_struct
*dld
= data
;
288 g_mutex_lock(mt_db_lock
);
292 axl_doc_free(magnatune_xmldoc
);
294 magnatune_xmldoc
= NULL
;
296 g_mutex_unlock(mt_db_lock
);
297 if(gmpc_easy_download("http://www.magnatune.com/info/album_info.xml", dld
))
299 g_mutex_lock(mt_db_lock
);
301 magnatune_xmldoc
= axl_doc_parse(dld
->data
, dld
->size
, NULL
);
302 magnatune_cleanup_xml();
303 path
= gmpc_get_user_path("magnatune.xml");
304 axl_doc_dump_to_file(magnatune_xmldoc
, path
);
306 g_mutex_unlock(mt_db_lock
);
310 g_mutex_lock(mt_db_lock
);
312 gchar
*path
= gmpc_get_user_path("magnatune.xml");
313 if(g_file_test(path
, G_FILE_TEST_EXISTS
))
315 magnatune_xmldoc
= axl_doc_parse_from_file(path
, NULL
);
318 g_mutex_unlock(mt_db_lock
);
323 gmpc_easy_download_clean(dld
);
328 g_idle_add(magnatune_end_download
, NULL
);
331 void magnatune_db_download_xml(ProgressCallback cb
, gpointer data
)
333 gmpc_easy_download_struct
*dld
= g_malloc0(sizeof(*dld
));
334 dld
->callback_data
= data
;
339 g_thread_create(magnatune_db_download_xml_thread
, dld
,FALSE
, NULL
);
343 MpdData
* magnatune_db_get_artist_list(char *wanted_genre
)
345 MpdData
*list
= NULL
;
348 /** check if there is data */
349 g_mutex_lock(mt_db_lock
);
350 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
352 g_mutex_unlock(mt_db_lock
);
356 root
= axl_doc_get_root(magnatune_xmldoc
);
357 cur
= axl_node_get_first_child(root
);
361 if(NODE_CMP_NAME(cur
, "Album"))
363 const char *genre
= NULL
;
364 const char *artist
= NULL
;
365 cur2
= axl_node_get_first_child(cur
);
368 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
370 genre
= axl_node_get_content(cur2
,NULL
);
372 else if(NODE_CMP_NAME(cur2
, "artist"))
374 artist
= axl_node_get_content(cur2
,NULL
);
376 cur2
= axl_node_get_next(cur2
);
378 if(genre
&& artist
&& strstr(genre
, wanted_genre
))
380 list
= mpd_new_data_struct_append(list
);
381 list
->type
= MPD_DATA_TYPE_TAG
;
382 list
->tag_type
= MPD_TAG_ITEM_ARTIST
;
383 list
->tag
= url_decode(artist
);
388 cur
= axl_node_get_next(cur
);
390 g_mutex_unlock(mt_db_lock
);
391 return misc_mpddata_remove_duplicate_songs(list
);
394 MpdData
*magnatune_db_get_album_list(char *wanted_genre
,char *wanted_artist
)
396 MpdData
*list
= NULL
;
399 /** check if there is data */
400 g_mutex_lock(mt_db_lock
);
401 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
|| wanted_artist
== NULL
)
403 g_mutex_unlock(mt_db_lock
);
407 root
= axl_doc_get_root(magnatune_xmldoc
);
408 cur
= axl_node_get_first_child(root
);
412 if(NODE_CMP_NAME(cur
, "Album"))
414 const char *genre
= NULL
;
415 const char *album
= NULL
;
416 const char *artist
= NULL
;
417 cur2
= axl_node_get_first_child(cur
);
420 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
422 genre
= axl_node_get_content(cur2
,NULL
);
424 else if(NODE_CMP_NAME(cur2
, "artist"))
426 artist
= axl_node_get_content(cur2
,NULL
);
428 else if(NODE_CMP_NAME(cur2
, "albumname"))
430 album
= axl_node_get_content(cur2
,NULL
);
432 cur2
= axl_node_get_next(cur2
);
434 if(genre
&& artist
&&album
&& strstr(genre
, wanted_genre
) && !strcmp(artist
, wanted_artist
))
436 list
= mpd_new_data_struct_append(list
);
437 list
->type
= MPD_DATA_TYPE_TAG
;
438 list
->tag_type
= MPD_TAG_ITEM_ALBUM
;
439 list
->tag
= url_decode(album
);
442 cur
= axl_node_get_next(cur
);
444 g_mutex_unlock(mt_db_lock
);
445 return mpd_data_get_first(list
);
449 GList
* magnatune_db_get_url_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
)
454 /** check if there is data */
455 g_mutex_lock(mt_db_lock
);
456 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
458 g_mutex_unlock(mt_db_lock
);
462 root
= axl_doc_get_root(magnatune_xmldoc
);
463 cur
= axl_node_get_first_child(root
);
467 if(NODE_CMP_NAME(cur
, "Album"))
469 const char *genre
= NULL
;
470 const char *album
= NULL
;
471 const char *artist
= NULL
;
472 gboolean add_urls
= FALSE
;
474 cur2
= axl_node_get_first_child(cur
);
477 if(NODE_CMP_NAME(cur2
, "magnatunegenres"))
479 genre
= axl_node_get_content(cur2
,NULL
);
481 else if(NODE_CMP_NAME(cur2
, "artist"))
483 artist
= axl_node_get_content(cur2
,NULL
);
485 else if(NODE_CMP_NAME(cur2
, "albumname"))
487 album
= axl_node_get_content(cur2
,NULL
);
489 cur2
= axl_node_get_next(cur2
);
491 if(genre
&& strstr(genre
, wanted_genre
))
493 if(wanted_artist
&& wanted_album
) {
494 if(!strcmp(wanted_artist
,artist
) && !strcmp(wanted_album
, album
)) {
497 }else if(wanted_artist
) {
498 if(!strcmp(wanted_artist
, artist
)) {
507 cur2
= axl_node_get_first_child(cur
);
510 if (NODE_CMP_NAME(cur2
, "Track"))
512 tracks
= axl_node_get_first_child(cur2
);
515 if (NODE_CMP_NAME(tracks
, "url"))
517 const char *url
= axl_node_get_content(tracks
,NULL
);
518 list
= g_list_append(list
, url_decode(url
));
520 tracks
= axl_node_get_next(tracks
);
523 cur2
= axl_node_get_next(cur2
);
527 cur
= axl_node_get_next(cur
);
529 g_mutex_unlock(mt_db_lock
);
535 MpdData
* magnatune_db_get_song_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
)
537 MpdData
*data
= NULL
;
540 /** check if there is data */
541 g_mutex_lock(mt_db_lock
);
542 if(magnatune_xmldoc
== NULL
|| wanted_genre
== NULL
)
544 g_mutex_unlock(mt_db_lock
);
548 root
= axl_doc_get_root(magnatune_xmldoc
);
549 cur
= axl_node_get_first_child(root
);
553 if(NODE_CMP_NAME(cur
, (const char *)"Album"))
555 const char *year
= NULL
;
556 const char *temp
= NULL
;
557 const char *genre
= NULL
;
558 const char *album
= NULL
;
559 const char *artist
= NULL
;
561 gboolean add_urls
= FALSE
;
563 cur2
= axl_node_get_first_child(cur
);
566 if(NODE_CMP_NAME(cur2
, (const char *)"magnatunegenres"))
568 genre
= axl_node_get_content(cur2
,NULL
);
570 else if(NODE_CMP_NAME(cur2
, (const char *)"artist"))
572 artist
= axl_node_get_content(cur2
,NULL
);
574 else if(NODE_CMP_NAME(cur2
, (const char *)"albumname"))
576 album
= axl_node_get_content(cur2
,NULL
);
579 cur2
= axl_node_get_next(cur2
);
581 if(genre
&& strstr(genre
, wanted_genre
))
583 if(wanted_artist
&& wanted_album
) {
584 if(!strcmp(wanted_artist
,artist
) && !strcmp(wanted_album
, album
)) {
587 }else if(wanted_artist
) {
588 if(!strcmp(wanted_artist
, artist
)) {
598 cur2
= axl_node_get_first_child(cur
);
601 if (NODE_CMP_NAME(cur2
, (const char *)"Track"))
603 const char *tn
= NULL
;
605 const char *url
= NULL
;
606 const char *name
= NULL
;
608 tracks
= axl_node_get_first_child(cur2
);
613 if (NODE_CMP_NAME(tracks
, (const char *)"url")&& !url
)
615 url
= axl_node_get_content(tracks
,NULL
);
617 else if (NODE_CMP_NAME(tracks
, (const char *)"trackname")&& !name
)
619 name
= axl_node_get_content(tracks
,NULL
);
622 else if (NODE_CMP_NAME(tracks
, (const char *)"tracknum")&& !tn
)
624 tn
= axl_node_get_content(tracks
,NULL
);
626 else if (NODE_CMP_NAME(tracks
, "seconds")&& !stime
)
628 const char *eurl
= axl_node_get_content(tracks
, NULL
);
631 else if (NODE_CMP_NAME(tracks
, (const char *)"year")&& !year
)
633 year
= axl_node_get_content(tracks
,NULL
);
635 tracks
= axl_node_get_next(tracks
);
639 data
= (MpdData
*)mpd_new_data_struct_append((MpdData
*)data
);
640 data
->type
= MPD_DATA_TYPE_SONG
;
641 data
->song
= mpd_newSong();
642 data
->song
->file
= url_decode(url
);
643 data
->song
->title
= url_decode(name
);
644 data
->song
->album
= url_decode(album
);
645 data
->song
->artist
= url_decode(artist
);
646 data
->song
->genre
= url_decode(genre
);
647 data
->song
->date
= url_decode(year
);
648 data
->song
->track
= url_decode(tn
);
649 data
->song
->time
= stime
;
652 cur2
= axl_node_get_next(cur2
);
656 cur
= axl_node_get_next(cur
);
658 g_mutex_unlock(mt_db_lock
);