changeset 1200:0ae013f630fa

mowgli transition, and some fixes
author Cristi Magherusan <majeru@atheme-project.org>
date Sun, 01 Jul 2007 18:11:44 +0300
parents 2cb9c6b5cf4d
children 2ae8155baef1
files src/lastfm/lastfm.c src/lastfm/lastfm.h
diffstat 2 files changed, 247 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/src/lastfm/lastfm.c	Sun Jul 01 07:01:48 2007 -0500
+++ b/src/lastfm/lastfm.c	Sun Jul 01 18:11:44 2007 +0300
@@ -1,131 +1,200 @@
-/*  Audacious
- *  Copyright (c) 2007 Cristi Magherusan
- *
- *  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.
+/* Audacious lastfm transport plugin
+ * Copyright (c) 2007 Cristi Magherusan <majeru@gentoo.ro>
+ * All rights reserved.
  *
- *  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.
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 
+ *       Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ * 
+ *       Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ * 
+ *       Neither the name of the author nor the names of its contributors may be
+ *       used to endorse or promote products derived from this software without
+ *       specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <audacious/vfs.h>
 #include <audacious/plugin.h>
 #include <audacious/configdb.h>
-
 #include <libmowgli/mowgli_global_storage.h>
 #include <curl/curl.h>
 #include <glib.h>
 #include "lastfm.h"
 
-#define DEBUG 0
+#define DEBUG 1 
+
+size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata)
+{
+        GString *data = (GString *) udata;
+        g_string_append_len(data, ptr, nmemb);
+        return size * nmemb;
+}
 
-LastFM *LastFMGlobalData;
-/*this keeps the login data in a global place since 
- * we cannot login on every fopen call* if anyone 
- * has a better solution to this any hint is welcome */
-
-static size_t lastfm_store_res(void *ptr, size_t size, size_t nmemb, void *udata)
+gint lastfm_get_data_from_uri(gchar *url, GString * result)
 {
-	GString *data = (GString *) udata;
-	g_string_append_len(data, ptr, nmemb);
-	return size * nmemb;
+        CURL *curl = curl_easy_init();
+        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
+        curl_easy_setopt(curl, CURLOPT_USERAGENT, "mplayer");
+        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);
+        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, LASTFM_CURL_TIMEOUT);
+        curl_easy_setopt(curl, CURLOPT_URL, url);
+        curl_easy_setopt(curl, CURLOPT_WRITEDATA, result);
+        gint status = curl_easy_perform(curl);
+        curl_easy_cleanup(curl);
+        return status;
 }
 
-gint get_data_from_url(gchar buf[4096], GString * res)
+gchar* lastfm_get_login_uri()
 {
-	CURL *curl = curl_easy_init();
-	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
-	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);
-	curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, LASTFM_CURL_TIMEOUT);
-	curl_easy_setopt(curl, CURLOPT_URL, buf);
-	curl_easy_setopt(curl, CURLOPT_WRITEDATA, res);
-	gint status = curl_easy_perform(curl);
-	curl_easy_cleanup(curl);
-	return status;
+#if DEBUG
+        g_print("Getting login data from config\n");
+#endif
+
+        ConfigDb *cfgfile = NULL;
+        gchar   *buf=NULL,
+                *username = NULL, 
+                *password = NULL;
+        if ((cfgfile = bmp_cfg_db_open()) != NULL)
+        {
+                bmp_cfg_db_get_string(cfgfile, "audioscrobbler","username",
+                                &username);
+                bmp_cfg_db_get_string(cfgfile, "audioscrobbler","password",
+                                &password);
+                g_free(cfgfile);
+        }
+        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 {
+#if DEBUG
+                g_print("Couldn't find the login data. Use the scrobbler plugin to set it up.\n");
+#endif
+
+        return NULL;
+        }
+}
+
+void lastfm_store(gchar *var_name,gchar* var){
+if (mowgli_global_storage_get(var_name))
+                mowgli_global_storage_free(var_name);
+
+        mowgli_global_storage_put(var_name,var);
+#if DEBUG
+        g_print("Storing into '%s' the value '%s'\n",var_name,var);
+#endif
 }
 
-static gboolean lastfm_login(void)
+int lastfm_login(void)
 {
-	/*gets the session ID in lastfm_session_id and returns the URL to be played
-	 * read http://gabistapler.de/blog/index.php?/archives/268-Play-last.fm-streams-without-the-player.html for more info
-	 */
-	gint status, i;
-	gchar buf[4096], **split = NULL;
-	GString *res = g_string_new(NULL);
-	ConfigDb *cfgfile = NULL;
-	char *username = NULL, *password = NULL;
-	if ((cfgfile = bmp_cfg_db_open()) != NULL)
-	{
-		bmp_cfg_db_get_string(cfgfile, "audioscrobbler", "username", &username);
-		bmp_cfg_db_get_string(cfgfile, "audioscrobbler", "password", &password);
-		g_free(cfgfile);
-	}
-	if (username != NULL && password != NULL)
-	{
-		snprintf(buf, sizeof(buf), LASTFM_HANDSHAKE_URL, username, password);
-		g_free(password);
-		g_free(username);
-	}
-	else
-		return FALSE;
+        /*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,
+                **split = NULL;
+        GString *res = g_string_new(NULL);
+g_print("Logging in\n");
+        login_uri=lastfm_get_login_uri();
+        if(login_uri==NULL){
+                g_free(login_uri);
+                return LASTFM_MISSING_LOGIN_DATA;
+                }
+        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
 
-	status = get_data_from_url(buf, res);
+        if (status == CURLE_OK)
+        {
+                split = g_strsplit(res->str, "\n", 7);
 
-#ifdef DEBUG
-	g_print("URL:%s\n", buf);
-	g_print("Downloaded data:%s\n", res->str);
+                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
-	if (status == CURLE_OK)
-	{
-		split = g_strsplit(res->str, "\n", 7);
+                        }
+                        else if (g_str_has_prefix(split[i], "stream_url="))
+                                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);
 
-		for (i = 0; split && split[i]; i++)
-		{
-			if (g_str_has_prefix(split[i], "session="))
-				LastFMGlobalData->lastfm_session_id = g_strndup(split[i] + 8, 32);
-			else if (g_str_has_prefix(split[i], "stream_url="))
-				LastFMGlobalData->lastfm_mp3_stream_url = g_strdup(split[i] + 11);
-		}
-	}
-	else
-		return FALSE;
-
-	g_strfreev(split);
-	g_string_erase(res, 0, -1);
-
-	if (mowgli_global_storage_get("lastfm_session_id"))
-		mowgli_global_storage_free("lastfm_session_id");
-
-	mowgli_global_storage_put("lastfm_session_id", LastFMGlobalData->lastfm_session_id);
-
-	return (gboolean) TRUE;
+#if DEBUG
+        g_print("Login finished succesfully\n");
+#endif
+        g_strfreev(split);
+        g_string_erase(res, 0, -1);
+        g_free(login_uri);
+ return LASTFM_LOGIN_OK ;
 }
 
-static gboolean lastfm_adjust(const gchar * url)
+gint lastfm_adjust(const gchar * uri)
 {
-	int status, i;
-	gchar tmp[4096], **split = NULL;
-	gboolean ret = FALSE;
-	GString *res = g_string_new(NULL);
+        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");
+
 
-	if (LastFMGlobalData->lastfm_session_id == NULL)
-		return FALSE;
-	snprintf(tmp, sizeof(tmp), LASTFM_ADJUST_URL, LastFMGlobalData->lastfm_session_id, url);
+        if (!session_id)
+		return LASTFM_SESSION_MISSING;
+#if DEBUG
+        g_print("Session ID: '%s'\n",session_id);
+#endif
 
-	status = get_data_from_url(tmp, res);
+        snprintf(tmp, sizeof(tmp), LASTFM_ADJUST_URL, session_id, uri);
 
-#ifdef DEBUG
+	status = lastfm_get_data_from_uri(tmp, res);
+
+#if DEBUG
 	g_print("Adjust received data:%s\n", res->str);
 #endif
 	if (status == CURLE_OK)
@@ -135,54 +204,67 @@
 		for (i = 0; split && split[i]; i++)
 		{
 			if (g_str_has_prefix(split[i], "response=OK"))
-				ret = TRUE;
+				ret = LASTFM_ADJUST_OK;
 			if (g_str_has_prefix(split[i], "stationname="))
 			{
-				LastFMGlobalData->lastfm_station_name = g_strdup(split[i] + 12);
-#ifdef DEBUG
-				g_print("StationnName:%s\n", LastFMGlobalData->lastfm_station_name);
+				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;
 }
 
+void parse( gchar **split , gchar* field, gchar* data){
 
-static void parse_metadata(LastFM * handle,GString * res)
+
+}
+
+void parse_metadata(LastFM * handle,GString * metadata)
 {
-        gchar **split = g_strsplit(res->str, "\n", 20);
+        gchar **split = g_strsplit(metadata->str, "\n", 20);
         int i;
+        handle->lastfm_duration=0;
+        
         for (i = 0; split && split[i]; i++)
         {
                 if (g_str_has_prefix(split[i], "artist="))
                 {
-                        if (handle->lastfm_artist) g_free(handle->lastfm_artist);
+                        if (handle->lastfm_artist) 
+                                g_free(handle->lastfm_artist);
+
                         handle->lastfm_artist = g_strdup(split[i] + 7);
-#ifdef DEBUG
+#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);
+                        if (handle->lastfm_title) 
+                                g_free(handle->lastfm_title);
+
                         handle->lastfm_title = g_strdup(split[i] + 6);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Title: %s\n", handle->lastfm_title);
 #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);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Duration:%d\n", handle->lastfm_duration);
 #endif
                 }
@@ -192,7 +274,7 @@
                 if (g_str_has_prefix(split[i], "station="))
                 {
                         handle->lastfm_station_name = g_strdup(split[i] + 8);
-#ifdef DEBUG
+#if DEBUG
                         g_print("Station Name: %s\n", handle->lastfm_station_name);
 #endif
                 }
@@ -203,22 +285,31 @@
 }
 
 
-static gpointer lastfm_get_metadata(gpointer arg)
-{
-        int err=0,delay=-2;
-
-        int sleep_duration,count=0;
-        gint status;
-        gchar tmp[4096];
+gpointer lastfm_get_metadata(gpointer arg)
+{     
+        gint    err=0,
+                delay=-2,
+                sleep_duration=1,
+                count=0,
+                status;
+        gchar uri[4096];
         GString *res = g_string_new(NULL);
         gboolean track_end=FALSE;
         LastFM *handle = (LastFM *)arg;
+        handle->lastfm_session_id =g_strdup(mowgli_global_storage_get("lastfm_session_id"));
+#if DEBUG
+                        g_print("Session ID: %s\n", handle->lastfm_session_id);
+#endif
 
         if (handle->lastfm_session_id == NULL)
                 return NULL;
-        snprintf(tmp, sizeof(tmp), LASTFM_METADATA_URL, handle->lastfm_session_id);
+        snprintf(uri, sizeof(uri), LASTFM_METADATA_URL, handle->lastfm_session_id);
+#if DEBUG
+                        g_print("Download URI: %s\n", uri);
+#endif
 
-        while ( (handle!= NULL) && (handle->metadata_thread == g_thread_self ()) && (err<5))
+
+        while ( (handle!= NULL)  && (err<5))
                 //exit after 5 failed retries or after metadata_thread changes
         {       
                 count++;
@@ -226,14 +317,12 @@
                 {
                         handle->lastfm_duration = 0;
                         handle->lastfm_progress = 0;
-                        status = get_data_from_url(tmp, res);
-#if 0
-                        g_print("Received metadata:%s\n", res->str);
-#endif
+                        status = lastfm_get_data_from_uri(uri, res);
                         if (status == CURLE_OK)
                         {
-#ifdef DEBUG
-                                g_print("Got Metadata\n");
+#if DEBUG
+                                g_print("Successfully got Metadata\n");
+                                g_print("Received metadata:'%s'\nParsing...", res->str);
 #endif
                                 parse_metadata( handle,res);
                         }
@@ -263,14 +352,14 @@
                                                 //when calculating sleep_time
                         }
 
-#ifdef DEBUG
+#if DEBUG
 		g_print("Sleeping for %d seconds\n", sleep_duration);
 #endif
 	        }
                 sleep(1);
         }
 
-#ifdef DEBUG
+#if DEBUG
         g_print("Exiting thread, ID = %p\n", (void *)g_thread_self());
 #endif
         handle->metadata_thread = NULL;
@@ -284,29 +373,32 @@
 	LastFM *handle;
 	file = g_new0(VFSFile, 1);
 	handle = g_new0(LastFM, 1);
-        while ((LastFMGlobalData->lastfm_mp3_stream_url == NULL) && (LastFMGlobalData->login_count <= 3))
+        int login_count = 0;
+        while( ! mowgli_global_storage_get("lastfm_stream_uri")&&(login_count <= 3))
 	{
-		printf("Login try count: %d\n", LastFMGlobalData->login_count++);
+		printf("Login try count: %d\n", login_count++);
 		lastfm_login();
-		if (LastFMGlobalData->lastfm_mp3_stream_url == NULL)
+		if (!mowgli_global_storage_get("lastfm_stream_uri"))
 			sleep(5);
 	}
 
-	if (LastFMGlobalData->lastfm_mp3_stream_url == NULL)
+        if (!mowgli_global_storage_get("lastfm_stream_uri"))
 		return NULL;
 
-
-	if (LastFMGlobalData->lastfm_station_name==NULL)
+	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))
+                        if(lastfm_adjust(path)==LASTFM_ADJUST_OK)
                         {	                                
-#ifdef DEBUG
+#if DEBUG
         		g_print("Tuning was successfully completed into the channel\n");
 #endif
 		        }
                         else
                         {
-#ifdef DEBUG            
+#if DEBUG            
         		g_print("Cannot tune to given channel\n");
 #endif
                         }
@@ -314,21 +406,18 @@
         
         if ((handle->metadata_thread = g_thread_create(lastfm_get_metadata, handle, FALSE, NULL)) == NULL)
 		            {
-#ifdef DEBUG
-			            g_print("Error creating metadata thread!!!\n");
+#if DEBUG
+                                        g_print("Error creating metadata thread!!!\n");
 #endif
 			             return NULL;
 		            }
 		        else
                             {
-#ifdef DEBUG
-                                g_print("A metadata thread has just been created, ID = %p \n", (void *)handle->metadata_thread);
+#if DEBUG
+                                        g_print("A metadata thread has just been created, ID = %p \n", (void *)handle->metadata_thread);
 #endif
                             }
 
-	handle->lastfm_mp3_stream_url = g_strdup(LastFMGlobalData->lastfm_mp3_stream_url);
-	handle->lastfm_session_id = g_strdup(LastFMGlobalData->lastfm_session_id);
-	handle->lastfm_station_name = g_strdup(LastFMGlobalData->lastfm_station_name);
         handle->proxy_fd = vfs_fopen(handle->lastfm_mp3_stream_url, mode);
 	file->handle = handle;
 
@@ -459,13 +548,17 @@
 
 static void init(void)
 {       
-	LastFMGlobalData = g_new0(LastFM, 1);
 	vfs_register_transport(&lastfm_const);
 }
 
 static void cleanup(void)
 {
-	g_free(LastFMGlobalData);
+
+mowgli_global_storage_free("lastfm_session_id");
+mowgli_global_storage_free("lastfm_stream_uri");
+#if DEBUG
+g_print ("Cleanup finished\n");
+#endif
 }
 
 DECLARE_PLUGIN(lastfm, init, cleanup, NULL, NULL, NULL, NULL, NULL)
--- a/src/lastfm/lastfm.h	Sun Jul 01 07:01:48 2007 -0500
+++ b/src/lastfm/lastfm.h	Sun Jul 01 18:11:44 2007 +0300
@@ -5,6 +5,13 @@
 #define LASTFM_CURL_TIMEOUT 10
 
 
+#define LASTFM_LOGIN_OK                 0
+#define LASTFM_LOGIN_ERROR              1
+#define LASTFM_MISSING_LOGIN_DATA       2
+#define LASTFM_SESSION_MISSING          4
+#define LASTFM_ADJUST_OK                0
+
+
 typedef struct
 {
 	VFSFile *proxy_fd;