1 /* gmpc-magnatune (GMPC plugin)
2 * Copyright (C) 2006-2009 Qball Cow <qball@sarine.nl>
3 * Project homepage: http://gmpcwiki.sarine.nl/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <gmpc/plugin.h>
24 #include <gmpc/gmpc_easy_download.h>
25 #include <gmpc/misc.h>
26 #include <libmpd/libmpd-internal.h>
28 #include <libxml/xmlreader.h>
29 #include <libxml/tree.h>
30 #include "magnatune.h"
32 static void magnatune_cleanup_xml();
33 static sqlite3
*magnatune_sqlhandle
= NULL
;
34 GMutex
*mt_db_lock
= NULL
;
37 void magnatune_db_destroy(void)
41 g_mutex_lock(mt_db_lock
);
42 g_mutex_unlock(mt_db_lock
);
43 g_mutex_free(mt_db_lock
);
45 if(magnatune_sqlhandle
)
47 sqlite3_close(magnatune_sqlhandle
);
48 magnatune_sqlhandle
= NULL
;
52 /* run this before using the other fucntions */
53 void magnatune_db_init()
55 mt_db_lock
= g_mutex_new();
58 void magnatune_db_open()
62 g_mutex_lock(mt_db_lock
);
67 if(magnatune_sqlhandle
)
69 sqlite3_close(magnatune_sqlhandle
);
70 magnatune_sqlhandle
= NULL
;
74 path
= gmpc_get_user_path("magnatune.sqlite3");
75 sqlite3_open(path
, &(magnatune_sqlhandle
));
78 g_mutex_unlock(mt_db_lock
);
81 gboolean
magnatune_db_has_data()
83 char *query
= sqlite3_mprintf("SELECT * from 'sqlite_master'");
89 g_mutex_lock(mt_db_lock
);
90 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
93 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
){
94 sqlite3_finalize(stmt
);
95 g_mutex_unlock(mt_db_lock
);
100 g_mutex_unlock(mt_db_lock
);
104 MpdData
* magnatune_db_get_genre_list()
106 MpdData
*list
= NULL
;
111 g_mutex_lock(mt_db_lock
);
112 char *query
= sqlite3_mprintf("SELECT genre from 'genres' group by genre");
115 int r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
117 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
119 list
= mpd_new_data_struct_append(list
);
120 list
->type
= MPD_DATA_TYPE_TAG
;
121 list
->tag_type
= MPD_TAG_ITEM_GENRE
;
122 list
->tag
= g_strdup(sqlite3_column_text(stmt
,0));
124 sqlite3_finalize(stmt
);
127 g_mutex_unlock(mt_db_lock
);
128 return misc_mpddata_remove_duplicate_songs(list
);
131 void magnatune_db_load_data(const char *data
, const goffset length
)
134 xmlTextReaderPtr reader
= NULL
;
137 g_mutex_lock(mt_db_lock
);
139 path
= gmpc_get_user_path("magnatune.sqlite3");
140 if(magnatune_sqlhandle
)
142 sqlite3_close(magnatune_sqlhandle
);
143 magnatune_sqlhandle
= NULL
;
145 // if(gmpc_easy_download("http://he3.magnatune.com/info/sqlite_magnatune.db", dld))
147 GError
*error
= NULL
;
148 gssize size
= (gssize
)length
;
149 g_file_set_contents(path
, data
, size
, &error
);
151 printf("%s\n", error
->message
);
154 printf("%s\n", path
);
155 // gmpc_easy_download_clean(dld);
157 /* open the db if it is closed */
158 if(!magnatune_sqlhandle
) {
161 int retv
= sqlite3_open(path
, &(magnatune_sqlhandle
));
162 if(retv
!= SQLITE_OK
)
165 g_mutex_unlock(mt_db_lock
);
170 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL
, NULL
, &error
);
171 if(error
)printf("%i: %s",__LINE__
, error
);
172 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX genresAlbumname ON genres(albumname);", NULL
, NULL
, &error
);
173 if(error
)printf("%i: %s",__LINE__
, error
);
174 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX albumsAlbumname ON albums(albumname);", NULL
, NULL
, &error
);
175 if(error
)printf("%i: %s",__LINE__
, error
);
176 g_mutex_unlock(mt_db_lock
);
178 // g_idle_add(magnatune_end_download, NULL);
182 MpdData
* magnatune_db_get_artist_list(char *wanted_genre
)
184 MpdData
*list
= NULL
;
187 /** check if there is data */
188 g_mutex_lock(mt_db_lock
);
189 char *query
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE genre=%Q", wanted_genre
);
192 int r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
194 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
198 char *query2
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q", sqlite3_column_text(stmt
,0));
199 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
201 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
203 list
= mpd_new_data_struct_append(list
);
204 list
->type
= MPD_DATA_TYPE_TAG
;
205 list
->tag_type
= MPD_TAG_ITEM_ARTIST
;
206 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
209 sqlite3_finalize(stmt2
);
210 sqlite3_free(query2
);
212 sqlite3_finalize(stmt
);
215 g_mutex_unlock(mt_db_lock
);
216 return misc_mpddata_remove_duplicate_songs(list
);
219 MpdData
*magnatune_db_get_album_list(char *wanted_genre
,char *wanted_artist
)
221 MpdData
*list
= NULL
;
224 /** check if there is data */
225 g_mutex_lock(mt_db_lock
);
227 char *query
= sqlite3_mprintf("SELECT albumname from 'albums' WHERE artist=%Q",wanted_artist
);
230 int r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
232 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
236 char *query2
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE albumname=%Q AND genre=%Q", sqlite3_column_text(stmt
,0),wanted_genre
);
237 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
239 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
241 list
= mpd_new_data_struct_append(list
);
242 list
->type
= MPD_DATA_TYPE_TAG
;
243 list
->tag_type
= MPD_TAG_ITEM_ALBUM
;
244 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
247 sqlite3_finalize(stmt2
);
248 sqlite3_free(query2
);
250 sqlite3_finalize(stmt
);
253 g_mutex_unlock(mt_db_lock
);
254 return mpd_data_get_first(list
);
257 static char *__magnatune_get_artist_name(const char *album
)
264 if(!album
) return NULL
;
265 query
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q limit 1",album
);
266 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
268 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
270 retv
= g_strdup(sqlite3_column_text(stmt
, 0));
272 sqlite3_finalize(stmt
);
277 static char *__magnatune_get_genre_name(const char *album
)
284 if(!album
) return NULL
;
285 query
= sqlite3_mprintf("SELECT genre from 'genres' WHERE albumname=%Q",album
);
286 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
288 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
290 const char *temp
= sqlite3_column_text(stmt
, 0);
294 retv
= g_strconcat(t
, ", ",temp
, NULL
);
297 else retv
= g_strdup(temp
);
299 sqlite3_finalize(stmt
);
304 static MpdData
*__magnatune_get_data_album(const char *album
, gboolean exact
)
306 MpdData
*list
= NULL
;
313 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
314 "WHERE songs.albumname=%Q",album
);
316 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
317 "WHERE songs.albumname LIKE '%%%%%q%%%%'",album
);
319 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
321 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
323 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
324 list
= mpd_new_data_struct_append(list
);
325 list
->type
= MPD_DATA_TYPE_SONG
;
326 list
->song
= mpd_newSong();
327 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
328 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
329 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
330 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
331 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
332 list
->song
->time
= sqlite3_column_int(stmt
,1);
333 list
->song
->file
= g_strdup_printf("http://he3.magnatune.com/all/%s",temp
);
336 sqlite3_finalize(stmt
);
341 static gchar
** __magnatune_get_albums(const char *genre
, const char *artist
, gboolean exact
)
350 if(genre
&& !artist
) {
352 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre
);
354 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre
);
356 else if (artist
&& !genre
) {
358 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist
);
360 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist
);
362 else if (artist
&& genre
) {
364 query
= sqlite3_mprintf("SELECT genres.albumname FROM 'albums' JOIN 'genres' on albums.albumname = genres.albumname WHERE albums.artist=%Q AND genres.genre=%Q", artist
,genre
);
366 query
= sqlite3_mprintf("SELECT genres.albumname FROM 'albums' JOIN 'genres' on albums.albumname = genres.albumname WHERE albums.artist LIKE '%%%%%q%%%%' AND genres.genre LIKE '%%%%%q%%%%'", artist
,genre
);
370 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
372 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
375 retv
= g_realloc(retv
, (items
+1)*sizeof(*retv
));
377 retv
[items
-1] = g_strdup(sqlite3_column_text(stmt
, 0));
379 sqlite3_finalize(stmt
);
385 MpdData
* magnatune_db_get_song_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
, gboolean exact
)
387 MpdData
*data
= NULL
;
392 if(!wanted_genre
&& !wanted_artist
&& !wanted_album
) return NULL
;
394 g_mutex_lock(mt_db_lock
);
395 if(wanted_album
) /* album seems to be unique */
397 data
= __magnatune_get_data_album(wanted_album
, exact
);
401 char **albums
= __magnatune_get_albums(wanted_genre
, wanted_artist
, exact
);
405 for(i
=0; albums
[i
];i
++)
407 MpdData
*data2
= __magnatune_get_data_album(albums
[i
], exact
);
408 data
= mpd_data_concatenate(data
, data2
);
414 g_mutex_unlock(mt_db_lock
);
415 return mpd_data_get_first(data
);
418 MpdData
* magnatune_db_search_title(const gchar
*title
)
421 MpdData
*list
= NULL
;
426 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
427 "WHERE songs.desc LIKE '%%%%%q%%%%'",title
);
428 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
430 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
432 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
433 list
= mpd_new_data_struct_append(list
);
434 list
->type
= MPD_DATA_TYPE_SONG
;
435 list
->song
= mpd_newSong();
436 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
437 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
438 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
439 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
440 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
441 list
->song
->time
= sqlite3_column_int(stmt
,1);
442 list
->song
->file
= g_strdup_printf("http://he3.magnatune.com/all/%s",temp
);
445 sqlite3_finalize(stmt
);
453 gchar
*magnatune_get_artist_image(const gchar
*wanted_artist
)
457 char *artist
= __magnatune_process_string(wanted_artist
);
461 query
= sqlite3_mprintf("SELECT homepage from 'artists' WHERE artist LIKE '%%%%%q%%%%' limit 1",artist
);
462 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
464 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
466 gchar
*temp
= gmpc_easy_download_uri_escape( sqlite3_column_text(stmt
, 0));
467 retv
= g_strdup_printf("http://he3.magnatune.com/artists/img/%s_1.jpg", temp
);
470 sqlite3_finalize(stmt
);
477 gchar
*magnatune_get_album_url(const gchar
*wanted_artist
, const gchar
*wanted_album
)
483 gchar
*magnatune_get_album_image(const gchar
*wanted_artist
, const gchar
*wanted_album
)
486 char *artist
= __magnatune_process_string(wanted_artist
);
487 char *album
= __magnatune_process_string(wanted_album
);
488 gchar
*artist_enc
= gmpc_easy_download_uri_escape(artist
);
489 gchar
*album_enc
= gmpc_easy_download_uri_escape(album
);
490 retv
= g_strdup_printf("http://he3.magnatune.com/music/%s/%s/cover_600.jpg",artist_enc
, album_enc
);