configure: If on windows, check for the gmpc import library
[gmpc-magnatune.git] / src / magnatune.c
blob1969a657373957d37398df13df88b689a2fabd04
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.
20 #include <stdio.h>
21 #include <string.h>
22 #include <gtk/gtk.h>
23 #include <gmpc/plugin.h>
24 #include <gmpc/gmpc_easy_download.h>
25 #include <gmpc/misc.h>
26 #include <libmpd/libmpd-internal.h>
27 #include <sqlite3.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);
39 user_name = NULL;
41 if(name && strlen(name) > 0)
42 user_name = gmpc_easy_download_uri_escape(name);
44 if(user_password) g_free(user_password);
45 user_password = NULL;
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)
55 int len = strlen(n);
56 if (len > 4)
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()
79 gchar *path = NULL;
80 const gchar *final = NULL;
83 /**
84 * if open close it
86 if(magnatune_sqlhandle)
88 sqlite3_close(magnatune_sqlhandle);
89 magnatune_sqlhandle = NULL;
92 path = gmpc_get_cache_directory("magnatune.sqlite3");// g_build_filename(final, "gmpc", "magnatune.sqlite3", NULL);
93 sqlite3_open(path, &(magnatune_sqlhandle));
94 g_free(path);
97 /* FIXME */
98 gboolean magnatune_db_has_data()
100 char *query = sqlite3_mprintf("SELECT * from 'sqlite_master'");
101 sqlite3_stmt *stmt = NULL;
102 const char *tail;
103 int r;
106 r= sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
107 sqlite3_free(query);
108 if(r == SQLITE_OK) {
109 while((r = sqlite3_step(stmt)) == SQLITE_ROW){
110 sqlite3_finalize(stmt);
111 return TRUE;
115 sqlite3_finalize(stmt);
116 return FALSE;
119 MpdData * magnatune_db_get_genre_list()
121 MpdData *list = NULL;
122 int i,r;
124 char *query = sqlite3_mprintf("SELECT genre from 'genres' group by genre");
125 sqlite3_stmt *stmt = NULL;
126 const char *tail;
127 GTimer *timer = g_timer_new();
128 r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
129 if(r ==SQLITE_OK) {
130 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
132 list = mpd_new_data_struct_append(list);
133 list->type = MPD_DATA_TYPE_TAG;
134 list->tag_type = MPD_TAG_ITEM_GENRE;
135 list->tag = g_strdup(sqlite3_column_text(stmt,0));
139 sqlite3_finalize(stmt);
140 sqlite3_free(query);
141 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer,NULL));
142 g_timer_reset(timer);
143 list = misc_mpddata_remove_duplicate_songs(list);
144 g_debug("%f s elapsed unique genres list\n", g_timer_elapsed(timer,NULL));
145 g_timer_destroy(timer);
146 return list;
149 void magnatune_db_load_data(const char *data, const goffset length)
151 gchar *error = NULL;
152 gchar *path;
155 // const gchar *final = g_get_user_cache_dir();
156 path = gmpc_get_cache_directory("magnatune.sqlite3");//g_build_filename(final, "gmpc", "magnatune.sqlite3", NULL);
157 if(magnatune_sqlhandle)
159 int status = sqlite3_close(magnatune_sqlhandle);
160 if(status != 0)
162 gchar *temp =g_strdup_printf("Failed to close magnatune db: %i\n", status);
163 playlist3_show_error_message(temp, ERROR_WARNING);
164 g_free(temp);
166 magnatune_sqlhandle = NULL;
168 if(data){
169 GError *error = NULL;
170 gssize size= (gssize)length;
171 g_file_set_contents(path, data, size, &error);
172 if(error) {
173 gchar *temp =g_strdup_printf("Failed to store magnatune db: %s\n", error->message);
174 playlist3_show_error_message(temp, ERROR_WARNING);
175 g_free(temp);
176 g_error_free(error);
179 /* open the db if it is closed */
180 if(!magnatune_sqlhandle) {
183 int retv = sqlite3_open(path, &(magnatune_sqlhandle));
184 if(retv != SQLITE_OK)
186 g_free(path);
188 playlist3_show_error_message("Failed to open the new magnatune database", ERROR_WARNING);
189 /* Cleanup */
190 return;
194 sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL, NULL, &error);
195 if(error)printf("%i: %s",__LINE__, error);
196 sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX genresAlbumname ON genres(albumname);", NULL, NULL, &error);
197 if(error)printf("%i: %s",__LINE__, error);
198 sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX genresGenrename ON genres(genre);", NULL, NULL, &error);
199 if(error)printf("%i: %s",__LINE__, error);
200 sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX albumsAlbumname ON albums(albumname);", NULL, NULL, &error);
201 if(error)printf("%i: %s",__LINE__, error);
203 g_free(path);
206 MpdData * magnatune_db_get_artist_list(char *wanted_genre)
208 MpdData *list = NULL;
209 int r;
210 /** check if there is data */
211 char *query = sqlite3_mprintf("SELECT albumname from 'genres' WHERE genre=%Q", wanted_genre);
212 sqlite3_stmt *stmt = NULL;
213 const char *tail;
214 GTimer *timer = g_timer_new();
215 r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
216 if(r ==SQLITE_OK) {
217 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
219 sqlite3_stmt *stmt2 = NULL;
220 const char *tail2;
221 char *query2 = sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q", sqlite3_column_text(stmt,0));
222 int r2 = sqlite3_prepare_v2(magnatune_sqlhandle, query2, -1, &stmt2, &tail2);
223 if(r2 ==SQLITE_OK) {
224 while((r2 = sqlite3_step(stmt2)) == SQLITE_ROW)
226 list = mpd_new_data_struct_append(list);
227 list->type = MPD_DATA_TYPE_TAG;
228 list->tag_type = MPD_TAG_ITEM_ARTIST;
229 list->tag = g_strdup(sqlite3_column_text(stmt2,0));
232 sqlite3_finalize(stmt2);
233 sqlite3_free(query2);
236 sqlite3_finalize(stmt);
237 sqlite3_free(query);
238 g_debug("%f s elapsed getting genres\n", g_timer_elapsed(timer,NULL));
239 g_timer_reset(timer);
240 list = misc_mpddata_remove_duplicate_songs(list);
242 g_debug("%f s elapsed unique artist list\n", g_timer_elapsed(timer,NULL));
243 g_timer_destroy(timer);
244 return list;
247 MpdData *magnatune_db_get_album_list(char *wanted_genre,char *wanted_artist)
249 int r;
250 MpdData *list = NULL;
251 /** check if there is data */
253 char *query = sqlite3_mprintf("SELECT albumname from 'albums' WHERE artist=%Q",wanted_artist);
254 sqlite3_stmt *stmt = NULL;
255 const char *tail;
256 GTimer *timer = g_timer_new();
257 r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
258 if(r ==SQLITE_OK) {
259 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
261 sqlite3_stmt *stmt2 = NULL;
262 const char *tail2;
263 char *query2 = sqlite3_mprintf("SELECT albumname from 'genres' WHERE albumname=%Q AND genre=%Q", sqlite3_column_text(stmt,0),wanted_genre);
264 int r2 = sqlite3_prepare_v2(magnatune_sqlhandle, query2, -1, &stmt2, &tail2);
265 if(r2 ==SQLITE_OK) {
266 while((r2 = sqlite3_step(stmt2)) == SQLITE_ROW)
268 list = mpd_new_data_struct_append(list);
269 list->type = MPD_DATA_TYPE_TAG;
270 list->tag_type = MPD_TAG_ITEM_ALBUM;
271 list->tag = g_strdup(sqlite3_column_text(stmt2,0));
274 sqlite3_finalize(stmt2);
275 sqlite3_free(query2);
278 sqlite3_finalize(stmt);
279 sqlite3_free(query);
280 g_debug("%f s elapsed listing albums songs\n", g_timer_elapsed(timer,NULL));
281 g_timer_destroy(timer);
282 return mpd_data_get_first(list);
285 static char *__magnatune_get_artist_name(const char *album)
287 char *retv = NULL;
288 sqlite3_stmt *stmt = NULL;
289 const char *tail;
290 int r = 0;
291 char *query = NULL;
292 if(!album) return NULL;
293 query = sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q limit 1",album);
294 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
295 if(r ==SQLITE_OK) {
296 if((r = sqlite3_step(stmt)) == SQLITE_ROW)
298 retv = g_strdup(sqlite3_column_text(stmt, 0));
301 sqlite3_finalize(stmt);
302 sqlite3_free(query);
303 return retv;
305 static char *__magnatune_get_genre_name(const char *album)
307 char *retv = NULL;
308 sqlite3_stmt *stmt = NULL;
309 const char *tail;
310 int r = 0;
311 char *query = NULL;
312 if(!album) return NULL;
313 query = sqlite3_mprintf("SELECT genre from 'genres' WHERE albumname=%Q",album);
314 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
315 if(r ==SQLITE_OK) {
316 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
318 const char *temp= sqlite3_column_text(stmt, 0);
319 if(retv)
321 gchar *t = retv;
322 retv = g_strconcat(t, ", ",temp, NULL);
323 g_free(t);
325 else retv = g_strdup(temp);
329 sqlite3_finalize(stmt);
330 sqlite3_free(query);
331 return retv;
333 static MpdData *__magnatune_get_data_album_from_genre(const char *genre, gboolean exact)
335 MpdData *list = NULL;
336 char *query = NULL;
337 sqlite3_stmt *stmt = NULL;
338 const char *tail;
339 int r = 0;
340 GTimer *timer = g_timer_new();
341 if(exact)
343 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
344 "WHERE genres.genre=%Q",genre);
345 }else{
346 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' JOIN 'genres' ON songs.albumname = genres.albumname "
347 "WHERE genres.genre LIKE '%%%%%q%%%%'",genre);
349 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
350 if(r ==SQLITE_OK) {
351 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
353 gchar *temp = gmpc_easy_download_uri_escape(sqlite3_column_text(stmt,4));
354 list = mpd_new_data_struct_append(list);
355 list->type = MPD_DATA_TYPE_SONG;
356 list->song = mpd_newSong();
357 list->song->album = g_strdup(sqlite3_column_text(stmt,0));
358 list->song->artist = __magnatune_get_artist_name(list->song->album);
359 list->song->genre = __magnatune_get_genre_name(list->song->album);
360 list->song->title= g_strdup(sqlite3_column_text(stmt,3));
361 list->song->track = g_strdup(sqlite3_column_text(stmt,2));
362 list->song->time = sqlite3_column_int(stmt,1);
363 list->song->file = magnatune_get_url(temp);
364 g_free(temp);
366 }else{
367 g_warning("Sqlite error: %s\n", tail);
370 sqlite3_finalize(stmt);
371 sqlite3_free(query);
372 g_debug("%f s elapsed getting album songs from genre\n", g_timer_elapsed(timer,NULL));
373 g_timer_destroy(timer);
374 return list;
377 static MpdData *__magnatune_get_data_album(const char *album, gboolean exact)
379 MpdData *list = NULL;
380 char *query = NULL;
381 sqlite3_stmt *stmt = NULL;
382 const char *tail;
383 int r = 0;
384 GTimer *timer = g_timer_new();
385 if(exact)
387 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
388 "WHERE songs.albumname=%Q",album);
389 }else{
390 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
391 "WHERE songs.albumname LIKE '%%%%%q%%%%'",album);
393 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
394 if(r ==SQLITE_OK) {
395 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
397 gchar *temp = gmpc_easy_download_uri_escape(sqlite3_column_text(stmt,4));
398 list = mpd_new_data_struct_append(list);
399 list->type = MPD_DATA_TYPE_SONG;
400 list->song = mpd_newSong();
401 list->song->album = g_strdup(sqlite3_column_text(stmt,0));
402 list->song->artist = __magnatune_get_artist_name(list->song->album);
403 list->song->genre = __magnatune_get_genre_name(list->song->album);
404 list->song->title= g_strdup(sqlite3_column_text(stmt,3));
405 list->song->track = g_strdup(sqlite3_column_text(stmt,2));
406 list->song->time = sqlite3_column_int(stmt,1);
407 list->song->file = magnatune_get_url(temp);
408 g_free(temp);
411 else{
412 g_warning("Sqlite error: %s\n", tail);
414 sqlite3_finalize(stmt);
415 sqlite3_free(query);
416 g_debug("%f s elapsed getting album songs\n", g_timer_elapsed(timer,NULL));
417 g_timer_destroy(timer);
418 return list;
420 static gchar ** __magnatune_get_albums(const char *genre, const char *artist, gboolean exact)
422 char **retv = NULL;
423 sqlite3_stmt *stmt = NULL;
424 const char *tail;
425 int items = 0;
426 int r = 0;
427 char *query = NULL;
429 if(genre && !artist) {
430 if(exact)
431 query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre);
432 else
433 query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre);
435 else if (artist && !genre) {
436 if(exact)
437 query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist);
438 else
439 query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist);
441 else if (artist && genre) {
442 if(exact)
443 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);
444 else
445 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);
449 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
450 if(r ==SQLITE_OK) {
451 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
453 items++;
454 retv = g_realloc(retv, (items+1)*sizeof(*retv));
455 retv[items] = NULL;
456 retv[items-1] = g_strdup(sqlite3_column_text(stmt, 0));
459 sqlite3_finalize(stmt);
460 sqlite3_free(query);
461 return retv;
464 MpdData* magnatune_db_get_song_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album, gboolean exact)
466 MpdData *data = NULL;
467 char *query;
469 if(!wanted_genre && !wanted_artist && !wanted_album) return NULL;
471 GTimer *timer = g_timer_new();
472 if(wanted_album) /* album seems to be unique */
474 data = __magnatune_get_data_album(wanted_album, exact);
475 }else if (wanted_genre && !wanted_artist)
477 data = __magnatune_get_data_album_from_genre(wanted_genre, exact);
479 else
481 char **albums = __magnatune_get_albums(wanted_genre, wanted_artist, exact);
482 if(albums)
484 int i;
485 for(i=0; albums[i];i++)
487 MpdData *data2 = __magnatune_get_data_album(albums[i], exact);
488 data = mpd_data_concatenate(data, data2);
490 g_strfreev(albums);
494 g_debug("%f s elapsed song list\n", g_timer_elapsed(timer,NULL));
495 g_timer_destroy(timer);
496 return mpd_data_get_first(data);
499 MpdData * magnatune_db_search_title(const gchar *title)
502 MpdData *list = NULL;
503 char *query = NULL;
504 sqlite3_stmt *stmt = NULL;
505 const char *tail;
506 int r = 0;
507 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
508 "WHERE songs.desc LIKE '%%%%%q%%%%'",title);
509 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
510 if(r ==SQLITE_OK) {
511 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
513 gchar *temp = gmpc_easy_download_uri_escape(sqlite3_column_text(stmt,4));
514 list = mpd_new_data_struct_append(list);
515 list->type = MPD_DATA_TYPE_SONG;
516 list->song = mpd_newSong();
517 list->song->album = g_strdup(sqlite3_column_text(stmt,0));
518 list->song->artist = __magnatune_get_artist_name(list->song->album);
519 list->song->genre = __magnatune_get_genre_name(list->song->album);
520 list->song->title= g_strdup(sqlite3_column_text(stmt,3));
521 list->song->track = g_strdup(sqlite3_column_text(stmt,2));
522 list->song->time = sqlite3_column_int(stmt,1);
523 list->song->file = magnatune_get_url(temp);
524 g_free(temp);
527 sqlite3_finalize(stmt);
528 sqlite3_free(query);
529 return list;
534 gchar *magnatune_get_artist_image(const gchar *wanted_artist)
536 char *retv = NULL;
537 sqlite3_stmt *stmt = NULL;
538 char *artist = __magnatune_process_string(wanted_artist);
539 const char *tail;
540 int r = 0;
541 char *query = NULL;
542 query = sqlite3_mprintf("SELECT homepage from 'artists' WHERE artist LIKE '%%%%%q%%%%' limit 1",artist);
543 r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
544 if(r ==SQLITE_OK) {
545 if((r = sqlite3_step(stmt)) == SQLITE_ROW)
547 gchar *temp = gmpc_easy_download_uri_escape( sqlite3_column_text(stmt, 0));
548 retv = g_strdup_printf("http://he3.magnatune.com/artists/img/%s_1.jpg", temp);
549 g_free(temp);
552 sqlite3_finalize(stmt);
553 sqlite3_free(query);
554 g_free(artist);
555 return retv;
558 gchar *magnatune_get_album_url(const gchar *wanted_artist, const gchar *wanted_album)
564 gchar *magnatune_get_album_image(const gchar *wanted_artist, const gchar *wanted_album)
566 char *retv = NULL;
567 char *artist = __magnatune_process_string(wanted_artist);
568 char *album = __magnatune_process_string(wanted_album);
569 gchar *artist_enc = gmpc_easy_download_uri_escape(artist);
570 gchar *album_enc = gmpc_easy_download_uri_escape(album);
571 retv = g_strdup_printf("http://he3.magnatune.com/music/%s/%s/cover_600.jpg",artist_enc, album_enc);
572 g_free(artist);
573 g_free(album);
574 g_free(artist_enc);
575 g_free(album_enc);
576 return retv;