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 <playlist3-messages.h>
31 #include "magnatune.h"
33 static void magnatune_cleanup_xml();
34 static sqlite3
*magnatune_sqlhandle
= NULL
;
37 void magnatune_db_destroy(void)
39 if(magnatune_sqlhandle
)
41 sqlite3_close(magnatune_sqlhandle
);
42 magnatune_sqlhandle
= NULL
;
46 /* run this before using the other fucntions */
47 void magnatune_db_init()
51 void magnatune_db_open()
59 if(magnatune_sqlhandle
)
61 sqlite3_close(magnatune_sqlhandle
);
62 magnatune_sqlhandle
= NULL
;
66 path
= gmpc_get_user_path("magnatune.sqlite3");
67 sqlite3_open(path
, &(magnatune_sqlhandle
));
72 gboolean
magnatune_db_has_data()
74 char *query
= sqlite3_mprintf("SELECT * from 'sqlite_master'");
75 sqlite3_stmt
*stmt
= NULL
;
80 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
83 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
){
84 sqlite3_finalize(stmt
);
89 sqlite3_finalize(stmt
);
93 MpdData
* magnatune_db_get_genre_list()
100 char *query
= sqlite3_mprintf("SELECT genre from 'genres' group by genre");
101 sqlite3_stmt
*stmt
= NULL
;
103 GTimer
*timer
= g_timer_new();
104 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
106 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
108 list
= mpd_new_data_struct_append(list
);
109 list
->type
= MPD_DATA_TYPE_TAG
;
110 list
->tag_type
= MPD_TAG_ITEM_GENRE
;
111 list
->tag
= g_strdup(sqlite3_column_text(stmt
,0));
115 sqlite3_finalize(stmt
);
117 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer
,NULL
));
118 g_timer_reset(timer
);
119 list
= misc_mpddata_remove_duplicate_songs(list
);
120 g_debug("%f s elapsed unique genres list\n", g_timer_elapsed(timer
,NULL
));
121 g_timer_destroy(timer
);
125 void magnatune_db_load_data(const char *data
, const goffset length
)
128 xmlTextReaderPtr reader
= NULL
;
132 path
= gmpc_get_user_path("magnatune.sqlite3");
133 if(magnatune_sqlhandle
)
135 int status
= sqlite3_close(magnatune_sqlhandle
);
138 gchar
*temp
=g_strdup_printf("Failed to close magnatune db: %i\n", status
);
139 playlist3_show_error_message(temp
, ERROR_WARNING
);
142 magnatune_sqlhandle
= NULL
;
144 // if(gmpc_easy_download("http://he3.magnatune.com/info/sqlite_magnatune.db", dld))
146 GError
*error
= NULL
;
147 gssize size
= (gssize
)length
;
148 g_file_set_contents(path
, data
, size
, &error
);
150 gchar
*temp
=g_strdup_printf("Failed to store magnatune db: %s\n", error
->message
);
151 playlist3_show_error_message(temp
, ERROR_WARNING
);
153 printf("%s\n", error
->message
);
156 printf("%s\n", path
);
157 // gmpc_easy_download_clean(dld);
159 /* open the db if it is closed */
160 if(!magnatune_sqlhandle
) {
163 int retv
= sqlite3_open(path
, &(magnatune_sqlhandle
));
164 if(retv
!= SQLITE_OK
)
168 playlist3_show_error_message("Failed to open the new magnatune database", ERROR_WARNING
);
174 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL
, NULL
, &error
);
175 if(error
)printf("%i: %s",__LINE__
, error
);
176 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX genresAlbumname ON genres(albumname);", NULL
, NULL
, &error
);
177 if(error
)printf("%i: %s",__LINE__
, error
);
178 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX genresGenrename ON genres(genre);", NULL
, NULL
, &error
);
179 if(error
)printf("%i: %s",__LINE__
, error
);
180 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX albumsAlbumname ON albums(albumname);", NULL
, NULL
, &error
);
181 if(error
)printf("%i: %s",__LINE__
, error
);
183 // g_idle_add(magnatune_end_download, NULL);
187 MpdData
* magnatune_db_get_artist_list(char *wanted_genre
)
189 MpdData
*list
= NULL
;
193 /** check if there is data */
194 char *query
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE genre=%Q", wanted_genre
);
195 sqlite3_stmt
*stmt
= NULL
;
197 GTimer
*timer
= g_timer_new();
198 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
200 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
202 sqlite3_stmt
*stmt2
= NULL
;
204 char *query2
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q", sqlite3_column_text(stmt
,0));
205 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
207 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
209 list
= mpd_new_data_struct_append(list
);
210 list
->type
= MPD_DATA_TYPE_TAG
;
211 list
->tag_type
= MPD_TAG_ITEM_ARTIST
;
212 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
215 sqlite3_finalize(stmt2
);
216 sqlite3_free(query2
);
219 sqlite3_finalize(stmt
);
221 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer
,NULL
));
222 g_timer_reset(timer
);
223 list
= misc_mpddata_remove_duplicate_songs(list
);
225 g_debug("%f s elapsed unique artist list\n", g_timer_elapsed(timer
,NULL
));
226 g_timer_destroy(timer
);
230 MpdData
*magnatune_db_get_album_list(char *wanted_genre
,char *wanted_artist
)
233 MpdData
*list
= NULL
;
236 /** check if there is data */
238 char *query
= sqlite3_mprintf("SELECT albumname from 'albums' WHERE artist=%Q",wanted_artist
);
239 sqlite3_stmt
*stmt
= NULL
;
241 GTimer
*timer
= g_timer_new();
242 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
244 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
246 sqlite3_stmt
*stmt2
= NULL
;
248 char *query2
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE albumname=%Q AND genre=%Q", sqlite3_column_text(stmt
,0),wanted_genre
);
249 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
251 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
253 list
= mpd_new_data_struct_append(list
);
254 list
->type
= MPD_DATA_TYPE_TAG
;
255 list
->tag_type
= MPD_TAG_ITEM_ALBUM
;
256 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
259 sqlite3_finalize(stmt2
);
260 sqlite3_free(query2
);
263 sqlite3_finalize(stmt
);
265 g_debug("%f s elapsed listing albums songs\n", g_timer_elapsed(timer
,NULL
));
266 g_timer_destroy(timer
);
267 return mpd_data_get_first(list
);
270 static char *__magnatune_get_artist_name(const char *album
)
273 sqlite3_stmt
*stmt
= NULL
;
277 if(!album
) return NULL
;
278 query
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q limit 1",album
);
279 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
281 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
283 retv
= g_strdup(sqlite3_column_text(stmt
, 0));
286 sqlite3_finalize(stmt
);
290 static char *__magnatune_get_genre_name(const char *album
)
293 sqlite3_stmt
*stmt
= NULL
;
297 if(!album
) return NULL
;
298 query
= sqlite3_mprintf("SELECT genre from 'genres' WHERE albumname=%Q",album
);
299 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
301 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
303 const char *temp
= sqlite3_column_text(stmt
, 0);
307 retv
= g_strconcat(t
, ", ",temp
, NULL
);
310 else retv
= g_strdup(temp
);
314 sqlite3_finalize(stmt
);
318 static MpdData
*__magnatune_get_data_album_from_genre(const char *genre
, gboolean exact
)
320 MpdData
*list
= NULL
;
322 sqlite3_stmt
*stmt
= NULL
;
325 GTimer
*timer
= g_timer_new();
328 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
329 "WHERE genres.genre=%Q",genre
);
331 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
332 "WHERE genres.genre LIKE '%%%%%q%%%%'",genre
);
334 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
336 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
338 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
339 list
= mpd_new_data_struct_append(list
);
340 list
->type
= MPD_DATA_TYPE_SONG
;
341 list
->song
= mpd_newSong();
342 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
343 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
344 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
345 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
346 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
347 list
->song
->time
= sqlite3_column_int(stmt
,1);
348 list
->song
->file
= g_strdup_printf("http://he3.magnatune.com/all/%s",temp
);
352 g_warning("Sqlite error: %s\n", tail
);
355 sqlite3_finalize(stmt
);
357 g_debug("%f s elapsed getting album songs from genre\n", g_timer_elapsed(timer
,NULL
));
358 g_timer_destroy(timer
);
362 static MpdData
*__magnatune_get_data_album(const char *album
, gboolean exact
)
364 MpdData
*list
= NULL
;
366 sqlite3_stmt
*stmt
= NULL
;
369 GTimer
*timer
= g_timer_new();
372 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
373 "WHERE songs.albumname=%Q",album
);
375 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
376 "WHERE songs.albumname LIKE '%%%%%q%%%%'",album
);
378 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
380 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
382 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
383 list
= mpd_new_data_struct_append(list
);
384 list
->type
= MPD_DATA_TYPE_SONG
;
385 list
->song
= mpd_newSong();
386 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
387 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
388 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
389 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
390 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
391 list
->song
->time
= sqlite3_column_int(stmt
,1);
392 list
->song
->file
= g_strdup_printf("http://he3.magnatune.com/all/%s",temp
);
397 g_warning("Sqlite error: %s\n", tail
);
399 sqlite3_finalize(stmt
);
401 g_debug("%f s elapsed getting album songs\n", g_timer_elapsed(timer
,NULL
));
402 g_timer_destroy(timer
);
405 static gchar
** __magnatune_get_albums(const char *genre
, const char *artist
, gboolean exact
)
408 sqlite3_stmt
*stmt
= NULL
;
414 if(genre
&& !artist
) {
416 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre
);
418 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre
);
420 else if (artist
&& !genre
) {
422 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist
);
424 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist
);
426 else if (artist
&& genre
) {
428 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
);
430 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
);
434 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
436 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
439 retv
= g_realloc(retv
, (items
+1)*sizeof(*retv
));
441 retv
[items
-1] = g_strdup(sqlite3_column_text(stmt
, 0));
444 sqlite3_finalize(stmt
);
449 MpdData
* magnatune_db_get_song_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
, gboolean exact
)
451 MpdData
*data
= NULL
;
456 if(!wanted_genre
&& !wanted_artist
&& !wanted_album
) return NULL
;
458 GTimer
*timer
= g_timer_new();
459 if(wanted_album
) /* album seems to be unique */
461 data
= __magnatune_get_data_album(wanted_album
, exact
);
462 }else if (wanted_genre
&& !wanted_artist
)
464 data
= __magnatune_get_data_album_from_genre(wanted_genre
, exact
);
468 char **albums
= __magnatune_get_albums(wanted_genre
, wanted_artist
, exact
);
472 for(i
=0; albums
[i
];i
++)
474 MpdData
*data2
= __magnatune_get_data_album(albums
[i
], exact
);
475 data
= mpd_data_concatenate(data
, data2
);
481 g_debug("%f s elapsed song list\n", g_timer_elapsed(timer
,NULL
));
482 g_timer_destroy(timer
);
483 return mpd_data_get_first(data
);
486 MpdData
* magnatune_db_search_title(const gchar
*title
)
489 MpdData
*list
= NULL
;
491 sqlite3_stmt
*stmt
= NULL
;
494 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
495 "WHERE songs.desc LIKE '%%%%%q%%%%'",title
);
496 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
498 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
500 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
501 list
= mpd_new_data_struct_append(list
);
502 list
->type
= MPD_DATA_TYPE_SONG
;
503 list
->song
= mpd_newSong();
504 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
505 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
506 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
507 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
508 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
509 list
->song
->time
= sqlite3_column_int(stmt
,1);
510 list
->song
->file
= g_strdup_printf("http://he3.magnatune.com/all/%s",temp
);
514 sqlite3_finalize(stmt
);
521 gchar
*magnatune_get_artist_image(const gchar
*wanted_artist
)
524 sqlite3_stmt
*stmt
= NULL
;
525 char *artist
= __magnatune_process_string(wanted_artist
);
529 query
= sqlite3_mprintf("SELECT homepage from 'artists' WHERE artist LIKE '%%%%%q%%%%' limit 1",artist
);
530 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
532 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
534 gchar
*temp
= gmpc_easy_download_uri_escape( sqlite3_column_text(stmt
, 0));
535 retv
= g_strdup_printf("http://he3.magnatune.com/artists/img/%s_1.jpg", temp
);
539 sqlite3_finalize(stmt
);
545 gchar
*magnatune_get_album_url(const gchar
*wanted_artist
, const gchar
*wanted_album
)
551 gchar
*magnatune_get_album_image(const gchar
*wanted_artist
, const gchar
*wanted_album
)
554 char *artist
= __magnatune_process_string(wanted_artist
);
555 char *album
= __magnatune_process_string(wanted_album
);
556 gchar
*artist_enc
= gmpc_easy_download_uri_escape(artist
);
557 gchar
*album_enc
= gmpc_easy_download_uri_escape(album
);
558 retv
= g_strdup_printf("http://he3.magnatune.com/music/%s/%s/cover_600.jpg",artist_enc
, album_enc
);