Mercurial > audlegacy-plugins
changeset 1217:d4efe4889489
rendered the lastfm transport plugin stable again, preparing it for its GUI
author | Cristi Magherusan <majeru@atheme-project.org> |
---|---|
date | Mon, 09 Jul 2007 05:01:16 +0300 |
parents | cc04ccffaa8d |
children | cc4e03df48a3 |
files | src/lastfm/lastfm.c src/lastfm/lastfm.h |
diffstat | 2 files changed, 263 insertions(+), 351 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lastfm/lastfm.c Sun Jul 08 22:26:25 2007 +0300 +++ b/src/lastfm/lastfm.c Mon Jul 09 05:01:16 2007 +0300 @@ -28,6 +28,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + Current status and known issues: + - Works fine ant is relatively stable unless DEBUG is enabled (read below) + - The adjust fails when having 2 or more opened streams at the same time. + * It will randomly adjust to any one of them, because the playlist keeps + pulling metadata + - When the network is disconnected opening a new track freezes the player + * This seems to recover after the connection is restablished + * Ordinary mp3 streams seem to share this behavior. Didnt tested if others do. +*/ + #include <audacious/vfs.h> #include <audacious/plugin.h> #include <audacious/configdb.h> @@ -36,7 +47,10 @@ #include <glib.h> #include "lastfm.h" -#define DEBUG 1 +#define DEBUG 0 +/*Caution!!! setting DEBUG to 1 is very likely to crash the player because the g_print-ed values +aren't checked of being !=NULL +*/ size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata) { @@ -49,7 +63,7 @@ { CURL *curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); - curl_easy_setopt(curl, CURLOPT_USERAGENT, "mplayer"); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "Audacious"); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, lastfm_store_res); curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); @@ -61,503 +75,399 @@ return status; } -gchar* lastfm_get_login_uri() -{ -#if DEBUG - g_print("Getting login data from config\n"); -#endif - - ConfigDb *cfgfile = NULL; +gchar* lastfm_get_login_uri() /* reads the audioscrobbler login data from the config */ +{ /* and then uses them to create a login URL*/ + ConfigDb *cfg = NULL; gchar *buf=NULL, *username = NULL, *password = NULL; - if ((cfgfile = bmp_cfg_db_open()) != NULL) + if ((cfg = bmp_cfg_db_open()) != NULL) { - bmp_cfg_db_get_string(cfgfile, "audioscrobbler","username", + bmp_cfg_db_get_string(cfg, "audioscrobbler","username", &username); - bmp_cfg_db_get_string(cfgfile, "audioscrobbler","password", + bmp_cfg_db_get_string(cfg, "audioscrobbler","password", &password); - g_free(cfgfile); + g_free(cfg); } if (username != NULL && password != NULL) { -#if DEBUG - g_print("Creating the login URI\n"); -#endif - buf=g_strdup_printf(LASTFM_HANDSHAKE_URL, username, password); g_free(password); g_free(username); -#if DEBUG - g_print("Succesfully created the login uri\n"); -#endif return buf; } - else { + else + { #if DEBUG g_print("Couldn't find the login data. Use the scrobbler plugin to set it up.\n"); #endif - - return NULL; + return NULL; } } -void lastfm_store(gchar *var_name,gchar* var){ -if (mowgli_global_storage_get(var_name)) - mowgli_global_storage_free(var_name); + void lastfm_store(gchar *var_name,gchar* var){ /*mowgli storage wrapper*/ + if (mowgli_global_storage_get(var_name)) + mowgli_global_storage_free(var_name); + mowgli_global_storage_put(var_name,var); + } - mowgli_global_storage_put(var_name,var); -#if DEBUG - g_print("Storing into '%s' the value '%s'\n",var_name,var); -#endif -} - -int lastfm_login(void) +int lastfm_login(void) /*gets the session ID and the mp3 stream URL and stores them*/ { - /*gets the session ID in the URL to be played and stores them using - * mowgli_global_storage - * read http://gabistapler.de/blog/index.php?/archives/268-Play-last.fm-streams-without-the-player.html for more info - */ - - gint status, i; - gchar *lastfm_session_id=NULL, - *lastfm_stream_uri=NULL, - *login_uri=NULL, + gint status, i, + ret=LASTFM_LOGIN_OK; /*suppose everything goes fine*/ + gchar *login_uri=NULL, **split = NULL; - GString *res = g_string_new(NULL); -g_print("Logging in\n"); + GString *res; login_uri=lastfm_get_login_uri(); - if(login_uri==NULL){ + if(login_uri==NULL) + { g_free(login_uri); return LASTFM_MISSING_LOGIN_DATA; - } + } + res = g_string_new(NULL); status = lastfm_get_data_from_uri(login_uri, res); #if DEBUG g_print("Opened login URI: '%s'\n", login_uri); g_print("Got following data: '%s'\n", res->str); #endif - if (status == CURLE_OK) { split = g_strsplit(res->str, "\n", 7); - for (i = 0; split && split[i]; i++) { if (g_str_has_prefix(split[i], "session=")) - { - lastfm_session_id = g_strndup(split[i] + 8, 32); -#if DEBUG - g_print("Got session ID:'%s'\n",lastfm_session_id); -#endif - } + lastfm_store("lastfm_session_id",g_strndup(split[i] + 8, 32)); else if (g_str_has_prefix(split[i], "stream_url=")) - lastfm_stream_uri = g_strdup(split[i] + 11); + lastfm_store("lastfm_stream_uri" ,g_strdup(split[i] + 11)); } } else - { - g_strfreev(split); - g_string_erase(res, 0, -1); - g_free(lastfm_session_id); - g_free(lastfm_stream_uri); - g_free(login_uri); - return LASTFM_LOGIN_ERROR; - } - lastfm_store("lastfm_session_id",lastfm_session_id); - lastfm_store("lastfm_stream_uri",lastfm_stream_uri); - -#if DEBUG - g_print("Login finished succesfully\n"); -#endif + ret = LASTFM_LOGIN_ERROR; g_strfreev(split); g_string_erase(res, 0, -1); g_free(login_uri); - return LASTFM_LOGIN_OK ; + return ret; +} + +gint lastfm_adjust(const gchar * uri) /*tunes into a channel*/ +{ + gint status, i,ret = LASTFM_ADJUST_FAILED; + gchar *fetch_url=NULL, + *session_id, + **split = NULL; + GString *res; + session_id=mowgli_global_storage_get("lastfm_session_id"); + if (!session_id) + { +#if DEBUG + g_print("Adjust failed! Session ID not set.\n"); +#endif + return LASTFM_SESSION_MISSING; + } + fetch_url=g_strdup_printf(LASTFM_ADJUST_URL, session_id, uri); + res= g_string_new(NULL); + status = lastfm_get_data_from_uri(fetch_url, res); +#if 0 + g_print("\nAdjusting: \nSession ID:%s\n",session_id); + g_print("Fetch URL:%s\n",fetch_url); + g_print("Adjust OK, \nReceived data:\n%s\n", res->str); +#endif + if (status == CURLE_OK) + { + split = g_strsplit(res->str, "\n", 3); + for (i = 0; split && split[i]; i++) + { + if (g_str_has_prefix(split[i], "response=OK")) + ret = LASTFM_ADJUST_OK; + if (g_str_has_prefix(split[i], "url=")) + lastfm_store("lastfm_tuned_to_url", g_strdup(split[i] + 4)); + } + } + g_string_erase(res, 0, -1); + g_strfreev(split); + return ret; +} + +gchar* parse(gchar* input_string,gchar* token) +{ + return g_strdup(g_strstr_len(input_string,20,"=")+1); } -gint lastfm_adjust(const gchar * uri) +gboolean parse_metadata(LastFM * handle,GString * metadata_strings) { - int status, i; - gchar tmp[4096], **split = NULL; - gboolean ret = FALSE; - GString *res = g_string_new(NULL); - gchar* session_id=mowgli_global_storage_get("lastfm_session_id"); - + int i; - if (!session_id) - return LASTFM_SESSION_MISSING; + if(metadata_strings == NULL) + return FALSE; + gchar **split = g_strsplit(metadata_strings->str, "\n", 20); + if(g_str_has_prefix(split[0],"streaming=false")) + return FALSE; + handle->lastfm_duration=0; + handle->lastfm_progress=0; + g_free(handle->lastfm_artist); + g_free(handle->lastfm_title); + g_free(handle->lastfm_album); + g_free(handle->lastfm_cover); + g_free(handle->lastfm_station_name); + for (i = 0; split && split[i]; i++) + { + if(g_str_has_prefix(split[i],"artist=")) + handle->lastfm_artist = parse(split[i],"artist="); + if(g_str_has_prefix(split[i],"track=" )) + handle->lastfm_title = parse(split[i],"track=" ); + if(g_str_has_prefix(split[i],"album=" )) + handle->lastfm_album = parse(split[i],"album=" ); + if(g_str_has_prefix(split[i],"albumcover_medium=")) + handle->lastfm_cover = parse(split[i],"albumcover_medium="); + if(g_str_has_prefix(split[i],"station=")) + handle->lastfm_station_name = parse(split[i],"station="); + if(g_str_has_prefix(split[i], "trackduration=")) + handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); + if (g_str_has_prefix(split[i], "trackprogress=")) + handle->lastfm_progress = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); + } #if DEBUG - g_print("Session ID: '%s'\n",session_id); -#endif - - snprintf(tmp, sizeof(tmp), LASTFM_ADJUST_URL, session_id, uri); - - status = lastfm_get_data_from_uri(tmp, res); - -#if DEBUG - g_print("Adjust received data:%s\n", res->str); + g_print("\nDuration:%d\n", handle->lastfm_duration); + if(handle->lastfm_station_name!=NULL) + g_print("Station Name: %s\n", handle->lastfm_station_name); #endif - if (status == CURLE_OK) - { - split = g_strsplit(res->str, "\n", 3); - - for (i = 0; split && split[i]; i++) - { - if (g_str_has_prefix(split[i], "response=OK")) - ret = LASTFM_ADJUST_OK; - if (g_str_has_prefix(split[i], "stationname=")) - { - mowgli_global_storage_put("lastfm_station_name", g_strdup(split[i] + 12)); -#if DEBUG - g_print ("Setting station name: '%s'\n", - (gchar*)mowgli_global_storage_get("lastfm_station_name")); -#endif - } - } - g_strfreev(split); - } - g_string_erase(res, 0, -1); - - return ret; + g_strfreev(split); + g_string_erase(metadata_strings, 0, -1); + return TRUE; } -void parse( gchar **split , gchar* field, gchar* data){ - - -} - -void parse_metadata(LastFM * handle,GString * metadata) +int fetch_metadata(LastFM * handle) { - gchar **split = g_strsplit(metadata->str, "\n", 20); - int i; - handle->lastfm_duration=0; - - for (i = 0; split && split[i]; i++) + gchar *uri=NULL; + gint status,res=METADATA_FETCH_FAILED; + handle->lastfm_session_id=mowgli_global_storage_get("lastfm_session_id"); + if (handle->lastfm_session_id == NULL) + return res; + uri=g_strdup_printf(LASTFM_METADATA_URL, handle->lastfm_session_id); + GString *fetched_metadata = g_string_new(NULL); + status = lastfm_get_data_from_uri(uri, fetched_metadata); + if (status == CURLE_OK) { - if (g_str_has_prefix(split[i], "artist=")) +#if DEBUG + g_print("Received metadata:'%s'\n", fetched_metadata->str); +#endif + if(parse_metadata( handle,fetched_metadata)) { - if (handle->lastfm_artist) - g_free(handle->lastfm_artist); - - handle->lastfm_artist = g_strdup(split[i] + 7); + res=METADATA_FETCH_SUCCEEDED; #if DEBUG - g_print("Artist: %s\n", handle->lastfm_artist); -#endif - } - if (g_str_has_prefix(split[i], "track=")) - { - if (handle->lastfm_title) - g_free(handle->lastfm_title); - - handle->lastfm_title = g_strdup(split[i] + 6); -#if DEBUG - g_print("Title: %s\n", handle->lastfm_title); + g_print("metadata was parsed ok\n"); #endif } - if (g_str_has_prefix(split[i], "album=")) - handle->lastfm_album = g_strdup(split[i] + 6); - - if (g_str_has_prefix(split[i], "albumcover_medium=")) - handle->lastfm_cover = g_strdup(split[i] + 18); - - if (g_str_has_prefix(split[i], "trackduration=")) - { - handle->lastfm_duration = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); -#if DEBUG - g_print("Duration:%d\n", handle->lastfm_duration); -#endif - } - if (g_str_has_prefix(split[i], "trackprogress=")) - handle->lastfm_progress = g_ascii_strtoull(g_strdup(split[i] + 14), NULL, 10); - - if (g_str_has_prefix(split[i], "station=")) - { - handle->lastfm_station_name = g_strdup(split[i] + 8); -#if DEBUG - g_print("Station Name: %s\n", handle->lastfm_station_name); -#endif - } } - - g_strfreev(split); -return; + return res; } - -gpointer lastfm_get_metadata(gpointer arg) -{ +gpointer lastfm_metadata_thread_func(gpointer arg) +{ gint err=0, - delay=-2, sleep_duration=1, + previous_track_duration=-1, count=0, - status; - gchar uri[4096]; - GString *res = g_string_new(NULL); - gboolean track_end=FALSE; + status=0; + gboolean track_end_expected=FALSE; + gchar* previous_track_title=NULL; LastFM *handle = (LastFM *)arg; - handle->lastfm_session_id =g_strdup(mowgli_global_storage_get("lastfm_session_id")); + // metadata is fetched 1 second after the stream is opened. + // if it's fetched ok i'm waiting for track_length-10 seconds + // then start polling for new metadata each 2 seconds, until + // the track gets changed from the previous iteration + do + { + sleep(1); + count++; + if(count%sleep_duration==0) + { + status=fetch_metadata(handle); + if(status==METADATA_FETCH_SUCCEEDED) + { + if(!track_end_expected) + { + sleep_duration=handle->lastfm_duration-10; + previous_track_duration=handle->lastfm_duration; + previous_track_title=g_strdup(handle->lastfm_title); + track_end_expected=TRUE; /*then the track_end will follow*/ + count=err=0; + } + else + { //two tracks are considered identical if they have the same length and the same title + if((handle->lastfm_duration == previous_track_duration)&& + g_str_has_prefix(handle->lastfm_title, previous_track_title)) + { + sleep_duration=2; + err++; + } + else //the tracks are different so i'm at the beginning of a new one + { + track_end_expected=FALSE; + g_free(previous_track_title); + } + } #if DEBUG - g_print("Session ID: %s\n", handle->lastfm_session_id); -#endif - - if (handle->lastfm_session_id == NULL) - return NULL; - snprintf(uri, sizeof(uri), LASTFM_METADATA_URL, handle->lastfm_session_id); -#if DEBUG - g_print("Download URI: %s\n", uri); + g_print("Current thread, ID = %p\n", (void *)g_thread_self()); #endif - - - while ( (handle!= NULL) && (err<5)) - //exit after 5 failed retries or after metadata_thread changes - { - count++; - if (count==sleep_duration) - { - handle->lastfm_duration = 0; - handle->lastfm_progress = 0; - status = lastfm_get_data_from_uri(uri, res); - if (status == CURLE_OK) - { -#if DEBUG - g_print("Successfully got Metadata\n"); - g_print("Received metadata:'%s'\nParsing...", res->str); -#endif - parse_metadata( handle,res); - } - g_string_erase(res, 0, -1); - - - if ((!track_end) && (handle->lastfm_duration >0)) - { //refresh metadata 2 sec before track's end and 2 sec after the next track starts - sleep_duration = handle->lastfm_duration - handle->lastfm_progress - delay -4; - track_end=TRUE; - err=delay=count=0; } else - { - err++; - track_end=FALSE; - sleep_duration=4; - count=0; - } - - if(handle->lastfm_duration ==0) //polling every 2 seconds until I get first data - { - sleep_duration=2; - count=0; - delay+=2; //time until I get first data - //starts from -2 to have uniform handling for in first iteration - //when calculating sleep_time - } - + err+=5; + } #if DEBUG - g_print("Sleeping for %d seconds\n", sleep_duration); + g_print("Thread_count: %d\n",thread_count); #endif - } - sleep(1); } + while (err<=7 && (g_thread_self()==metadata_thread )); #if DEBUG g_print("Exiting thread, ID = %p\n", (void *)g_thread_self()); #endif - handle->metadata_thread = NULL; - return NULL; + thread_count--; + return NULL; } VFSFile *lastfm_vfs_fopen_impl(const gchar * path, const gchar * mode) { -// static GThread *th; - VFSFile *file; - LastFM *handle; - file = g_new0(VFSFile, 1); - handle = g_new0(LastFM, 1); + VFSFile *file = g_new0(VFSFile, 1); + LastFM *handle = g_new0(LastFM, 1); + gchar* lastfm_uri=NULL; int login_count = 0; - while( ! mowgli_global_storage_get("lastfm_stream_uri")&&(login_count <= 3)) - { - printf("Login try count: %d\n", login_count++); - lastfm_login(); - if (!mowgli_global_storage_get("lastfm_stream_uri")) - sleep(5); - } - - if (!mowgli_global_storage_get("lastfm_stream_uri")) - return NULL; + while((login_count++ <= 3)&&(lastfm_login()!= LASTFM_LOGIN_OK)) + sleep(5); - handle->lastfm_session_id = g_strdup(mowgli_global_storage_get("lastfm_session_id")); - handle->lastfm_mp3_stream_url = g_strdup(mowgli_global_storage_get("lastfm_stream_uri")); - - if (!mowgli_global_storage_get("lastfm_station_name")) - { - if(lastfm_adjust(path)==LASTFM_ADJUST_OK) - { -#if DEBUG - g_print("Tuning was successfully completed into the channel\n"); -#endif - } - else - { -#if DEBUG - g_print("Cannot tune to given channel\n"); -#endif - } - } - - if ((handle->metadata_thread = g_thread_create(lastfm_get_metadata, handle, FALSE, NULL)) == NULL) - { -#if DEBUG - g_print("Error creating metadata thread!!!\n"); -#endif - return NULL; - } - else - { -#if DEBUG - g_print("A metadata thread has just been created, ID = %p \n", (void *)handle->metadata_thread); -#endif - } + handle->lastfm_session_id = mowgli_global_storage_get("lastfm_session_id"); + handle->lastfm_mp3_stream_url = mowgli_global_storage_get("lastfm_stream_uri"); + lastfm_uri=mowgli_global_storage_get("lastfm_tuned_to_url"); + //only tune in if the existinfg uri is NULL or != our new one(from path) + //adjust doesnt work as it should when having more than one lastfm stream opened at a time + if (!lastfm_uri || (!g_str_has_prefix(path,lastfm_uri)) ) + if(!lastfm_adjust(path)==LASTFM_ADJUST_OK) + return NULL; + metadata_thread = g_thread_create(lastfm_metadata_thread_func, handle, FALSE, NULL); + thread_count++; handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode); - file->handle = handle; - - return file; + file->handle = handle; + return file; } gint lastfm_vfs_fclose_impl(VFSFile * file) { - gint ret = 0; + gint ret = 0; - if (file == NULL) - return -1; + if (file == NULL) + return -1; LastFM *handle = file->handle; - ret = vfs_fclose(handle->proxy_fd); - if (!ret) - { - handle->proxy_fd = NULL; - handle->metadata_thread=NULL; - } + ret = vfs_fclose(handle->proxy_fd); + if (!ret) + handle->proxy_fd = NULL; g_free(handle); handle=NULL; - return ret; + return ret; } size_t lastfm_vfs_fread_impl(gpointer ptr, size_t size, size_t nmemb, VFSFile * file) { - LastFM *handle = file->handle; - size_t ret = vfs_fread(ptr, size, nmemb, handle->proxy_fd); - return ret; + LastFM *handle = file->handle; + size_t ret = vfs_fread(ptr, size, nmemb, handle->proxy_fd); + return ret; } size_t lastfm_vfs_fwrite_impl(gconstpointer ptr, size_t size, size_t nmemb, VFSFile * file) { - return -1; + return -1; } gint lastfm_vfs_getc_impl(VFSFile * stream) { - LastFM *handle = stream->handle; - return vfs_getc(handle->proxy_fd); + LastFM *handle = stream->handle; + return vfs_getc(handle->proxy_fd); } gint lastfm_vfs_ungetc_impl(gint c, VFSFile * stream) { - LastFM *handle = stream->handle; + LastFM *handle = stream->handle; - return vfs_ungetc(c, handle->proxy_fd); + return vfs_ungetc(c, handle->proxy_fd); } gint lastfm_vfs_fseek_impl(VFSFile * file, glong offset, gint whence) { - return -1; + return -1; } void lastfm_vfs_rewind_impl(VFSFile * file) { - return; + return; } glong lastfm_vfs_ftell_impl(VFSFile * file) { - LastFM *handle = file->handle; + LastFM *handle = file->handle; - return vfs_ftell(handle->proxy_fd); + return vfs_ftell(handle->proxy_fd); } gboolean lastfm_vfs_feof_impl(VFSFile * file) { - LastFM *handle = file->handle; + LastFM *handle = file->handle; - return vfs_feof(handle->proxy_fd); + return vfs_feof(handle->proxy_fd); } gint lastfm_vfs_truncate_impl(VFSFile * file, glong size) { - return -1; + return -1; } off_t lastfm_vfs_fsize_impl(VFSFile * file) { - return 0; + return 0; } gchar *lastfm_vfs_metadata_impl(VFSFile * file, const gchar * field) { - LastFM *handle = file->handle; - -#if 0 - g_print("Interesting metadata (want: %s):\n", field); - - if (handle->lastfm_station_name != NULL) - g_print("%s\n", handle->lastfm_station_name); - - if (handle->lastfm_artist != NULL) - g_print("%s\n", handle->lastfm_artist); - + LastFM *handle = file->handle; - if (handle->lastfm_title != NULL) - g_print("%s\n", handle->lastfm_title); - - g_print("%u\n\n", handle->lastfm_duration); -#endif + if (!g_ascii_strncasecmp(field, "stream-name", 11) && (handle->lastfm_station_name != NULL)) + return g_strdup(handle->lastfm_station_name); + if (!g_ascii_strncasecmp(field, "track-name", 10) && (handle->lastfm_title != NULL) && (handle->lastfm_artist != NULL)) + return g_strdup_printf("%s - %s", handle->lastfm_artist, handle->lastfm_title); - if (!g_ascii_strncasecmp(field, "stream-name", 11) && (handle->lastfm_station_name != NULL)) - return g_strdup(handle->lastfm_station_name); - if (!g_ascii_strncasecmp(field, "track-name", 10) && (handle->lastfm_title != NULL) && (handle->lastfm_artist != NULL)) - return g_strdup_printf("%s - %s", handle->lastfm_artist, handle->lastfm_title); - - return NULL; + return NULL; } VFSConstructor lastfm_const = { - "lastfm://", - lastfm_vfs_fopen_impl, - lastfm_vfs_fclose_impl, - lastfm_vfs_fread_impl, - lastfm_vfs_fwrite_impl, - lastfm_vfs_getc_impl, - lastfm_vfs_ungetc_impl, - lastfm_vfs_fseek_impl, - lastfm_vfs_rewind_impl, - lastfm_vfs_ftell_impl, - lastfm_vfs_feof_impl, - lastfm_vfs_truncate_impl, - lastfm_vfs_fsize_impl, - lastfm_vfs_metadata_impl + "lastfm://", + lastfm_vfs_fopen_impl, + lastfm_vfs_fclose_impl, + lastfm_vfs_fread_impl, + lastfm_vfs_fwrite_impl, + lastfm_vfs_getc_impl, + lastfm_vfs_ungetc_impl, + lastfm_vfs_fseek_impl, + lastfm_vfs_rewind_impl, + lastfm_vfs_ftell_impl, + lastfm_vfs_feof_impl, + lastfm_vfs_truncate_impl, + lastfm_vfs_fsize_impl, + lastfm_vfs_metadata_impl }; static void init(void) { - vfs_register_transport(&lastfm_const); + vfs_register_transport(&lastfm_const); } static void cleanup(void) { -mowgli_global_storage_free("lastfm_session_id"); -mowgli_global_storage_free("lastfm_stream_uri"); + mowgli_global_storage_free("lastfm_session_id"); + mowgli_global_storage_free("lastfm_stream_uri"); #if DEBUG -g_print ("Cleanup finished\n"); + g_print ("Cleanup finished\n"); #endif }
--- a/src/lastfm/lastfm.h Sun Jul 08 22:26:25 2007 +0300 +++ b/src/lastfm/lastfm.h Mon Jul 09 05:01:16 2007 +0300 @@ -9,9 +9,10 @@ #define LASTFM_LOGIN_ERROR 1 #define LASTFM_MISSING_LOGIN_DATA 2 #define LASTFM_SESSION_MISSING 4 -#define LASTFM_ADJUST_OK 0 - - +#define LASTFM_ADJUST_OK 8 +#define LASTFM_ADJUST_FAILED 16 +#define METADATA_FETCH_FAILED 64 +#define METADATA_FETCH_SUCCEEDED 128 typedef struct { VFSFile *proxy_fd; @@ -24,10 +25,11 @@ gchar *lastfm_cover; unsigned int lastfm_duration; unsigned int lastfm_progress; - GThread *metadata_thread; - int login_count; } LastFM; +GThread* metadata_thread=NULL; +gint thread_count=0; + VFSFile *lastfm_vfs_fopen_impl(const gchar * path, const gchar * mode); size_t lastfm_vfs_fread_impl(gpointer ptr, size_t size, size_t nmemb, VFSFile * file); @@ -54,9 +56,9 @@ gchar *lastfm_vfs_metadata_impl(VFSFile * file, const gchar * field); -static void parse_metadata(LastFM * handle,GString * res); +gboolean parse_metadata(LastFM * handle,GString * res); -static gpointer lastfm_get_metadata(gpointer arg); +static gpointer lastfm_metadata_thread_func(gpointer arg); static gboolean lastfm_login(void);