Make db_has_data() check work.
[gmpc-magnatune.git] / src / magnatune.c
blob89b660797066026cf57e7f546d3fb416924ec813
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 <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)
39 if(mt_db_lock)
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()
60 gchar *path = NULL;
62 g_mutex_lock(mt_db_lock);
64 /**
65 * if open close it
67 if(magnatune_sqlhandle)
69 sqlite3_close(magnatune_sqlhandle);
70 magnatune_sqlhandle = NULL;
73 g_free(path);
74 path = gmpc_get_user_path("magnatune.sqlite3");
75 sqlite3_open(path, &(magnatune_sqlhandle));
76 g_free(path);
78 g_mutex_unlock(mt_db_lock);
80 /* FIXME */
81 gboolean magnatune_db_has_data()
83 char *query = sqlite3_mprintf("SELECT * from 'sqlite_master'");
84 sqlite3_stmt *stmt;
85 const char *tail;
86 int r;
89 g_mutex_lock(mt_db_lock);
90 r= sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
91 sqlite3_free(query);
92 if(r == SQLITE_OK) {
93 while((r = sqlite3_step(stmt)) == SQLITE_ROW){
94 sqlite3_finalize(stmt);
95 g_mutex_unlock(mt_db_lock);
96 return TRUE;
100 g_mutex_unlock(mt_db_lock);
101 return FALSE;
104 MpdData * magnatune_db_get_genre_list()
106 MpdData *list = NULL;
107 xmlNodePtr **root;
108 xmlNodePtr **cur;
109 int i;
111 g_mutex_lock(mt_db_lock);
112 char *query = sqlite3_mprintf("SELECT genre from 'genres' group by genre");
113 sqlite3_stmt *stmt;
114 const char *tail;
115 int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
116 if(r ==SQLITE_OK) {
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);
126 sqlite3_free(query);
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)
133 gchar *error = NULL;
134 xmlTextReaderPtr reader = NULL;
135 gchar *path;
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))
146 if(data){
147 GError *error = NULL;
148 gssize size= (gssize)length;
149 g_file_set_contents(path, data, size, &error);
150 if(error) {
151 printf("%s\n", error->message);
152 g_error_free(error);
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)
164 /* Cleanup */
165 g_mutex_unlock(mt_db_lock);
166 return;
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);
179 g_free(path);
182 MpdData * magnatune_db_get_artist_list(char *wanted_genre)
184 MpdData *list = NULL;
185 xmlNodePtr root;
186 xmlNodePtr cur;
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);
190 sqlite3_stmt *stmt;
191 const char *tail;
192 int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
193 if(r ==SQLITE_OK) {
194 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
196 sqlite3_stmt *stmt2;
197 const char *tail2;
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);
200 if(r2 ==SQLITE_OK) {
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);
214 sqlite3_free(query);
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;
222 xmlNodePtr **root;
223 xmlNodePtr **cur;
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);
228 sqlite3_stmt *stmt;
229 const char *tail;
230 int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail);
231 if(r ==SQLITE_OK) {
232 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
234 sqlite3_stmt *stmt2;
235 const char *tail2;
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);
238 if(r2 ==SQLITE_OK) {
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);
252 sqlite3_free(query);
253 g_mutex_unlock(mt_db_lock);
254 return mpd_data_get_first(list);
257 static char *__magnatune_get_artist_name(const char *album)
259 char *retv = NULL;
260 sqlite3_stmt *stmt;
261 const char *tail;
262 int r = 0;
263 char *query = NULL;
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);
267 if(r ==SQLITE_OK) {
268 if((r = sqlite3_step(stmt)) == SQLITE_ROW)
270 retv = g_strdup(sqlite3_column_text(stmt, 0));
272 sqlite3_finalize(stmt);
274 sqlite3_free(query);
275 return retv;
277 static char *__magnatune_get_genre_name(const char *album)
279 char *retv = NULL;
280 sqlite3_stmt *stmt;
281 const char *tail;
282 int r = 0;
283 char *query = NULL;
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);
287 if(r ==SQLITE_OK) {
288 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
290 const char *temp= sqlite3_column_text(stmt, 0);
291 if(retv)
293 gchar *t = retv;
294 retv = g_strconcat(t, ", ",temp, NULL);
295 g_free(t);
297 else retv = g_strdup(temp);
299 sqlite3_finalize(stmt);
301 sqlite3_free(query);
302 return retv;
304 static MpdData *__magnatune_get_data_album(const char *album, gboolean exact)
306 MpdData *list = NULL;
307 char *query = NULL;
308 sqlite3_stmt *stmt;
309 const char *tail;
310 int r = 0;
311 if(exact)
313 query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' "
314 "WHERE songs.albumname=%Q",album);
315 }else{
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);
320 if(r ==SQLITE_OK) {
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);
334 g_free(temp);
336 sqlite3_finalize(stmt);
338 sqlite3_free(query);
339 return list;
341 static gchar ** __magnatune_get_albums(const char *genre, const char *artist, gboolean exact)
343 char **retv = NULL;
344 sqlite3_stmt *stmt;
345 const char *tail;
346 int items = 0;
347 int r = 0;
348 char *query = NULL;
350 if(genre && !artist) {
351 if(exact)
352 query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre);
353 else
354 query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre);
356 else if (artist && !genre) {
357 if(exact)
358 query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist);
359 else
360 query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist);
362 else if (artist && genre) {
363 if(exact)
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);
365 else
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);
371 if(r ==SQLITE_OK) {
372 while((r = sqlite3_step(stmt)) == SQLITE_ROW)
374 items++;
375 retv = g_realloc(retv, (items+1)*sizeof(*retv));
376 retv[items] = NULL;
377 retv[items-1] = g_strdup(sqlite3_column_text(stmt, 0));
379 sqlite3_finalize(stmt);
381 sqlite3_free(query);
382 return retv;
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;
388 xmlNodePtr * root;
389 xmlNodePtr * cur;
390 char *query;
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);
399 else
401 char **albums = __magnatune_get_albums(wanted_genre, wanted_artist, exact);
402 if(albums)
404 int i;
405 for(i=0; albums[i];i++)
407 MpdData *data2 = __magnatune_get_data_album(albums[i], exact);
408 data = mpd_data_concatenate(data, data2);
410 g_strfreev(albums);
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;
422 char *query = NULL;
423 sqlite3_stmt *stmt;
424 const char *tail;
425 int r = 0;
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);
429 if(r ==SQLITE_OK) {
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);
443 g_free(temp);
445 sqlite3_finalize(stmt);
447 sqlite3_free(query);
448 return list;
453 gchar *magnatune_get_artist_image(const gchar *wanted_artist)
455 char *retv = NULL;
456 sqlite3_stmt *stmt;
457 char *artist = __magnatune_process_string(wanted_artist);
458 const char *tail;
459 int r = 0;
460 char *query = NULL;
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);
463 if(r ==SQLITE_OK) {
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);
468 g_free(temp);
470 sqlite3_finalize(stmt);
472 sqlite3_free(query);
473 g_free(artist);
474 return retv;
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)
485 char *retv = NULL;
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);
491 g_free(artist);
492 g_free(album);
493 g_free(artist_enc);
494 g_free(album_enc);
495 return retv;