From 3b3f9acccb4c38a81736a424b547b81302885431 Mon Sep 17 00:00:00 2001 From: Qball Cow Date: Tue, 13 Jan 2009 18:01:35 +0100 Subject: [PATCH] Move to sqlite --- configure.ac | 1 + src/magnatune.c | 1204 +++++++++++++++++++++++-------------------------------- src/magnatune.h | 11 +- src/plugin.c | 74 ++-- 4 files changed, 559 insertions(+), 731 deletions(-) rewrite src/magnatune.c (83%) diff --git a/configure.ac b/configure.ac index 7473609..407294a 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,7 @@ PKG_CHECK_MODULES([gmpcmagnatune], libmpd >= 0.15.98 gmpc >= 0.15.98 libglade-2.0 + sqlite3 ]) AC_SUBST(gmpcmagnatune_LIBS) AC_SUBST(gmpcmagnatune_CFLAGS) diff --git a/src/magnatune.c b/src/magnatune.c dissimilarity index 83% index 28de125..21f64c3 100644 --- a/src/magnatune.c +++ b/src/magnatune.c @@ -1,703 +1,501 @@ -/* gmpc-magnatune (GMPC plugin) - * Copyright (C) 2006-2009 Qball Cow - * Project homepage: http://gmpcwiki.sarine.nl/ - - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "magnatune.h" - -static void magnatune_cleanup_xml(); -static axlDoc *magnatune_xmldoc = NULL; -GMutex *mt_db_lock = NULL; - -/* hack fix this */ -int magnatune_end_download(); - -/** - * Makes a copy with all &#; decoded - */ -static char * url_decode(const char *string) -{ - char *retv = NULL; - if(string && string[0] != '\0') - { - int i; - const gchar *a = string; - gchar *b; - b = retv= g_malloc0((strlen(string)+1)*sizeof(char)); - while(*a){ - if(*a == '&'){ - const char *c = a; - while(*c != ';')c++; - /* skip &# */ - a+=2; - *b= (char)atoi(a); - a = c; - } - else - *b = *a; - b++; - a++; - } - } - return retv; -} - -void magnatune_db_destroy(void) -{ - if(mt_db_lock) - { - g_mutex_lock(mt_db_lock); - g_mutex_unlock(mt_db_lock); - g_mutex_free(mt_db_lock); - } - if(magnatune_xmldoc) - { - axl_doc_free(magnatune_xmldoc); - axl_end(); - magnatune_xmldoc = NULL; - } -} - -/* run this before using the other fucntions */ -void magnatune_db_init() -{ - mt_db_lock = g_mutex_new(); - axl_init(); -} - -void magnatune_db_open() -{ - gchar *path = gmpc_get_user_path("magnatune.xml"); - - g_mutex_lock(mt_db_lock); - /** - * if the db doesn't exists exit - */ - if(!g_file_test(path, G_FILE_TEST_EXISTS)) - { - g_free(path); - g_mutex_unlock(mt_db_lock); - return; - } - /** - * if open close it - */ - if(magnatune_xmldoc) - { - axl_doc_free(magnatune_xmldoc); - magnatune_xmldoc = NULL; - } - magnatune_xmldoc = axl_doc_parse_from_file(path, NULL); - - g_mutex_unlock(mt_db_lock); - g_free(path); -} - -gboolean magnatune_db_has_data() -{ - gboolean data = FALSE; - g_mutex_lock(mt_db_lock); - data = (magnatune_xmldoc != NULL)? TRUE:FALSE; - g_mutex_unlock(mt_db_lock); - return data; -} - -MpdData * magnatune_db_get_genre_list() -{ - MpdData *list = NULL; - axlNode *root; - axlNode *cur; - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - const char *genre = NULL; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, "magnatunegenres")) - { - gchar **tokens = NULL; - genre = axl_node_get_content(cur2,NULL); - if(genre) - { - int i =0; - tokens = g_strsplit(genre,",",0); - for(i=0; tokens[i];i++) - { - list = mpd_new_data_struct_append(list); - list->type = MPD_DATA_TYPE_TAG; - list->tag_type = MPD_TAG_ITEM_GENRE; - list->tag = url_decode(tokens[i]); - } - g_strfreev (tokens); - } - } - cur2 = axl_node_get_next(cur2); - } - } - - cur = axl_node_get_next(cur); - } - g_mutex_unlock(mt_db_lock); - return misc_mpddata_remove_duplicate_songs(list); -} - -gchar *magnatune_db_get_value(const char *artist, const char *album, int type) -{ - gchar *retval = NULL; - axlNode *root; - axlNode *cur; - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL || !artist ) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL && !retval) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - const char *gartist = NULL; - const char *galbum = NULL; - const char *gvalue = NULL; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL && !retval) - { - if(!gartist && NODE_CMP_NAME(cur2, "artist")) - { - gartist = axl_node_get_content(cur2,NULL); - } - else if(!galbum && NODE_CMP_NAME(cur2, "albumname")) - { - galbum= axl_node_get_content(cur2,NULL); - } - else if(!gvalue && NODE_CMP_NAME(cur2, ((type== META_ARTIST_ART)?"artistphoto":"cover_small"))) - { - gvalue= axl_node_get_content(cur2,NULL); - } - cur2 = axl_node_get_next(cur2); - } - if(gvalue && artist && !strncmp(gartist, artist,strlen(artist))) - { - if(type == META_ARTIST_ART) - { - retval = url_decode(gvalue); - } - else if(galbum && !strcmp(galbum, album)){ - retval = url_decode(gvalue); - } - } - - } - cur = axl_node_get_next(cur); - } - - g_mutex_unlock(mt_db_lock); - return retval; -} -/** - * This removes duplicate/unused fields from every Track entry, - * This remove around 1/2 the file size - * NOT THREAD SAFE, USE INTERNALLY - */ -static void magnatune_cleanup_xml() -{ - axlNode *root; - axlNode *cur; - if(!magnatune_xmldoc) - return; - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, "Track")) - { - axlNode *cur3 = axl_node_get_first_child(cur2) ; - while(cur3) { - if(NODE_CMP_NAME(cur3, "albumname") || - NODE_CMP_NAME(cur3, "artist") || - NODE_CMP_NAME(cur3, "artistdesc") || - NODE_CMP_NAME(cur3, "home") || - NODE_CMP_NAME (cur3, "artistphoto") || - NODE_CMP_NAME (cur3, "mp3lofi") || - NODE_CMP_NAME (cur3, "albumsku") || - NODE_CMP_NAME (cur3, "mp3genre") || - NODE_CMP_NAME (cur3, "magnatunegenres") || - NODE_CMP_NAME (cur3, "license") || - NODE_CMP_NAME (cur3, "album_notes") || - NODE_CMP_NAME (cur3, "launchdate") || - NODE_CMP_NAME (cur3, "buy") || - NODE_CMP_NAME (cur3, "moods") ) - - { - axl_node_remove(cur3,TRUE); - - cur3 = axl_node_get_first_child(cur2) ; - } else { - cur3 = axl_node_get_next(cur3); - } - } - cur2 = axl_node_get_next(cur2); - } - else if(NODE_CMP_NAME(cur2, "album_notes") || - NODE_CMP_NAME (cur2, "buy") || - NODE_CMP_NAME (cur2, "launchdate")) - { - axl_node_remove(cur2,TRUE); - cur2 = axl_node_get_first_child(cur); - } else { - cur2 = axl_node_get_next(cur2); - } - } - } - cur = axl_node_get_next(cur); - } -} - - -void magnatune_db_download_xml_thread(gpointer data) -{ - gmpc_easy_download_struct *dld = data; - - g_mutex_lock(mt_db_lock); - - if(magnatune_xmldoc) - { - axl_doc_free(magnatune_xmldoc); - - magnatune_xmldoc = NULL; - } - g_mutex_unlock(mt_db_lock); - if(gmpc_easy_download("http://www.magnatune.com/info/album_info.xml", dld)) - { - g_mutex_lock(mt_db_lock); - gchar *path = NULL; - magnatune_xmldoc = axl_doc_parse(dld->data, dld->size, NULL); - magnatune_cleanup_xml(); - path = gmpc_get_user_path("magnatune.xml"); - axl_doc_dump_to_file(magnatune_xmldoc, path); - g_free(path); - g_mutex_unlock(mt_db_lock); - } - else - { - g_mutex_lock(mt_db_lock); - /* update */ - gchar *path = gmpc_get_user_path("magnatune.xml"); - if(g_file_test(path, G_FILE_TEST_EXISTS)) - { - magnatune_xmldoc = axl_doc_parse_from_file(path, NULL); - } - g_free(path); - g_mutex_unlock(mt_db_lock); - } - /** - * cleanup - */ - gmpc_easy_download_clean(dld); - g_free(dld); - - - - g_idle_add(magnatune_end_download, NULL); - -} -void magnatune_db_download_xml(ProgressCallback cb, gpointer data ) -{ - gmpc_easy_download_struct *dld = g_malloc0(sizeof(*dld)); - dld->callback_data = data; - dld->callback = cb; - dld->max_size = -1; - dld->data = NULL; - dld->size = 0; - g_thread_create((GThreadFunc)magnatune_db_download_xml_thread, dld,FALSE, NULL); - -} - -MpdData * magnatune_db_get_artist_list(char *wanted_genre) -{ - MpdData *list = NULL; - axlNode *root; - axlNode *cur; - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL || wanted_genre == NULL) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - const char *genre = NULL; - const char *artist = NULL; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, "magnatunegenres")) - { - genre = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, "artist")) - { - artist = axl_node_get_content(cur2,NULL); - } - cur2 = axl_node_get_next(cur2); - } - if(genre && artist && strstr(genre, wanted_genre)) - { - list = mpd_new_data_struct_append(list); - list->type = MPD_DATA_TYPE_TAG; - list->tag_type = MPD_TAG_ITEM_ARTIST; - list->tag = url_decode(artist); - - } - - } - cur = axl_node_get_next(cur); - } - g_mutex_unlock(mt_db_lock); - return misc_mpddata_remove_duplicate_songs(list); -} - -MpdData *magnatune_db_get_album_list(char *wanted_genre,char *wanted_artist) -{ - MpdData *list = NULL; - axlNode *root; - axlNode *cur; - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL || wanted_genre == NULL || wanted_artist == NULL) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - const char *genre = NULL; - const char *album = NULL; - const char *artist = NULL; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, "magnatunegenres")) - { - genre = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, "artist")) - { - artist = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, "albumname")) - { - album = axl_node_get_content(cur2,NULL); - } - cur2 = axl_node_get_next(cur2); - } - if(genre && artist&&album && strstr(genre, wanted_genre) && !strcmp(artist, wanted_artist)) - { - list = mpd_new_data_struct_append(list); - list->type = MPD_DATA_TYPE_TAG; - list->tag_type = MPD_TAG_ITEM_ALBUM; - list->tag = url_decode(album); - } - } - cur = axl_node_get_next(cur); - } - g_mutex_unlock(mt_db_lock); - return mpd_data_get_first(list); -} - - -GList * magnatune_db_get_url_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album) -{ - GList *list = NULL; - axlNode *root; - axlNode *cur; - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL || wanted_genre == NULL) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode *cur2; - if(NODE_CMP_NAME(cur, "Album")) - { - const char *genre = NULL; - const char *album = NULL; - const char *artist = NULL; - gboolean add_urls = FALSE; - axlNode *tracks; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, "magnatunegenres")) - { - genre = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, "artist")) - { - artist = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, "albumname")) - { - album = axl_node_get_content(cur2,NULL); - } - cur2 = axl_node_get_next(cur2); - } - if(genre && strstr(genre, wanted_genre)) - { - if(wanted_artist && wanted_album) { - if(!strcmp(wanted_artist,artist) && !strcmp(wanted_album, album)) { - add_urls = TRUE; - } - }else if(wanted_artist) { - if(!strcmp(wanted_artist, artist)) { - add_urls = TRUE; - } - } else { - add_urls = TRUE; - } - } - if(add_urls) - { - cur2 = axl_node_get_first_child(cur); - while(cur2) - { - if (NODE_CMP_NAME(cur2, "Track")) - { - tracks = axl_node_get_first_child(cur2); - while(tracks) - { - if (NODE_CMP_NAME(tracks, "url")) - { - const char *url = axl_node_get_content(tracks,NULL); - list = g_list_append(list, url_decode(url)); - } - tracks = axl_node_get_next(tracks); - } - } - cur2 = axl_node_get_next(cur2); - } - } - } - cur = axl_node_get_next(cur); - } - g_mutex_unlock(mt_db_lock); - return list; -} - -static int custcmp(const gchar *hay, const gchar *needle) -{ - int retv = -1; - gchar *sa1 = g_utf8_casefold(needle, -1); - gchar *sa = g_utf8_normalize(sa1,-1,G_NORMALIZE_ALL_COMPOSE); - gchar *sb1 = g_utf8_casefold(hay, -1); - gchar *sb = g_utf8_normalize(sb1,-1,G_NORMALIZE_ALL_COMPOSE); - retv = (strstr(sb, sa) == NULL); - g_free(sa1);g_free(sa); - g_free(sb1);g_free(sb); - return retv; -} - -MpdData* magnatune_db_get_song_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album, gboolean exact) -{ - MpdData *data = NULL; - axlNode * root; - axlNode * cur; - int (*cmpfunc)(const char *hay, const char *needle); - if(exact) - { - cmpfunc = strcmp; - }else{ - cmpfunc = custcmp; - } - /** check if there is data */ - g_mutex_lock(mt_db_lock); - if(magnatune_xmldoc == NULL ) - { - g_mutex_unlock(mt_db_lock); - return NULL; - } - - root = axl_doc_get_root(magnatune_xmldoc); - cur = axl_node_get_first_child(root); - while(cur != NULL) - { - axlNode * cur2; - if(NODE_CMP_NAME(cur, (const char *)"Album")) - { - const char *year = NULL; - const char *temp = NULL; - const char *genre = NULL; - const char *album = NULL; - const char *artist = NULL; - - gboolean add_urls = FALSE; - axlNode * tracks; - cur2 = axl_node_get_first_child(cur); - while(cur2 != NULL) - { - if(NODE_CMP_NAME(cur2, (const char *)"magnatunegenres")) - { - genre = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, (const char *)"artist")) - { - artist = axl_node_get_content(cur2,NULL); - } - else if(NODE_CMP_NAME(cur2, (const char *)"albumname")) - { - album = axl_node_get_content(cur2,NULL); - } - - cur2 = axl_node_get_next(cur2); - } - add_urls = TRUE; - if(wanted_genre && add_urls) { - add_urls = FALSE; - if(genre) - { - int i=0; - gchar **str = g_strsplit(genre, ",", 0); - for(i=0; str && str[i];i++) - { - if(cmpfunc(str[i], wanted_genre) == 0) add_urls = TRUE; - } - if(str)g_strfreev(str); - } - } - if(wanted_album && add_urls) { - add_urls = (album && cmpfunc(album, wanted_album) == 0); - } - if(wanted_artist && add_urls) { - add_urls = (artist && cmpfunc(artist, wanted_artist) == 0); - } - - if(add_urls) - { - cur2 = axl_node_get_first_child(cur); - while(cur2) - { - if (NODE_CMP_NAME(cur2, (const char *)"Track")) - { - const char *tn = NULL; - int stime = 0; - const char *url= NULL; - const char *name = NULL; - - tracks = axl_node_get_first_child(cur2); - - - while(tracks) - { - if (NODE_CMP_NAME(tracks, (const char *)"url")&& !url) - { - url= axl_node_get_content(tracks,NULL); - } - else if (NODE_CMP_NAME(tracks, (const char *)"trackname")&& !name) - { - name = axl_node_get_content(tracks,NULL); - } - - else if (NODE_CMP_NAME(tracks, (const char *)"tracknum")&& !tn) - { - tn = axl_node_get_content(tracks,NULL); - } - else if (NODE_CMP_NAME(tracks, "seconds")&& !stime) - { - const char *eurl = axl_node_get_content(tracks, NULL); - stime = atoi(eurl); - } - else if (NODE_CMP_NAME(tracks, (const char *)"year")&& !year) - { - year = axl_node_get_content(tracks,NULL); - } - tracks = axl_node_get_next(tracks); - } - - if(url){ - data = (MpdData *)mpd_new_data_struct_append((MpdData *)data); - data->type = MPD_DATA_TYPE_SONG; - data->song = mpd_newSong(); - data->song->file = url_decode(url); - data->song->title = url_decode(name); - data->song->album = url_decode(album); - data->song->artist = url_decode(artist); - data->song->genre = url_decode(genre); - data->song->date = url_decode(year); - data->song->track = url_decode(tn); - data->song->time = stime; - } - } - cur2 = axl_node_get_next(cur2); - } - } - } - cur = axl_node_get_next(cur); - } - g_mutex_unlock(mt_db_lock); - return data; -} +/* gmpc-magnatune (GMPC plugin) + * Copyright (C) 2006-2009 Qball Cow + * Project homepage: http://gmpcwiki.sarine.nl/ + + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "magnatune.h" + +static void magnatune_cleanup_xml(); +static sqlite3 *magnatune_sqlhandle = NULL; +GMutex *mt_db_lock = NULL; + +/* hack fix this */ +int magnatune_end_download(); +char *GENRE_LIST[] = +{ +"", "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", +"Grunge", "Hip-Hop", "Jazz", "Metal ", "New Age ", "Oldies ", "Other ", +"Pop ", "R&B ", "Rap ", "Reggae ", "Rock ", "Techno ", "Industrial ", +"Alternative ", "Ska ", "Death Metal ", "Pranks ", "Soundtrack ", "Euro-Techno ", "Ambient ", +"Trip-Hop ", "Vocal ", "Jazz+Funk ", "Fusion ", "Trance ", "Classical ", "Instrumental ", +"Acid ", "House ", "Game ", "Sound Clip ", "Gospel ", "Noise ", "Alternative Rock ", +"Bass ", "Soul ", "Punk ", "Space ", "Meditative ", "Instrumental Pop ", "Instrumental Rock ", +"Ethnic ", "Gothic ", "Darkwave ", "Techno-Industrial ", "Electronic ", "Pop-Folk ", "Eurodance ", +"Dream ", "Southern Rock ", "Comedy ", "Cult ", "Gangsta ", "Top 40 ", "Christian Rap ", +"Pop/Funk ", "Jungle ", "Native US ", "Cabaret ", "New Wave ", "Psychadelic ", "Rave ", +"Showtunes ", "Trailer ", "Lo-Fi ", "Tribal ", "Acid Punk ", "Acid Jazz ", "Polka ", +"Retro ", "Musical ", "Rock & Roll ", "Hard Rock ", "Folk ", "Folk-Rock ", "National Folk ", +"Swing ", "Fast Fusion ", "Bebob ", "Latin ", "Revival ", "Celtic ", "Bluegrass ", +"Avantgarde ", "Gothic Rock ", "Progressive Rock ", "Psychedelic Rock ", "Symphonic Rock ", "Slow Rock ", "Big Band ", +"Chorus ", "Easy Listening ", "Acoustic ", "Humour ", "Speech ", "Chanson ", "Opera ", +"Chamber Music ", "Sonata ", "Symphony ", "Booty Bass ", "Primus ", "Porn Groove ", "Satire", +"Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", +"Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "Acapella", "Euro-House", +"Dance Hall", "Goa", "Drum & Bass", "Club\"House", "Hardcore", "Terror", "Indie", +"BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", +"Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", +"JPop", "Synthpop", "Unknown", NULL +}; + + +void magnatune_db_destroy(void) +{ + if(mt_db_lock) + { + g_mutex_lock(mt_db_lock); + g_mutex_unlock(mt_db_lock); + g_mutex_free(mt_db_lock); + } + if(magnatune_sqlhandle) + { + sqlite3_close(magnatune_sqlhandle); + magnatune_sqlhandle = NULL; + } +} + +/* run this before using the other fucntions */ +void magnatune_db_init() +{ + mt_db_lock = g_mutex_new(); +} + +void magnatune_db_open() +{ + gchar *path = NULL; + + g_mutex_lock(mt_db_lock); + + /** + * if open close it + */ + if(magnatune_sqlhandle) + { + sqlite3_close(magnatune_sqlhandle); + magnatune_sqlhandle = NULL; + } + + g_free(path); + path = gmpc_get_user_path("magnatune.sqlite3"); + sqlite3_open(path, &(magnatune_sqlhandle)); + g_free(path); + + g_mutex_unlock(mt_db_lock); +} +/* FIXME */ +gboolean magnatune_db_has_data() +{ + return TRUE; +} + +MpdData * magnatune_db_get_genre_list() +{ + MpdData *list = NULL; + xmlNodePtr **root; + xmlNodePtr **cur; + int i; + + g_mutex_lock(mt_db_lock); + char *query = sqlite3_mprintf("SELECT genre from 'genres' group by genre"); + sqlite3_stmt *stmt; + const char *tail; + int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + list = mpd_new_data_struct_append(list); + list->type = MPD_DATA_TYPE_TAG; + list->tag_type = MPD_TAG_ITEM_GENRE; + list->tag = g_strdup(sqlite3_column_text(stmt,0)); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + g_mutex_unlock(mt_db_lock); + return misc_mpddata_remove_duplicate_songs(list); +} + +void magnatune_db_download_xml_thread(gpointer data) +{ + gchar *error = NULL; + xmlTextReaderPtr reader = NULL; + gchar *path; + gmpc_easy_download_struct *dld = data; + + g_mutex_lock(mt_db_lock); + + path = gmpc_get_user_path("magnatune.sqlite3"); + if(magnatune_sqlhandle) + { + sqlite3_close(magnatune_sqlhandle); + magnatune_sqlhandle = NULL; + } + if(gmpc_easy_download("http://he3.magnatune.com/info/sqlite_magnatune.db", dld)) + { + g_file_set_contents(path, dld->data, dld->size, NULL); + gmpc_easy_download_clean(dld); + } + /* open the db if it is closed */ + if(!magnatune_sqlhandle) { + + + int retv = sqlite3_open(path, &(magnatune_sqlhandle)); + if(retv != SQLITE_OK) + { + /* Cleanup */ + g_mutex_unlock(mt_db_lock); + return; + } + } + + sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL, NULL, &error); + if(error)printf("%i: %s",__LINE__, error); + sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX genresAlbumname ON genres(albumname);", NULL, NULL, &error); + if(error)printf("%i: %s",__LINE__, error); + sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX songsAlbumname ON songs(albumname);", NULL, NULL, &error); + if(error)printf("%i: %s",__LINE__, error); + sqlite3_exec(magnatune_sqlhandle, "CREATE INDEX artistsAlbumname ON artists(albumname);", NULL, NULL, &error); + if(error)printf("%i: %s",__LINE__, error); + g_free(dld); + g_mutex_unlock(mt_db_lock); + + g_idle_add(magnatune_end_download, NULL); + g_free(path); +} +void magnatune_db_download_xml(ProgressCallback cb, gpointer data ) +{ + gmpc_easy_download_struct *dld = g_malloc0(sizeof(*dld)); + dld->callback_data = data; + dld->callback = cb; + dld->max_size = -1; + dld->data = NULL; + dld->size = 0; + g_thread_create((GThreadFunc)magnatune_db_download_xml_thread, dld,FALSE, NULL); + +} + +MpdData * magnatune_db_get_artist_list(char *wanted_genre) +{ + MpdData *list = NULL; + xmlNodePtr root; + xmlNodePtr cur; + /** check if there is data */ + g_mutex_lock(mt_db_lock); + char *query = sqlite3_mprintf("SELECT albumname from 'genres' WHERE genre=%Q", wanted_genre); + sqlite3_stmt *stmt; + const char *tail; + int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + sqlite3_stmt *stmt2; + const char *tail2; + char *query2 = sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q", sqlite3_column_text(stmt,0)); + printf("%s\n", sqlite3_column_text(stmt, 0)); + int r2 = sqlite3_prepare_v2(magnatune_sqlhandle, query2, -1, &stmt2, &tail2); + if(r2 ==SQLITE_OK) { + while((r2 = sqlite3_step(stmt2)) == SQLITE_ROW) + { + printf("a:%s\n", sqlite3_column_text(stmt2, 0)); + list = mpd_new_data_struct_append(list); + list->type = MPD_DATA_TYPE_TAG; + list->tag_type = MPD_TAG_ITEM_ARTIST; + list->tag = g_strdup(sqlite3_column_text(stmt2,0)); + } + } + sqlite3_finalize(stmt2); + sqlite3_free(query2); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + g_mutex_unlock(mt_db_lock); + return misc_mpddata_remove_duplicate_songs(list); +} + +MpdData *magnatune_db_get_album_list(char *wanted_genre,char *wanted_artist) +{ + MpdData *list = NULL; + xmlNodePtr **root; + xmlNodePtr **cur; + /** check if there is data */ + g_mutex_lock(mt_db_lock); + + char *query = sqlite3_mprintf("SELECT albumname from 'albums' WHERE artist=%Q",wanted_artist); + sqlite3_stmt *stmt; + const char *tail; + int r = sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + sqlite3_stmt *stmt2; + const char *tail2; + char *query2 = sqlite3_mprintf("SELECT albumname from 'genres' WHERE albumname=%Q AND genre=%Q", sqlite3_column_text(stmt,0),wanted_genre); + printf("%s\n", sqlite3_column_text(stmt, 0)); + int r2 = sqlite3_prepare_v2(magnatune_sqlhandle, query2, -1, &stmt2, &tail2); + if(r2 ==SQLITE_OK) { + while((r2 = sqlite3_step(stmt2)) == SQLITE_ROW) + { + printf("a:%s\n", sqlite3_column_text(stmt2, 0)); + list = mpd_new_data_struct_append(list); + list->type = MPD_DATA_TYPE_TAG; + list->tag_type = MPD_TAG_ITEM_ALBUM; + list->tag = g_strdup(sqlite3_column_text(stmt2,0)); + } + } + sqlite3_finalize(stmt2); + sqlite3_free(query2); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + g_mutex_unlock(mt_db_lock); + return mpd_data_get_first(list); +} + +static char *__magnatune_get_artist_name(const char *album) +{ + char *retv = NULL; + sqlite3_stmt *stmt; + const char *tail; + int r = 0; + const char *query = NULL; + if(!album) return NULL; + query = sqlite3_mprintf("SELECT artist from 'albums' WHERE albumname=%Q limit 1",album); + r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + if((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + retv = g_strdup(sqlite3_column_text(stmt, 0)); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + return retv; +} +static char *__magnatune_get_genre_name(const char *album) +{ + char *retv = NULL; + sqlite3_stmt *stmt; + const char *tail; + int r = 0; + const char *query = NULL; + if(!album) return NULL; + query = sqlite3_mprintf("SELECT genre from 'genres' WHERE albumname=%Q",album); + r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + gchar *temp= sqlite3_column_text(stmt, 0); + if(retv) + { + gchar *t = retv; + retv = g_strconcat(t, ", ",temp, NULL); + g_free(t); + } + else retv = g_strdup(temp); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + return retv; +} +static MpdData *__magnatune_get_data_album(const char *album, gboolean exact) +{ + MpdData *list = NULL; + char *query = NULL; + sqlite3_stmt *stmt; + const char *tail; + int r = 0; + if(exact) + { + query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' " + "WHERE songs.albumname=%Q",album); + }else{ + query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' " + "WHERE songs.albumname LIKE '%%%%%q%%%%'",album); + } + r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + gchar *temp = g_uri_escape_string(sqlite3_column_text(stmt,4), NULL, TRUE); + list = mpd_new_data_struct_append(list); + list->type = MPD_DATA_TYPE_SONG; + list->song = mpd_newSong(); + list->song->album = g_strdup(sqlite3_column_text(stmt,0)); + list->song->artist = __magnatune_get_artist_name(list->song->album); + list->song->genre = __magnatune_get_genre_name(list->song->album); + list->song->title= g_strdup(sqlite3_column_text(stmt,3)); + list->song->track = g_strdup(sqlite3_column_text(stmt,2)); + list->song->time = sqlite3_column_int(stmt,1); + list->song->file = g_strdup_printf("http://he3.magnatune.com/all/%s",temp); + g_free(temp); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + return list; +} +static gchar ** __magnatune_get_albums(const char *genre, const char *artist, gboolean exact) +{ + char **retv = NULL; + sqlite3_stmt *stmt; + const char *tail; + int items = 0; + int r = 0; + const char *query = NULL; + + if(genre && !artist) { + if(exact) + query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre=%Q", genre); + else + query = sqlite3_mprintf("SELECT albumname FROM 'genres' WHERE genre LIKE '%%%%%q%%%%'", genre); + } + else if (artist && !genre) { + if(exact) + query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist=%Q", artist); + else + query = sqlite3_mprintf("SELECT albumname FROM 'albums' WHERE artist LIKE '%%%%%q%%%%'", artist); + } + else if (artist && genre) { + if(exact) + 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); + else + 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); + } + + printf("qeury: %s\n", query); + + r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + items++; + retv = g_realloc(retv, (items+1)*sizeof(*retv)); + retv[items] = NULL; + retv[items-1] = g_strdup(sqlite3_column_text(stmt, 0)); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + return retv; +} + +MpdData* magnatune_db_get_song_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album, gboolean exact) +{ + MpdData *data = NULL; + xmlNodePtr * root; + xmlNodePtr * cur; + char *query; + + if(!wanted_genre && !wanted_artist && !wanted_album) return NULL; + + g_mutex_lock(mt_db_lock); + if(wanted_album) /* album seems to be unique */ + { + data = __magnatune_get_data_album(wanted_album, exact); + } + else + { + char **albums = __magnatune_get_albums(wanted_genre, wanted_artist, exact); + if(albums) + { + int i; + for(i=0; albums[i];i++) + { + MpdData *data2 = __magnatune_get_data_album(albums[i], exact); + data = mpd_data_concatenate(data, data2); + } + g_strfreev(albums); + } + } + + g_mutex_unlock(mt_db_lock); + return mpd_data_get_first(data); +} + +MpdData * magnatune_db_search_title(const gchar *title) +{ + + MpdData *list = NULL; + char *query = NULL; + sqlite3_stmt *stmt; + const char *tail; + int r = 0; + query = sqlite3_mprintf("SELECT songs.albumname,duration,number,desc,mp3 from 'songs' " + "WHERE songs.desc LIKE '%%%%%q%%%%'",title); + r=sqlite3_prepare_v2(magnatune_sqlhandle, query, -1, &stmt, &tail); + if(r ==SQLITE_OK) { + while((r = sqlite3_step(stmt)) == SQLITE_ROW) + { + gchar *temp = g_uri_escape_string(sqlite3_column_text(stmt,4), NULL, TRUE); + list = mpd_new_data_struct_append(list); + list->type = MPD_DATA_TYPE_SONG; + list->song = mpd_newSong(); + list->song->album = g_strdup(sqlite3_column_text(stmt,0)); + list->song->artist = __magnatune_get_artist_name(list->song->album); + list->song->genre = __magnatune_get_genre_name(list->song->album); + list->song->title= g_strdup(sqlite3_column_text(stmt,3)); + list->song->track = g_strdup(sqlite3_column_text(stmt,2)); + list->song->time = sqlite3_column_int(stmt,1); + list->song->file = g_strdup_printf("http://he3.magnatune.com/all/%s",temp); + g_free(temp); + } + sqlite3_finalize(stmt); + } + sqlite3_free(query); + return list; +} + + + +gchar *magnatune_get_artist_image(const gchar *wanted_artist) +{ + gchar *retv = NULL; + return retv; +} + +gchar *magnatune_get_album_url(const gchar *wanted_artist, const gchar *wanted_album) +{ +} + + +gchar *magnatune_get_album_image(const gchar *wanted_artist, const gchar *wanted_album) +{ + char *retv = NULL; + char *artist = __magnatune_process_string(wanted_artist); + char *album = __magnatune_process_string(wanted_album); + gchar *artist_enc = g_uri_escape_string(artist, NULL, TRUE); + gchar *album_enc = g_uri_escape_string(album, NULL, TRUE); + retv = g_strdup_printf("http://he3.magnatune.com/music/%s/%s/cover_600.jpg",artist_enc, album_enc); + printf("album url: %s\n", retv); + g_free(artist); + g_free(album); + g_free(artist_enc); + g_free(album_enc); + return retv; +} diff --git a/src/magnatune.h b/src/magnatune.h index cda7487..5b14193 100644 --- a/src/magnatune.h +++ b/src/magnatune.h @@ -26,10 +26,19 @@ void magnatune_db_open(); gboolean magnatune_db_has_data(); MpdData * magnatune_db_get_genre_list(); void magnatune_db_download_xml(ProgressCallback cb, gpointer data ); -gchar *magnatune_db_get_value(const char *artist, const char *album, int type); MpdData * magnatune_db_get_album_list(char *wanted_genre,char *wanted_artist); MpdData * magnatune_db_get_artist_list(char *genre); GList * magnatune_db_get_url_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album); MpdData* magnatune_db_get_song_list(const char *wanted_genre,const char *wanted_artist, const char *wanted_album,gboolean exact); + + +gchar *magnatune_get_artist_image(const gchar *wanted_artist); +gchar *magnatune_get_album_image(const gchar *wanted_artist, const gchar *wanted_album); + +gchar *magnatune_get_album_url(const gchar *wanted_artist, const gchar *wanted_album); + +char * __magnatune_process_string(char *name); + +MpdData * magnatune_db_search_title(const gchar *title); #endif diff --git a/src/plugin.c b/src/plugin.c index 8841e71..e388c01 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -54,7 +54,7 @@ static void magnatune_show_album_list(GtkTreeSelection *selection, gpointer user static void magnatune_show_song_list(GtkTreeSelection *selection, gpointer user_data); static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpointer user_data); static void magnatune_save_myself(void); -static char * __magnatune_process_string(char *name); +char * __magnatune_process_string(char *name); static GtkTreeRowReference *magnatune_ref = NULL; @@ -610,7 +610,7 @@ static void magnatune_add(GtkWidget *cat_tree) } } -static char * __magnatune_process_string(char *name) +char * __magnatune_process_string(char *name) { int i = 0; int j = 0; @@ -643,53 +643,61 @@ static int magnatune_fetch_cover_priority(void){ static void magnatune_fetch_cover_priority_set(int priority){ cfg_set_single_value_as_int(config, "magnatune", "priority", priority); } + static int magnatune_fetch_get_image(mpd_Song *song,MetaDataType type, char **path) { int result = 0; - if(magnatune_db_has_data() == FALSE) - return META_DATA_UNAVAILABLE; + printf("try magnatune\n"); + /* if(type == META_ARTIST_ART && song->artist) { - char *artist = __magnatune_process_string(song->artist); - char *value = magnatune_db_get_value(artist,NULL,META_ARTIST_ART); + char *value = magnatune_get_artist_image(song->artist); if(value) { - gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL}; - *path = gmpc_get_metadata_filename(META_ARTIST_ART, song, NULL); - if(gmpc_easy_download(value, &dld)) - { - g_file_set_contents(*path, dld.data, dld.size, NULL); - return META_DATA_AVAILABLE; - } - gmpc_easy_download_clean(&dld); - g_free(*path); - *path = NULL; - } - g_free(artist); + if(strlen(value) > 0) + { + gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL}; + printf("artist image: %s\n", value); + *path = gmpc_get_metadata_filename(META_ARTIST_ART, song, NULL); + if(gmpc_easy_download(value, &dld)) + { + g_file_set_contents(*path, dld.data, dld.size, NULL); + g_free(value); + gmpc_easy_download_clean(&dld); + return META_DATA_AVAILABLE; + } + gmpc_easy_download_clean(&dld); + g_free(*path); + *path = NULL; + g_free(value); + } + } } - else if(type == META_ALBUM_ART && song->artist && song->album) + else*/ if(type == META_ALBUM_ART && song->artist && song->album) { - char *artist = __magnatune_process_string(song->artist); - char *album= __magnatune_process_string(song->album); - char *value = magnatune_db_get_value(artist,album,META_ALBUM_ART); + printf("try magnatune album\n"); + char *value = magnatune_get_album_image(song->artist,song->album); if(value) { gmpc_easy_download_struct dld = {NULL, 0, -1, NULL,NULL}; - + printf("album image: %s\n", value); *path = gmpc_get_metadata_filename(META_ALBUM_ART, song, NULL); if(gmpc_easy_download(value, &dld)) { g_file_set_contents(*path, dld.data, dld.size, NULL); - return META_DATA_AVAILABLE; + g_free(value); + gmpc_easy_download_clean(&dld); + return META_DATA_AVAILABLE; } - gmpc_easy_download_clean(&dld); - g_free(*path); + gmpc_easy_download_clean(&dld); + g_free(*path); *path = NULL; + g_free(value); } - g_free(artist); } return META_DATA_UNAVAILABLE; } + static void magnatune_redownload_reload_db() { GtkTreeIter iter; @@ -865,17 +873,26 @@ static int magnatune_button_handle_release_event_tag_add(GtkWidget *button, gpoi gtk_tree_model_get(model, &piter, MPDDATA_MODEL_COL_SONG_TITLE,&album,-1); } } + /* list = magnatune_db_get_url_list(genre, artist, album); for(;list; list = list->next) { mpd_playlist_queue_add(connection, list->data); } + */ + + data = magnatune_db_get_song_list(genre,artist,album, TRUE); + for(data = mpd_data_get_first(data);data;data = mpd_data_get_next(data)) { + mpd_playlist_queue_add(connection, data->song->file); + } mpd_playlist_queue_commit(connection); + /* if(list) { g_list_foreach(list, (GFunc)g_free, NULL); g_list_free(list); } + */ if(genre) g_free(genre); if(artist) @@ -1052,6 +1069,9 @@ static MpdData * magnatune_integrate_search(const int search_field, const gchar case MPD_TAG_ITEM_GENRE: genre = query; break; + case MPD_TAG_ITEM_TITLE: + return magnatune_db_search_title(query); + break; default: g_set_error(error, 0,0, "This type of search query is not supported"); return NULL; -- 2.11.4.GIT