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 <playlist3-messages.h>
29 #include "magnatune.h"
31 static sqlite3
*magnatune_sqlhandle
= NULL
;
33 static gchar
*user_name
= NULL
;
34 static gchar
*user_password
= NULL
;
36 void magnatune_set_user_password(const gchar
*name
, const gchar
*password
)
38 if(user_name
) g_free(user_name
);
41 if(name
&& strlen(name
) > 0)
42 user_name
= gmpc_easy_download_uri_escape(name
);
44 if(user_password
) g_free(user_password
);
47 if(password
&& strlen(password
) > 0)
48 user_password
= gmpc_easy_download_uri_escape(password
);
51 static gchar
*magnatune_get_url(const gchar
*n
)
53 if(user_name
!= NULL
&& user_password
!= NULL
)
57 return g_strdup_printf("http://%s:%s@stream.magnatune.com/all/%*.*s_nospeech.mp3",user_name
, user_password
, len
- 4, len
- 4, n
);
60 return g_strdup_printf("http://he3.magnatune.com/all/%s",n
);
63 void magnatune_db_destroy(void)
65 if(magnatune_sqlhandle
)
67 sqlite3_close(magnatune_sqlhandle
);
68 magnatune_sqlhandle
= NULL
;
72 /* run this before using the other fucntions */
73 void magnatune_db_init()
77 void magnatune_db_open()
80 const gchar
*final
= NULL
;
86 if(magnatune_sqlhandle
)
88 sqlite3_close(magnatune_sqlhandle
);
89 magnatune_sqlhandle
= NULL
;
92 final
= g_get_user_cache_dir();
93 path
= g_build_filename(final
, "gmpc", "magnatune.sqlite3", NULL
);
94 sqlite3_open(path
, &(magnatune_sqlhandle
));
99 gboolean
magnatune_db_has_data()
101 char *query
= sqlite3_mprintf("SELECT * from 'sqlite_master'");
102 sqlite3_stmt
*stmt
= NULL
;
107 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
110 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
){
111 sqlite3_finalize(stmt
);
116 sqlite3_finalize(stmt
);
120 MpdData
* magnatune_db_get_genre_list()
122 MpdData
*list
= NULL
;
125 char *query
= sqlite3_mprintf("SELECT genre from 'genres' group by genre");
126 sqlite3_stmt
*stmt
= NULL
;
128 GTimer
*timer
= g_timer_new();
129 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
131 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
133 list
= mpd_new_data_struct_append(list
);
134 list
->type
= MPD_DATA_TYPE_TAG
;
135 list
->tag_type
= MPD_TAG_ITEM_GENRE
;
136 list
->tag
= g_strdup(sqlite3_column_text(stmt
,0));
140 sqlite3_finalize(stmt
);
142 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer
,NULL
));
143 g_timer_reset(timer
);
144 list
= misc_mpddata_remove_duplicate_songs(list
);
145 g_debug("%f s elapsed unique genres list\n", g_timer_elapsed(timer
,NULL
));
146 g_timer_destroy(timer
);
150 void magnatune_db_load_data(const char *data
, const goffset length
)
156 const gchar
*final
= g_get_user_cache_dir();
157 path
= g_build_filename(final
, "gmpc", "magnatune.sqlite3", NULL
);
158 if(magnatune_sqlhandle
)
160 int status
= sqlite3_close(magnatune_sqlhandle
);
163 gchar
*temp
=g_strdup_printf("Failed to close magnatune db: %i\n", status
);
164 playlist3_show_error_message(temp
, ERROR_WARNING
);
167 magnatune_sqlhandle
= NULL
;
170 GError
*error
= NULL
;
171 gssize size
= (gssize
)length
;
172 g_file_set_contents(path
, data
, size
, &error
);
174 gchar
*temp
=g_strdup_printf("Failed to store magnatune db: %s\n", error
->message
);
175 playlist3_show_error_message(temp
, ERROR_WARNING
);
180 /* open the db if it is closed */
181 if(!magnatune_sqlhandle
) {
184 int retv
= sqlite3_open(path
, &(magnatune_sqlhandle
));
185 if(retv
!= SQLITE_OK
)
189 playlist3_show_error_message("Failed to open the new magnatune database", ERROR_WARNING
);
195 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL
, NULL
, &error
);
196 if(error
)printf("%i: %s",__LINE__
, error
);
197 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX genresAlbumname ON genres(albumname);", NULL
, NULL
, &error
);
198 if(error
)printf("%i: %s",__LINE__
, error
);
199 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX genresGenrename ON genres(genre);", NULL
, NULL
, &error
);
200 if(error
)printf("%i: %s",__LINE__
, error
);
201 sqlite3_exec(magnatune_sqlhandle
, "CREATE INDEX albumsAlbumname ON albums(albumname);", NULL
, NULL
, &error
);
202 if(error
)printf("%i: %s",__LINE__
, error
);
207 MpdData
* magnatune_db_get_artist_list(char *wanted_genre
)
209 MpdData
*list
= NULL
;
211 /** check if there is data */
212 char *query
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE genre=%Q", wanted_genre
);
213 sqlite3_stmt
*stmt
= NULL
;
215 GTimer
*timer
= g_timer_new();
216 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
218 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
220 sqlite3_stmt
*stmt2
= NULL
;
222 char *query2
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q", sqlite3_column_text(stmt
,0));
223 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
225 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
227 list
= mpd_new_data_struct_append(list
);
228 list
->type
= MPD_DATA_TYPE_TAG
;
229 list
->tag_type
= MPD_TAG_ITEM_ARTIST
;
230 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
233 sqlite3_finalize(stmt2
);
234 sqlite3_free(query2
);
237 sqlite3_finalize(stmt
);
239 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer
,NULL
));
240 g_timer_reset(timer
);
241 list
= misc_mpddata_remove_duplicate_songs(list
);
243 g_debug("%f s elapsed unique artist list\n", g_timer_elapsed(timer
,NULL
));
244 g_timer_destroy(timer
);
248 MpdData
*magnatune_db_get_album_list(char *wanted_genre
,char *wanted_artist
)
251 MpdData
*list
= NULL
;
252 /** check if there is data */
254 char *query
= sqlite3_mprintf("SELECT albumname from 'albums' WHERE artist=%Q",wanted_artist
);
255 sqlite3_stmt
*stmt
= NULL
;
257 GTimer
*timer
= g_timer_new();
258 r
= sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
260 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
262 sqlite3_stmt
*stmt2
= NULL
;
264 char *query2
= sqlite3_mprintf("SELECT albumname from 'genres' WHERE albumname=%Q AND genre=%Q", sqlite3_column_text(stmt
,0),wanted_genre
);
265 int r2
= sqlite3_prepare_v2(magnatune_sqlhandle
, query2
, -1, &stmt2
, &tail2
);
267 while((r2
= sqlite3_step(stmt2
)) == SQLITE_ROW
)
269 list
= mpd_new_data_struct_append(list
);
270 list
->type
= MPD_DATA_TYPE_TAG
;
271 list
->tag_type
= MPD_TAG_ITEM_ALBUM
;
272 list
->tag
= g_strdup(sqlite3_column_text(stmt2
,0));
275 sqlite3_finalize(stmt2
);
276 sqlite3_free(query2
);
279 sqlite3_finalize(stmt
);
281 g_debug("%f s elapsed listing albums songs\n", g_timer_elapsed(timer
,NULL
));
282 g_timer_destroy(timer
);
283 return mpd_data_get_first(list
);
286 static char *__magnatune_get_artist_name(const char *album
)
289 sqlite3_stmt
*stmt
= NULL
;
293 if(!album
) return NULL
;
294 query
= sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q limit 1",album
);
295 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
297 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
299 retv
= g_strdup(sqlite3_column_text(stmt
, 0));
302 sqlite3_finalize(stmt
);
306 static char *__magnatune_get_genre_name(const char *album
)
309 sqlite3_stmt
*stmt
= NULL
;
313 if(!album
) return NULL
;
314 query
= sqlite3_mprintf("SELECT genre from 'genres' WHERE albumname=%Q",album
);
315 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
317 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
319 const char *temp
= sqlite3_column_text(stmt
, 0);
323 retv
= g_strconcat(t
, ", ",temp
, NULL
);
326 else retv
= g_strdup(temp
);
330 sqlite3_finalize(stmt
);
334 static MpdData
*__magnatune_get_data_album_from_genre(const char *genre
, gboolean exact
)
336 MpdData
*list
= NULL
;
338 sqlite3_stmt
*stmt
= NULL
;
341 GTimer
*timer
= g_timer_new();
344 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
345 "WHERE genres.genre=%Q",genre
);
347 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
348 "WHERE genres.genre LIKE '%%%%%q%%%%'",genre
);
350 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
352 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
354 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
355 list
= mpd_new_data_struct_append(list
);
356 list
->type
= MPD_DATA_TYPE_SONG
;
357 list
->song
= mpd_newSong();
358 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
359 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
360 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
361 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
362 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
363 list
->song
->time
= sqlite3_column_int(stmt
,1);
364 list
->song
->file
= magnatune_get_url(temp
);
368 g_warning("Sqlite error: %s\n", tail
);
371 sqlite3_finalize(stmt
);
373 g_debug("%f s elapsed getting album songs from genre\n", g_timer_elapsed(timer
,NULL
));
374 g_timer_destroy(timer
);
378 static MpdData
*__magnatune_get_data_album(const char *album
, gboolean exact
)
380 MpdData
*list
= NULL
;
382 sqlite3_stmt
*stmt
= NULL
;
385 GTimer
*timer
= g_timer_new();
388 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
389 "WHERE songs.albumname=%Q",album
);
391 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
392 "WHERE songs.albumname LIKE '%%%%%q%%%%'",album
);
394 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
396 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
398 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
399 list
= mpd_new_data_struct_append(list
);
400 list
->type
= MPD_DATA_TYPE_SONG
;
401 list
->song
= mpd_newSong();
402 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
403 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
404 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
405 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
406 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
407 list
->song
->time
= sqlite3_column_int(stmt
,1);
408 list
->song
->file
= magnatune_get_url(temp
);
413 g_warning("Sqlite error: %s\n", tail
);
415 sqlite3_finalize(stmt
);
417 g_debug("%f s elapsed getting album songs\n", g_timer_elapsed(timer
,NULL
));
418 g_timer_destroy(timer
);
421 static gchar
** __magnatune_get_albums(const char *genre
, const char *artist
, gboolean exact
)
424 sqlite3_stmt
*stmt
= NULL
;
430 if(genre
&& !artist
) {
432 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre
);
434 query
= sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre
);
436 else if (artist
&& !genre
) {
438 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist
);
440 query
= sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist
);
442 else if (artist
&& genre
) {
444 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
);
446 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
);
450 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
452 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
455 retv
= g_realloc(retv
, (items
+1)*sizeof(*retv
));
457 retv
[items
-1] = g_strdup(sqlite3_column_text(stmt
, 0));
460 sqlite3_finalize(stmt
);
465 MpdData
* magnatune_db_get_song_list(const char *wanted_genre
,const char *wanted_artist
, const char *wanted_album
, gboolean exact
)
467 MpdData
*data
= NULL
;
470 if(!wanted_genre
&& !wanted_artist
&& !wanted_album
) return NULL
;
472 GTimer
*timer
= g_timer_new();
473 if(wanted_album
) /* album seems to be unique */
475 data
= __magnatune_get_data_album(wanted_album
, exact
);
476 }else if (wanted_genre
&& !wanted_artist
)
478 data
= __magnatune_get_data_album_from_genre(wanted_genre
, exact
);
482 char **albums
= __magnatune_get_albums(wanted_genre
, wanted_artist
, exact
);
486 for(i
=0; albums
[i
];i
++)
488 MpdData
*data2
= __magnatune_get_data_album(albums
[i
], exact
);
489 data
= mpd_data_concatenate(data
, data2
);
495 g_debug("%f s elapsed song list\n", g_timer_elapsed(timer
,NULL
));
496 g_timer_destroy(timer
);
497 return mpd_data_get_first(data
);
500 MpdData
* magnatune_db_search_title(const gchar
*title
)
503 MpdData
*list
= NULL
;
505 sqlite3_stmt
*stmt
= NULL
;
508 query
= sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
509 "WHERE songs.desc LIKE '%%%%%q%%%%'",title
);
510 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
512 while((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
514 gchar
*temp
= gmpc_easy_download_uri_escape(sqlite3_column_text(stmt
,4));
515 list
= mpd_new_data_struct_append(list
);
516 list
->type
= MPD_DATA_TYPE_SONG
;
517 list
->song
= mpd_newSong();
518 list
->song
->album
= g_strdup(sqlite3_column_text(stmt
,0));
519 list
->song
->artist
= __magnatune_get_artist_name(list
->song
->album
);
520 list
->song
->genre
= __magnatune_get_genre_name(list
->song
->album
);
521 list
->song
->title
= g_strdup(sqlite3_column_text(stmt
,3));
522 list
->song
->track
= g_strdup(sqlite3_column_text(stmt
,2));
523 list
->song
->time
= sqlite3_column_int(stmt
,1);
524 list
->song
->file
= magnatune_get_url(temp
);
528 sqlite3_finalize(stmt
);
535 gchar
*magnatune_get_artist_image(const gchar
*wanted_artist
)
538 sqlite3_stmt
*stmt
= NULL
;
539 char *artist
= __magnatune_process_string(wanted_artist
);
543 query
= sqlite3_mprintf("SELECT homepage from 'artists' WHERE artist LIKE '%%%%%q%%%%' limit 1",artist
);
544 r
=sqlite3_prepare_v2(magnatune_sqlhandle
, query
, -1, &stmt
, &tail
);
546 if((r
= sqlite3_step(stmt
)) == SQLITE_ROW
)
548 gchar
*temp
= gmpc_easy_download_uri_escape( sqlite3_column_text(stmt
, 0));
549 retv
= g_strdup_printf("http://he3.magnatune.com/artists/img/%s_1.jpg", temp
);
553 sqlite3_finalize(stmt
);
559 gchar
*magnatune_get_album_url(const gchar
*wanted_artist
, const gchar
*wanted_album
)
565 gchar
*magnatune_get_album_image(const gchar
*wanted_artist
, const gchar
*wanted_album
)
568 char *artist
= __magnatune_process_string(wanted_artist
);
569 char *album
= __magnatune_process_string(wanted_album
);
570 gchar
*artist_enc
= gmpc_easy_download_uri_escape(artist
);
571 gchar
*album_enc
= gmpc_easy_download_uri_escape(album
);
572 retv
= g_strdup_printf("http://he3.magnatune.com/music/%s/%s/cover_600.jpg",artist_enc
, album_enc
);