Code

added a plugin system for lyrics sources
authorAndreas Obergrusberger <tradiaz@yahoo.de>
Wed, 3 Jan 2007 20:12:16 +0000 (20:12 +0000)
committerAndreas Obergrusberger <tradiaz@yahoo.de>
Wed, 3 Jan 2007 20:12:16 +0000 (20:12 +0000)
git-svn-id: https://svn.musicpd.org/ncmpc/branches/tradiaz@5217 09075e82-0dd4-0310-85a5-a0d7c8717e4f

19 files changed:
ChangeLog
INSTALL
Makefile.am
configure.ac
plugins/Makefile.am [new file with mode: 0644]
plugins/hd/Makefile.am [new file with mode: 0644]
plugins/hd/lyrics_hd.c [new file with mode: 0644]
plugins/leoslyrics/Makefile.am [new file with mode: 0644]
plugins/leoslyrics/easy_download.c [new file with mode: 0644]
plugins/leoslyrics/easy_download.h [new file with mode: 0644]
plugins/leoslyrics/lyrics_leoslyrics.c [new file with mode: 0644]
src/Makefile.am
src/list_window.h
src/lyrics_hd.c [new file with mode: 0644]
src/lyrics_leoslyrics.c [new file with mode: 0644]
src/main.c
src/screen_lyrics.c
src/src_lyrics.c [new file with mode: 0644]
src/src_lyrics.h [new file with mode: 0644]

index 6fb81d02282bfc812d6112fc293d8f5ae5f5a638..6ae9dbf232b126219bf13e46ed8dc22e961a7c7c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-01-03 Andreas Obergrusberger <tradiaz@yahoo.d>
+  * added plugin support for lyrics
+  * changed the build system heavily, look at INSTALL
+  * build system now GNU standardized
+
 2006-11-11 Andreas Obergrusberger <tradiaz@yahoo.de>
   * fixed advanced search
   * go root/parent also for artist screen
diff --git a/INSTALL b/INSTALL
index 56b077d6a0b8773b014bd4381cc09abb17fff351..38893ada67d2919fb3c16aa98a06e64d9fc42351 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -234,3 +234,12 @@ configuration-related scripts to be executed by `/bin/bash'.
 `configure' also accepts some other, not widely useful, options.  Run
 `configure --help' for more details.
 
+Plugins
+=======
+
+To build the plugins type 'make' in the plugins folder
+
+Install the mby typing 'make install', deinstall them with 'make uninstall'
+
+This way can also install/build a certain plugin by changing to its folder in the plugins folder
+
index 574d8a294ae5cdc18c3208ed38b0fc4ec987e271..9a01c2aab65a27861c2b89a8730a5d426a1000f9 100644 (file)
@@ -3,7 +3,7 @@ SUBDIRS = \
   doc\
   po
 
-AUTOMAKE_OPTIONS =   foreign 1.6
+AUTOMAKE_OPTIONS =   gnu 1.6
 
 # $Id$
 
index 1baa12f1743b5fe4143acff87cbb189657e1c703..987c4d28bbc53b9f89e5ddddd4b4299365511eda 100644 (file)
@@ -11,6 +11,7 @@ dnl Check for programs
 AC_PROG_CC
 AC_PROG_INSTALL
 dnl AC_PROG_LIBTOOL
+AC_PROG_LIBTOOL
 
 dnl =======================================================
 dnl initialize variables
@@ -149,6 +150,14 @@ PKG_CHECK_MODULES([GTHREAD],
 AC_SUBST(GTHREAD_LIBS)
 AC_SUBST(GTHREAD_CFLAGS)
                  
+dnl check for gmodule
+PKG_CHECK_MODULES([GMODULE], 
+                 [gmodule-2.0],
+                 [gmodule=yes],
+                 [AC_MSG_WARN([gmodule-2.0 >= 0.20 is required the plugin system])])
+AC_SUBST(GMODULE_LIBS)
+AC_SUBST(GMODULE_CFLAGS)
+
 dnl check for libcurl
 PKG_CHECK_MODULES([libcurl], 
                  [libcurl],
@@ -214,7 +223,7 @@ dnl Optional screen - help screen
 #fi
 
 dnl Optional screen - browse screen
-#AC_MSG_CHECKING([whether to include the browse screen])
+#AC_MSG_CHECKING([whether to include the browse screen])r
 #AC_ARG_ENABLE([browse-screen], 
 #              AC_HELP_STRING([--enable-browse-screen],
 #                           [Enable the browse screen @<:@default=yes@:>@]),
@@ -240,6 +249,23 @@ if test "x$getmouse" = "xyes" ; then
                [])
 fi
 
+dnl Plugin loading for lyrics sources
+AC_MSG_CHECKING([whether to include the plugin infrastructure])
+AC_ARG_ENABLE([plugin-support],
+            AC_HELP_STRING([--enable-plugin-support],
+                           [Enable loading lyrics plugins @<:@default=yes@:>@]),
+            [plugin_support="$enableval"],
+            [plugin_support=yes])
+if test "x$plugin_support" != "xyes" ; then
+    AC_DEFINE(DISABLE_PLUGIN_SYSTEM, 1, [Disable plugin system])
+fi
+
+if test "x$gmodule" != "xyes" ; then
+    AC_DEFINE(DISABLE_PLUGIN_SYSTEM, 1, [Disable plugin system])
+    plugin_support=no
+fi
+AC_MSG_RESULT([$plugin_support])
+
 dnl Optional screen - artist
 AC_MSG_CHECKING([whether to include the artist screen])
 AC_ARG_ENABLE([artist-screen], 
@@ -294,29 +320,100 @@ AC_ARG_ENABLE([lyrics-screen],
               AC_HELP_STRING([--enable-lyrics-screen],
                             [Enable lyrics screen @<:@default=no@:>@]),
              [lyrics_screen="$enableval"],
-             [lyrics_screen=no])       
+             [lyrics_screen=yes])      
 if test "x$lyrics_screen" != "xyes" ; then
    AC_DEFINE(DISABLE_LYRICS_SCREEN, 1, [Disable lyrics screen])
    lyrics_screen=no
 fi
 #lyrics_screen=yes
-if test "$libcurl" != "yes" ; then
- AC_MSG_RESULT([$lyrics_screen])  
+#if test "x$libcurl" != "xyes" ; then
+# AC_MSG_RESULT([$lyrics_screen])  
  # AC_DEFINE(DISABLE_LYRICS_SCREEN, 1, [Disable lyrics screen])
   # lyrics_screen=no
-fi
-if test "$gthread" != "yes" ; then
-   AC_DEFINE(DISABLE_LYRICS_SCREEN, 1, [Disable lyrics screen])
-   lyrics_screen=no
-AC_MSG_RESULT([$lyrics_screen]) 
-fi
-if test "$have_expat" != "yes" ; then
+#fi
+if test "x$gthread" != "xyes" ; then
    AC_DEFINE(DISABLE_LYRICS_SCREEN, 1, [Disable lyrics screen])
    lyrics_screen=no
 fi
+#if test "x$have_expat" != "xyes" ; then
+#   AC_DEFINE(DISABLE_LYRICS_SCREEN, 1, [Disable lyrics screen])
+#   lyrics_screen=no
+#fi
 
 AC_MSG_RESULT([$lyrics_screen])
 
+dnl hd
+AC_MSG_CHECKING([whether to build with .lyrics support])
+AC_ARG_WITH([lyrics-hd],
+           AC_HELP_STRING([[--with-lyrics-leoslyrics[=plugin/fixed/no]]],
+                      [enable leoslyrics lyrics source @<:@default=plugin@:>@]),
+       [hd=$withval],
+       [hd=plugin])
+
+if test "x$plugin_support" != "xyes" ; then
+    if test "x$hd" == "xplugin" ; then
+       hd=fixed
+       AC_MSG_NOTICE([Enable lyrics plugin support to compile as a plugin!])
+   fi
+fi     
+AC_MSG_RESULT([$hd])
+if test "x$hd" == "xfixed"; then
+    AC_DEFINE_UNQUOTED([ENABLE_LYRSRC_HD], 1,
+                  [~/.lyrics inclusion])
+fi
+if test "x$hd" == "xplugin" ; then
+    src_lyr_plugins="${src_lyr_plugins}hd "
+fi
+AM_CONDITIONAL(HD_FIXED, test x$hd = xfixed)
+
+dnl leoslyrics
+AC_MSG_CHECKING([whether to build with leoslyrics])
+AC_ARG_WITH([lyrics-leoslyrics],
+           AC_HELP_STRING([[--with-lyrics-leoslyrics[=plugin/fixed/no]]],
+                      [enable leoslyrics lyrics source @<:@default=plugin@:>@]),
+       [leoslyrics=$withval],
+       [leoslyrics=plugin])
+
+if test "x$plugin_support" != "xyes" ; then
+    if test "x$leoslyrics" == "xplugin" ; then
+       leoslyrics=fixed
+       AC_MSG_NOTICE([Enable lyrics plugin support to compile as a plugin!])
+   fi
+fi     
+
+if test "x$have_expat" != "xyes" ; then
+    leoslyrics=no
+fi
+if test "x$libcurl" != "xyes" ; then
+    leoslyrics=no
+fi
+
+if test "x$leoslyrics" == "xplugin" ; then
+    src_lyr_plugins="${src_lyr_plugins}leoslyrics "
+fi
+AC_MSG_RESULT([$leoslyrics])
+
+if test "x$leoslyrics" == "xfixed" ; then 
+    AC_DEFINE_UNQUOTED([ENABLE_LYRSRC_LEOSLYRICS], 1,
+                  [Leoslyrics inclusion])
+fi
+
+#if test "x$leoslyrics" == "xfixed" ; then
+ #   src_lyr_fixed="${src_lyr_fixed}../plugins/leoslyrics/lyrics_leoslyrics.c "
+ #   leoslyrics_fixed=yes
+#fi
+AM_CONDITIONAL(LEOSLYRICS_FIXED, test x$leoslyrics = xfixed)
+
+dnl plugins directory
+AC_ARG_WITH([plugin-dir],
+           AC_HELP_STRING([[--with-plugin-dir[=DIRECTORY]]],
+                      [Directory where plugins are stored @<:@default=/usr/share/ncmpc/modules@:>@]),
+       [plugindir=$withval],
+       [plugindir="/usr/share/ncmpc/modules"])
+AC_DEFINE_UNQUOTED([PLUGIN_DIR_SYSTEM], ["$plugindir"],
+                  [Directory to search for plugins])
+
+AC_SUBST(plugindir)
 dnl Default host
 AC_MSG_CHECKING([for default MPD host])
 AC_ARG_WITH([default-host],
@@ -347,6 +444,9 @@ AC_ARG_WITH([default-timedisplay_type],
             [DEFAULT_TIMEDISPLAY_TYPE="elapsed"])
 AC_MSG_RESULT([$DEFAULT_TIMEDISPLAY_TYPE])
 AC_DEFINE_UNQUOTED([DEFAULT_TIMEDISPLAY_TYPE], ["$DEFAULT_TIMEDISPLAY_TYPE"], [Default way to display time, either 'elapsed' or 'remaining'])
-
-AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile po/Makefile.in])
+AC_SUBST(src_lyr_plugins)
+AC_SUBST(src_lyr_fixed)
+AC_CONFIG_FILES([Makefile src/Makefile plugins/Makefile doc/Makefile po/Makefile 
+               plugins/hd/Makefile 
+               plugins/leoslyrics/Makefile])
 AC_OUTPUT
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644 (file)
index 0000000..9bb784f
--- /dev/null
@@ -0,0 +1,6 @@
+SUBDIRS = \
+         ${src_lyr_plugins}
+
+AUTOMAKE_OPTIONS =   foreign 1.6
+
+
diff --git a/plugins/hd/Makefile.am b/plugins/hd/Makefile.am
new file mode 100644 (file)
index 0000000..f4d4608
--- /dev/null
@@ -0,0 +1,40 @@
+AM_CPPFLAGS =\
+  $(GLIB_CFLAGS)\
+  $(GTHREAD_CFLAGS)\
+  $(libcurl_CFLAGS)\
+  -I../../src
+
+###----
+
+plugin_headers =\
+                ../src_lyrics.h\
+                ../screen_lyrics.h\
+                ../easy_download.h\
+                ../options.h
+
+###-----
+
+ncmpc_modulesdir = @plugindir@
+
+ncmpc_modules_LTLIBRARIES = libhd.la 
+
+### libhd
+
+libhd_la_LIBADD =\
+  $(GLIB_LIBS)\
+  $(libcurl_LIBS)
+
+libhd_la_headers =\
+                         $(plugins_headers)
+
+libhd_la_SOURCES =\
+                         lyrics_hd.c\
+                         $(libhd_la_headers)
+install:
+       @$(MAKE)
+       mkdir -p ${ncmpc_modulesdir}
+       if test -f .libs/libhd.so; then cp .libs/libhd.so ${ncmpc_modulesdir}/lyrics_hd.so; fi
+
+uninstall:
+       @$(MAKE)
+       rm -f ${ncmpc_modulesdir}/lyrics_hd.so
diff --git a/plugins/hd/lyrics_hd.c b/plugins/hd/lyrics_hd.c
new file mode 100644 (file)
index 0000000..a90ee9d
--- /dev/null
@@ -0,0 +1,52 @@
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "src_lyrics.h"
+
+char *check_lyr_hd(char *artist, char *title, int how)
+{ //checking whether for lyrics file existence and proper access
+        static char path[1024];
+        snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", 
+                        getenv("HOME"), artist, title);
+    
+    if(g_access(path, how) != 0) return NULL;
+                 
+        return path;
+}              
+
+
+int get_lyr_hd(char *artist, char *title)
+{
+        char *path = check_lyr_hd(artist, title, R_OK);
+        if(path == NULL) return -1;
+        
+        FILE *lyr_file;        
+        lyr_file = fopen(path, "r");
+        if(lyr_file == NULL) return -1;
+        
+        char *buf = NULL;
+        char **line = &buf;
+        size_t n = 0;
+        
+        while(1)
+        {
+         n = getline(line, &n, lyr_file); 
+         if( n < 1 || *line == NULL || feof(lyr_file) != 0 ) return 0;
+         add_text_line(&lyr_text, *line, n);
+         free(*line);
+         *line = NULL; n = 0;
+         }
+        
+        return 0;
+}      
+
+int register_me (src_lyr *source_descriptor)
+{ 
+  source_descriptor->check_lyr = check_lyr_hd;
+  source_descriptor->get_lyr = get_lyr_hd;
+  
+  source_descriptor->name = "Harddisk";
+  source_descriptor->description = "";
+}
diff --git a/plugins/leoslyrics/Makefile.am b/plugins/leoslyrics/Makefile.am
new file mode 100644 (file)
index 0000000..4eb76f3
--- /dev/null
@@ -0,0 +1,43 @@
+AM_CPPFLAGS =\
+  $(GLIB_CFLAGS)\
+  $(GTHREAD_CFLAGS)\
+  $(libcurl_CFLAGS)\
+  -I../../src
+
+###----
+
+plugin_headers =\
+                ../src_lyrics.h\
+                ../screen_lyrics.h\
+                ../easy_download.h\
+                ../options.h
+
+###-----
+
+ncmpc_modulesdir = @plugindir@
+
+ncmpc_modules_LTLIBRARIES = libleoslyrics.la 
+
+### libleoslyrics
+
+libleoslyrics_la_LIBADD =\
+  $(GLIB_LIBS)\
+  $(libcurl_LIBS)
+
+libleoslyrics_la_headers =\
+                         easy_download.h\
+                         $(plugins_headers)
+
+libleoslyrics_la_SOURCES =\
+                         easy_download.c\
+                         lyrics_leoslyrics.c\
+                         $(libleoslyrics_la_headers)
+
+install:
+       @$(MAKE)
+       mkdir -p ${DESTDIR}${libdir}
+       if test -f .libs/libleoslyrics.so; then cp .libs/libleoslyrics.so ${ncmpc_modulesdir}/lyrics_leoslyrics.so; fi
+
+uninstall:
+       @$(MAKE)
+       rm -f ${ncmpc_modulesdir}/lyrics_leoslyrics.so
diff --git a/plugins/leoslyrics/easy_download.c b/plugins/leoslyrics/easy_download.c
new file mode 100644 (file)
index 0000000..83616cf
--- /dev/null
@@ -0,0 +1,89 @@
+/*     by Qball
+ *  
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include "ncmpc.h"
+
+#ifdef ENABLE_LYRICS_SCREEN
+
+#include <curl/curl.h>
+#include "easy_download.h"
+
+static size_t write_data(void *buffer, size_t size,
+       size_t nmemb, easy_download_struct *dld)
+{
+       if(dld->data == NULL)
+       {
+               dld->size = 0;
+       }
+       dld->data = g_realloc(dld->data,(gulong)(size*nmemb+dld->size));
+
+       memset(&(dld->data)[dld->size], '\0', (size*nmemb));
+       memcpy(&(dld->data)[dld->size], buffer, size*nmemb);
+
+       dld->size += size*nmemb;
+       if(dld->size >= dld->max_size && dld->max_size > 0)
+       {
+               return 0;
+       }
+       return size*nmemb;
+}
+
+int easy_download(char *url,easy_download_struct *dld,
+               curl_progress_callback cb)
+{
+       CURL *curl = NULL;
+       int res;
+       if(!dld) return 0;
+       easy_download_clean(dld);
+       /* initialize curl */
+       curl = curl_easy_init();
+       if(!curl) return 0;
+       /* set uri */
+       curl_easy_setopt(curl, CURLOPT_URL, url);
+       /* set callback data */
+       curl_easy_setopt(curl, CURLOPT_WRITEDATA, dld);
+       /* set callback function */
+       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
+       curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
+       curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cb);
+       /* run */
+       res = curl_easy_perform(curl);
+       /* cleanup */
+       curl_easy_cleanup(curl);
+       if(!res)
+       {
+               return 1;
+       }
+       if(dld->data) g_free(dld->data);
+       return 0;
+}
+
+void easy_download_clean(easy_download_struct *dld)
+{
+       if(dld->data)g_free(dld->data);
+       dld->data = NULL;
+       dld->size = 0;
+       dld->max_size = -1;
+}
+
+#endif
diff --git a/plugins/leoslyrics/easy_download.h b/plugins/leoslyrics/easy_download.h
new file mode 100644 (file)
index 0000000..92dc22e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ *  by Qball
+ *
+ *  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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <curl/curl.h>
+
+typedef struct _easy_download_struct{
+       char *data;
+       int size;
+       int max_size;
+
+}easy_download_struct;
+
+
+int easy_download(char *url,easy_download_struct *dld, 
+               curl_progress_callback cb);
+void easy_download_clean(easy_download_struct *dld);
diff --git a/plugins/leoslyrics/lyrics_leoslyrics.c b/plugins/leoslyrics/lyrics_leoslyrics.c
new file mode 100644 (file)
index 0000000..47aabe1
--- /dev/null
@@ -0,0 +1,158 @@
+#include "src_lyrics.h"
+#include "easy_download.h"
+#include <expat.h>
+#include <string.h>
+#include "options.h"
+
+#define LEOSLYRICS_SEARCH_URL "http://api.leoslyrics.com/api_search.php?auth=ncmpc&artist=%s&songtitle=%s"
+#define LEOSLYRICS_CONTENT_URL "http://api.leoslyrics.com/api_lyrics.php?auth=ncmpc&hid=%s"
+#define CREDITS "Lyrics provided by www.LeosLyrics.com"
+
+char *hid;
+XML_Parser parser, contentp;
+
+int check_dl_progress(void *clientp, double dltotal, double dlnow,
+                        double ultotal, double ulnow)
+{
+        if(g_timer_elapsed(dltime, NULL) >= options.lyrics_timeout || lock == 4)
+        {      
+                formed_text_init(&lyr_text);
+                return -1;
+        }
+
+        return 0;
+}      
+
+
+
+static void check_content(void *data, const char *name, const char **atts)
+{ 
+        if(strstr(name, "text") != NULL)
+        {
+
+                result |= 16;
+        }
+}
+        
+
+static void check_search_response(void *data, const char *name,
+                 const char **atts)
+{
+        if(strstr(name, "response") != NULL)
+        {
+        result |=2;
+        return;
+        }  
+            
+        if(result & 4)
+        {
+                if(strstr(name, "result") != NULL)
+                {
+                        if(strstr(atts[2], "hid") != NULL)
+                        {
+                                hid = atts[3];
+                        }
+        
+                        if(strstr(atts[2], "exactMatch") != NULL)
+                        {
+                                result |= 8;
+                        }                      
+                }
+        }
+                        
+}
+
+static void end_tag(void *data, const char *name)
+{
+  //hmmmmmm            
+}
+
+  static void check_search_success(void *userData, const XML_Char *s, int len)
+    {
+        if(result & 2) //lets first check whether we're right
+        {              //we don't really want to search in the wrong string
+                if(strstr((char*) s, "SUCCESS"))
+                {
+                result |=4;
+                }
+        }      
+    }
+
+static void fetch_text(void *userData, const XML_Char *s, int len) 
+{
+        if(result & 16)
+        {
+                add_text_line(&lyr_text, s, len); 
+        }
+}
+
+/*int deregister_lyr_leoslyrics ()
+{
+  
+}*/
+
+int check_lyr_leoslyrics(char *artist, char *title, char *url)
+{
+        char url_avail[256];
+
+        //this replacess the whitespaces with '+'
+        g_strdelimit(artist, " ", '+');
+        g_strdelimit(title, " ", '+');
+        
+        //we insert the artist and the title into the url              
+        snprintf(url_avail, 512, LEOSLYRICS_SEARCH_URL, artist, title);
+
+        //download that xml!
+        easy_download_struct lyr_avail = {NULL, 0,-1}; 
+        
+        g_timer_start(dltime);
+        if(!easy_download(url_avail, &lyr_avail, check_dl_progress)) return -1;
+        g_timer_stop(dltime);
+
+        //we gotta parse that stuff with expat
+        parser = XML_ParserCreate(NULL);
+        XML_SetUserData(parser, NULL);
+        
+        XML_SetElementHandler(parser, check_search_response, end_tag);
+        XML_SetCharacterDataHandler(parser, check_search_success);
+        XML_Parse(parser, lyr_avail.data, strlen(lyr_avail.data), 0);  
+        XML_ParserFree(parser);        
+
+        if(!(result & 4)) return -1; //check whether lyrics found
+        snprintf(url, 512, LEOSLYRICS_CONTENT_URL, hid);
+
+        return 0;
+}
+
+int get_lyr_leoslyrics(char *artist, char *title)
+{
+        char url_hid[256];
+        if(dltime == NULL) dltime = g_timer_new();
+
+        if(check_lyr_leoslyrics(artist, title, url_hid) != 0) return -1;
+        
+        easy_download_struct lyr_content = {NULL, 0,-1};  
+        g_timer_continue(dltime);              
+        if(!(easy_download(url_hid, &lyr_content, check_dl_progress))) return -1;
+        g_timer_stop(dltime);
+        
+        contentp = XML_ParserCreate(NULL);
+        XML_SetUserData(contentp, NULL);
+        XML_SetElementHandler(contentp, check_content, end_tag);       
+        XML_SetCharacterDataHandler(contentp, fetch_text);
+        XML_Parse(contentp, lyr_content.data, strlen(lyr_content.data), 0);
+        XML_ParserFree(contentp);
+
+        return 0;
+        
+}
+#if SRC_LYR_LEOSLYRICS == plugin
+int register_me (src_lyr *source_descriptor)
+{ 
+  source_descriptor->check_lyr = check_lyr_leoslyrics;
+  source_descriptor->get_lyr = get_lyr_leoslyrics;
+  
+  source_descriptor->name = "Leoslyrics";
+  source_descriptor->description = "powered by http://www.leoslyrics.com";
+}
+#endif
index 427c1f52936401b957f12dd128a27d6bd9f562d5..3ceef6a8c055c0a17084c597d48ca47958fd4517 100644 (file)
@@ -1,10 +1,17 @@
+#SUBDIRS = 
+
 AM_CPPFLAGS = \
   $(GLIB_CFLAGS)\
   $(GTHREAD_CFLAGS)\
-  $(libcurl_CFLAGS)\
+  $(GMODULE_CFLAGS)\
   -DLOCALE_DIR=\""$(datadir)/locale"\"\
   -DSYSCONFDIR=\""$(sysconfdir)"\"
 
+ncmpc_LDADD = \
+  $(GLIB_LIBS)\
+  $(GTHREAD_LIBS)\
+  $(GMODULE_LIBS)
+
 ncmpc_headers = \
   libmpdclient.h\
   mpdclient.h\
@@ -22,12 +29,15 @@ ncmpc_headers = \
   utils.h\
   ncmpc.h\
   screen_browse.h\
-  splash.h
+  splash.h\
+  src_lyrics.h
 
 # $Id$
 
 bin_PROGRAMS = ncmpc
 
+lyr_src=${lyr_src_fixed}
+
 ncmpc_SOURCES = \
   libmpdclient.c\
   main.c\
@@ -53,9 +63,18 @@ ncmpc_SOURCES = \
   strfsong.c\
   utils.c\
   splash.c\
-  $(ncmpc_headers)
+  src_lyrics.c
+
+if LEOSLYRICS_FIXED
+ncmpc_SOURCES+=lyrics_leoslyrics.c 
+AM_CPPFLAGS+=${libcurl_CFLAGS}
+ncmpc_LDADD+=${libcurl_LIBS}
+endif
+
+if HD_FIXED
+ncmpc_SOURCES+=lyrics_hd.c 
+endif
+
+ncmpc_SOURCES+=${ncmpc_headers}
+
 
-ncmpc_LDADD = \
-  $(GLIB_LIBS)\
-  $(GTHREAD_LIBS)\
-  $(libcurl_LIBS)
index 9d1211ec4104b65a10eb656b084766dae46a5076..79d2525e39696d58373b990466882719214452fa 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef LIST_WINDOW_H
 #define LIST_WINDOW_H
 
+#include <ncurses.h>
+#include <command.h>
 #define LW_ROW(lw) (lw ? lw->selected-lw->start :  0)
 
 #define LW_HIDE_CURSOR    0x01
diff --git a/src/lyrics_hd.c b/src/lyrics_hd.c
new file mode 100644 (file)
index 0000000..2d91adc
--- /dev/null
@@ -0,0 +1,52 @@
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "src_lyrics.h"
+
+char *check_lyr_hd(char *artist, char *title, int how)
+{ //checking whether for lyrics file existence and proper access
+        static char path[1024];
+        snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", 
+                        getenv("HOME"), artist, title);
+    
+    if(g_access(path, how) != 0) return NULL;
+                 
+        return path;
+}              
+
+
+int get_lyr_hd(char *artist, char *title)
+{
+        char *path = check_lyr_hd(artist, title, R_OK);
+        if(path == NULL) return -1;
+        
+        FILE *lyr_file;        
+        lyr_file = fopen(path, "r");
+        if(lyr_file == NULL) return -1;
+        
+        char *buf = NULL;
+        char **line = &buf;
+        size_t n = 0;
+        
+        while(1)
+        {
+         n = getline(line, &n, lyr_file); 
+         if( n < 1 || *line == NULL || feof(lyr_file) != 0 ) return 0;
+         add_text_line(&lyr_text, *line, n);
+         free(*line);
+         *line = NULL; n = 0;
+         }
+        
+        return 0;
+}      
+
+int register_lyr_hd (src_lyr *source_descriptor)
+{ 
+  source_descriptor->check_lyr = check_lyr_hd;
+  source_descriptor->get_lyr = get_lyr_hd;
+  
+  source_descriptor->name = "Harddisk";
+  source_descriptor->description = "";
+}
diff --git a/src/lyrics_leoslyrics.c b/src/lyrics_leoslyrics.c
new file mode 100644 (file)
index 0000000..f497376
--- /dev/null
@@ -0,0 +1,156 @@
+#include "src_lyrics.h"
+#include "easy_download.h"
+#include <expat.h>
+#include <string.h>
+#include "options.h"
+
+#define LEOSLYRICS_SEARCH_URL "http://api.leoslyrics.com/api_search.php?auth=ncmpc&artist=%s&songtitle=%s"
+#define LEOSLYRICS_CONTENT_URL "http://api.leoslyrics.com/api_lyrics.php?auth=ncmpc&hid=%s"
+#define CREDITS "Lyrics provided by www.LeosLyrics.com"
+
+char *hid;
+XML_Parser parser, contentp;
+
+int check_dl_progress(void *clientp, double dltotal, double dlnow,
+                        double ultotal, double ulnow)
+{
+        if(g_timer_elapsed(dltime, NULL) >= options.lyrics_timeout || lock == 4)
+        {      
+                formed_text_init(&lyr_text);
+                return -1;
+        }
+
+        return 0;
+}      
+
+
+
+static void check_content(void *data, const char *name, const char **atts)
+{ 
+        if(strstr(name, "text") != NULL)
+        {
+
+                result |= 16;
+        }
+}
+        
+
+static void check_search_response(void *data, const char *name,
+                 const char **atts)
+{
+        if(strstr(name, "response") != NULL)
+        {
+        result |=2;
+        return;
+        }  
+            
+        if(result & 4)
+        {
+                if(strstr(name, "result") != NULL)
+                {
+                        if(strstr(atts[2], "hid") != NULL)
+                        {
+                                hid = atts[3];
+                        }
+        
+                        if(strstr(atts[2], "exactMatch") != NULL)
+                        {
+                                result |= 8;
+                        }                      
+                }
+        }
+                        
+}
+
+static void end_tag(void *data, const char *name)
+{
+  //hmmmmmm            
+}
+
+  static void check_search_success(void *userData, const XML_Char *s, int len)
+    {
+        if(result & 2) //lets first check whether we're right
+        {              //we don't really want to search in the wrong string
+                if(strstr((char*) s, "SUCCESS"))
+                {
+                result |=4;
+                }
+        }      
+    }
+
+static void fetch_text(void *userData, const XML_Char *s, int len) 
+{
+        if(result & 16)
+        {
+                add_text_line(&lyr_text, s, len); 
+        }
+}
+
+/*int deregister_lyr_leoslyrics ()
+{
+  
+}*/
+
+int check_lyr_leoslyrics(char *artist, char *title, char *url)
+{
+        char url_avail[256];
+
+        //this replacess the whitespaces with '+'
+        g_strdelimit(artist, " ", '+');
+        g_strdelimit(title, " ", '+');
+        
+        //we insert the artist and the title into the url              
+        snprintf(url_avail, 512, LEOSLYRICS_SEARCH_URL, artist, title);
+
+        //download that xml!
+        easy_download_struct lyr_avail = {NULL, 0,-1}; 
+        
+        g_timer_start(dltime);
+        if(!easy_download(url_avail, &lyr_avail, check_dl_progress)) return -1;
+        g_timer_stop(dltime);
+
+        //we gotta parse that stuff with expat
+        parser = XML_ParserCreate(NULL);
+        XML_SetUserData(parser, NULL);
+        
+        XML_SetElementHandler(parser, check_search_response, end_tag);
+        XML_SetCharacterDataHandler(parser, check_search_success);
+        XML_Parse(parser, lyr_avail.data, strlen(lyr_avail.data), 0);  
+        XML_ParserFree(parser);        
+
+        if(!(result & 4)) return -1; //check whether lyrics found
+        snprintf(url, 512, LEOSLYRICS_CONTENT_URL, hid);
+
+        return 0;
+}
+
+int get_lyr_leoslyrics(char *artist, char *title)
+{
+        char url_hid[256];
+        if(dltime == NULL) dltime = g_timer_new();
+
+        if(check_lyr_leoslyrics(artist, title, url_hid) != 0) return -1;
+        
+        easy_download_struct lyr_content = {NULL, 0,-1};  
+        g_timer_continue(dltime);              
+        if(!(easy_download(url_hid, &lyr_content, check_dl_progress))) return -1;
+        g_timer_stop(dltime);
+        
+        contentp = XML_ParserCreate(NULL);
+        XML_SetUserData(contentp, NULL);
+        XML_SetElementHandler(contentp, check_content, end_tag);       
+        XML_SetCharacterDataHandler(contentp, fetch_text);
+        XML_Parse(contentp, lyr_content.data, strlen(lyr_content.data), 0);
+        XML_ParserFree(contentp);
+
+        return 0;
+        
+}
+int register_lyr_leoslyrics (src_lyr *source_descriptor)
+{ 
+  source_descriptor->check_lyr = check_lyr_leoslyrics;
+  source_descriptor->get_lyr = get_lyr_leoslyrics;
+  
+  source_descriptor->name = "Leoslyrics";
+  source_descriptor->description = "powered by http://www.leoslyrics.com";
+}
index 02311ad483637852639895e5bf54fb33f6013790..ed7c70cc76d860b45453f3542a8156bb3592f130 100644 (file)
@@ -33,6 +33,7 @@
 #include "options.h"
 #include "conf.h"
 #include "command.h"
+#include "src_lyrics.h"
 #include "screen.h"
 #include "screen_utils.h"
 #include "strfsong.h"
@@ -266,6 +267,8 @@ main(int argc, const char *argv[])
   ncurses_init();
   if(options->show_splash == TRUE) draw_splash();
 
+  init_src_lyr ();
+
   /* connect to our music player daemon */
   mpd = mpdclient_new();
  
index 0732fb31a8d4cbd70c76b2559160b18a372c3b40..8d70e004cac192847bc9c0370e6ee41ea4513b1e 100644 (file)
@@ -3,8 +3,6 @@
  *     
  * (c) 2006 by Kalle Wallin <kaw@linux.se>
  * Tue Aug  1 23:17:38 2006
- * lyrics enhancement written by Andreas Obergrusberger <tradiaz@yahoo.de> 
- * using www.leoslyrics.com XML API
  *
  * 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
 #include "screen_utils.h"
 #include "easy_download.h"
 #include "strfsong.h"
+#include "src_lyrics.h"
 
+int src_selection;
 
-#define LEOSLYRICS_SEARCH_URL "http://api.leoslyrics.com/api_search.php?auth=ncmpc&artist=%s&songtitle=%s"
-#define LEOSLYRICS_CONTENT_URL "http://api.leoslyrics.com/api_lyrics.php?auth=ncmpc&hid=%s"
-
-#define CREDITS "Lyrics provided by www.LeosLyrics.com"
-typedef struct _formed_text
-{
-        GString *text;
-        GArray *lines;
-        int val;
-} formed_text;
-
-typedef struct _retrieval_spec
-{
-        mpdclient_t *client;
-        int way;
-} retrieval_spec;
-
-
-
-XML_Parser parser, contentp;
-static int lyrics_text_rows = -1;
-static list_window_t *lw = NULL;
-guint8 result;
-char *hid;
-GTimer *dltime;
-short int lock;
-formed_text lyr_text;
-/* result is a bitset in which the succes when searching 4 lyrics is logged
-countend by position - backwards
-0: lyrics in database
-1: proper access  to the lyrics provider
-2: lyrics found
-3: exact match
-4: lyrics downloaded
-5: lyrics saved
-wasting 3 bits doesn't mean being a fat memory hog like kde.... does it?
-*/
 static void lyrics_paint(screen_t *screen, mpdclient_t *c);
 
-int get_text_line(formed_text *text, int num, char *dest, int len)
-{
-        memset(dest, '\0', len*sizeof(char));
-    if(num >= text->lines->len-1) return -1;   
-        int linelen;
-        if(num == 0)
-        {
-                linelen = g_array_index(text->lines, int, num);
-                memcpy(dest, text->text->str, linelen*sizeof(char));   
-        }
-        else if(num == 1)
-        { //dont ask me why, but this is needed....
-                linelen = g_array_index(text->lines, int, num)
-                        - g_array_index(text->lines, int, num-1);
-                memcpy(dest, &text->text->str[g_array_index(text->lines, int, num-1)],
-                linelen*sizeof(char)); 
-        }      
-        else
-        {
-                linelen = g_array_index(text->lines, int, num+1)
-                        - g_array_index(text->lines, int, num);
-                memcpy(dest, &text->text->str[g_array_index(text->lines, int, num)],
-                linelen*sizeof(char)); 
-        }
-        dest[linelen] = '\n';
-        dest[linelen+1] = '\0';
-        
-        return 0;
-}
-        
-void add_text_line(formed_text *dest, const char *src, int len)
-{
-        // need this because g_array_append_val doesnt work with literals
-        // and expat sends "\n" as an extra line everytime
-        if(len == 0)
-        {
-                dest->val = strlen(src);
-                if(dest->lines->len > 0) dest->val += g_array_index(dest->lines, int,
-                                                                        dest->lines->len-1);
-                g_string_append(dest->text, src);
-                g_array_append_val(dest->lines, dest->val);
-                return;
-        }
-        if(len > 1 || dest->val == 0) 
-        {
-                dest->val = len;       
-                if(dest->lines->len > 0) dest->val += g_array_index(dest->lines, int,
-                                                                        dest->lines->len-1);
-        }
-        else if (len == 1 && dest->val != 0) dest->val = 0;
-                                
-        if(dest->val > 0)
-        { 
-                g_string_append_len(dest->text, src, len);
-                g_array_append_val(dest->lines, dest->val);
-        }
-}
-
-void formed_text_init(formed_text *text)
-{
-        if(text->text != NULL) g_string_free(text->text, TRUE);        
-        text->text = g_string_new("");
-        
-        if(text->lines != NULL) g_array_free(text->lines, TRUE);
-        text->lines = g_array_new(FALSE, TRUE, 4);
-        
-        text->val = 0;
-}
-
-static void check_content(void *data, const char *name, const char **atts)
-{ 
-        if(strstr(name, "text") != NULL)
-        {
-
-                result |= 16;
-        }
-}
-        
-
-static void check_search_response(void *data, const char *name,
-                 const char **atts)
-{
-        if(strstr(name, "response") != NULL)
-        {
-        result |=2;
-        return;
-        }  
-            
-        if(result & 4)
-        {
-                if(strstr(name, "result") != NULL)
-                {
-                        if(strstr(atts[2], "hid") != NULL)
-                        {
-                                hid = atts[3];
-                        }
-        
-                        if(strstr(atts[2], "exactMatch") != NULL)
-                        {
-                                result |= 8;
-                        }                      
-                }
-        }
-                        
-}
-
-static void end_tag(void *data, const char *name)
-{
-  //hmmmmmm            
-}
-
-  static void check_search_success(void *userData, const XML_Char *s, int len)
-    {
-        if(result & 2) //lets first check whether we're right
-        {              //we don't really want to search in the wrong string
-                if(strstr((char*) s, "SUCCESS"))
-                {
-                result |=4;
-                }
-        }      
-    }
-
-static void fetch_text(void *userData, const XML_Char *s, int len) 
-{
-        if(result & 16)
-        {
-                add_text_line(&lyr_text, s, len); 
-        }
-}
-
-int check_dl_progress(void *clientp, double dltotal, double dlnow,
-                        double ultotal, double ulnow)
-{
-        if(g_timer_elapsed(dltime, NULL) >= options.lyrics_timeout || lock == 4)
-        {      
-                formed_text_init(&lyr_text);
-                return -1;
-        }
-
-        return 0;
-}      
-
-
-int check_lyr_http(char *artist, char *title, char *url)
-{
-        char url_avail[256];
-
-        //this replacess the whitespaces with '+'
-        g_strdelimit(artist, " ", '+');
-        g_strdelimit(title, " ", '+');
-        
-        //we insert the artist and the title into the url              
-        snprintf(url_avail, 512, LEOSLYRICS_SEARCH_URL, artist, title);
-
-        //download that xml!
-        easy_download_struct lyr_avail = {NULL, 0,-1}; 
-        
-        g_timer_start(dltime);
-        if(!easy_download(url_avail, &lyr_avail, check_dl_progress)) return -1;
-        g_timer_stop(dltime);
-
-        //we gotta parse that stuff with expat
-        parser = XML_ParserCreate(NULL);
-        XML_SetUserData(parser, NULL);
-        
-        XML_SetElementHandler(parser, check_search_response, end_tag);
-        XML_SetCharacterDataHandler(parser, check_search_success);
-        XML_Parse(parser, lyr_avail.data, strlen(lyr_avail.data), 0);  
-        XML_ParserFree(parser);        
-
-        if(!(result & 4)) return -1; //check whether lyrics found
-        snprintf(url, 512, LEOSLYRICS_CONTENT_URL, hid);
-
-        return 0;
-}
-int get_lyr_http(char *artist, char *title)
-{
-        char url_hid[256];
-        if(dltime == NULL) dltime = g_timer_new();
-
-        if(check_lyr_http(artist, title, url_hid) != 0) return -1;
-        
-        easy_download_struct lyr_content = {NULL, 0,-1};  
-        g_timer_continue(dltime);              
-        if(!(easy_download(url_hid, &lyr_content, check_dl_progress))) return -1;
-        g_timer_stop(dltime);
-        
-        contentp = XML_ParserCreate(NULL);
-        XML_SetUserData(contentp, NULL);
-        XML_SetElementHandler(contentp, check_content, end_tag);       
-        XML_SetCharacterDataHandler(contentp, fetch_text);
-        XML_Parse(contentp, lyr_content.data, strlen(lyr_content.data), 0);
-        XML_ParserFree(contentp);
-
-        return 0;
-        
-}
 FILE *create_lyr_file(char *artist, char *title)
 {
                 char path[1024];
@@ -299,42 +64,6 @@ FILE *create_lyr_file(char *artist, char *title)
             return fopen(path, "w");
 }      
 
-char *check_lyr_hd(char *artist, char *title, int how)
-{ //checking whether for lyrics file existence and proper access
-        static char path[1024];
-        snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", 
-                        getenv("HOME"), artist, title);
-    
-    if(g_access(path, how) != 0) return NULL;
-                 
-        return path;
-}              
-
-
-int get_lyr_hd(char *artist, char *title)
-{
-        char *path = check_lyr_hd(artist, title, R_OK);
-        if(path == NULL) return -1;
-        
-        FILE *lyr_file;        
-        lyr_file = fopen(path, "r");
-        if(lyr_file == NULL) return -1;
-        
-        char *buf = NULL;
-        char **line = &buf;
-        size_t n = 0;
-        
-        while(1)
-        {
-         n = getline(line, &n, lyr_file); 
-         if( n < 1 || *line == NULL || feof(lyr_file) != 0 ) return 0;
-         add_text_line(&lyr_text, *line, n);
-         free(*line);
-         *line = NULL; n = 0;
-         }
-        
-        return 0;
-}      
     
 int store_lyr_hd()
 {
@@ -401,17 +130,17 @@ gpointer get_lyr(void *c)
         add_text_line(&lyr_text, "", 0);
         add_text_line(&lyr_text, "", 0);
         
-        if (((retrieval_spec*)c)->way == 1)
+        if (((retrieval_spec*)c)->way != -1) /*till it'S of use*/
         {
-                 if(get_lyr_http(artist, title) != 0) return NULL;
+                 if(get_lyr_by_src (src_selection, artist, title) != 0) return NULL;
         }
-        else{
+        /*else{
                 if(get_lyr_hd(artist, title) != 0) 
                 {
-                if(get_lyr_http(artist, title) != 0) return NULL;
+                if(get_lyr_hd(artist, title) != 0) return NULL;
                 }
                 else result |= 1;
-        }
+        }*/
         
         lw->start = 0;
         check_repaint();
@@ -430,7 +159,9 @@ list_callback(int index, int *highlight, void *data)
           ||lyr_text.lines->len == 4) && index == 0))
   {
     *highlight=3; 
-          return CREDITS;
+    src_lyr* selected =  g_array_index (src_lyr_stack, src_lyr*, src_selection);
+    if (selected != NULL) return selected->description;
+    return "";
   }
     
   if(index < 2 && lyr_text.lines->len > 4) *highlight=3;
@@ -473,29 +204,43 @@ lyrics_exit(void)
 static char *
 lyrics_title(char *str, size_t size)
 {
-        if(lyr_text.lines->len == 4)
-        {
+  static GString *msg;
+  if (msg == NULL)
+    msg = g_string_new ("");
+  else g_string_erase (msg, 0, -1);
+
+  g_string_append (msg, "Lyrics  [");
+
+  if (src_selection > src_lyr_stack->len-1)
+    g_string_append (msg, "No plugin available");
+  else
+    {
+      src_lyr* selected =  g_array_index (src_lyr_stack, src_lyr*, src_selection);
+      if (selected != NULL)
+         g_string_append (msg, selected->name);
+      else g_string_append (msg, "NONE");
+    }
+  if(lyr_text.lines->len == 4)
+       {
                 if(lock == 1)
                 {
                         if(!(result & 1))
                         {
-                                if(!(result & 2)) return _("Lyrics  [No connection]");
-                                if(!(result & 4)) return _("Lyrics  [Not found]"); 
+                               g_string_append (msg, " - ");
+                                if(!(result & 2)) g_string_append (msg, _("No connection"));
+                                if(!(result & 4)) g_string_append (msg, _("Not found")); 
                         }
                 }
-                if(lock == 2) return _("Lyrics  [retrieving]");
+                if(lock == 2) 
+                 {
+                   g_string_append (msg, " - ");
+                   g_string_append (msg, _("retrieving"));
+                 }
         }
-        /*if(lyr_text.lines->len > 2) 
-        {
-                static char buf[512];
-                char artist[512];
-                char title[512];
-                get_text_line(&lyr_text, 0, artist, 512);
-                get_text_line(&lyr_text, 1, artist, 512);
-                snprintf(buf, 512, "Lyrics  %s - %s", artist, title);
-                return buf;
-        }*/
-        return "Lyrics";
+
+       g_string_append_c (msg, ']');
+
+       return msg->str;
 }
 
 static void 
@@ -506,6 +251,7 @@ lyrics_paint(screen_t *screen, mpdclient_t *c)
   wrefresh(lw->w);
 }
 
+
 static void 
 lyrics_update(screen_t *screen, mpdclient_t *c)
 {  
@@ -571,8 +317,14 @@ lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
           spec.client = c;
           spec.way = 1;
           g_thread_create(get_lyr, &spec, FALSE, NULL);
-        default:
-      break;
+         return 1;
+       case CMD_SEARCH_MODE:
+         //while (0==0) fprintf (stderr, "%i", src_lyr_stack->len);
+         if (src_selection == src_lyr_stack->len-1) src_selection = -1;
+         src_selection++;
+         return 1;
+       default:
+         break;
     }
 
   lw->selected = lw->start+lw->rows;
diff --git a/src/src_lyrics.c b/src/src_lyrics.c
new file mode 100644 (file)
index 0000000..ee7c852
--- /dev/null
@@ -0,0 +1,201 @@
+/* 
+ *     
+ * (c) 2006 by Kalle Wallin <kaw@linux.se>
+ * Thu Dec 28 23:17:38 2006
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "src_lyrics.h"
+#include <options.h>
+#include <unistd.h>
+#include "../config.h"
+
+#define PLUGIN_DIR_USER "/home/andi/.ncmpc/plugins"
+
+int get_text_line(formed_text *text, int num, char *dest, int len)
+{
+        memset(dest, '\0', len*sizeof(char));
+    if(num >= text->lines->len-1) return -1;   
+        int linelen;
+        if(num == 0)
+        {
+                linelen = g_array_index(text->lines, int, num);
+                memcpy(dest, text->text->str, linelen*sizeof(char));   
+        }
+        else if(num == 1)
+        { //dont ask me why, but this is needed....
+                linelen = g_array_index(text->lines, int, num)
+                        - g_array_index(text->lines, int, num-1);
+                memcpy(dest, &text->text->str[g_array_index(text->lines, int, num-1)],
+                linelen*sizeof(char)); 
+        }      
+        else
+        {
+                linelen = g_array_index(text->lines, int, num+1)
+                        - g_array_index(text->lines, int, num);
+                memcpy(dest, &text->text->str[g_array_index(text->lines, int, num)],
+                linelen*sizeof(char)); 
+        }
+        dest[linelen] = '\n';
+        dest[linelen+1] = '\0';
+        
+        return 0;
+}
+        
+void add_text_line(formed_text *dest, const char *src, int len)
+{
+        // need this because g_array_append_val doesnt work with literals
+        // and expat sends "\n" as an extra line everytime
+        if(len == 0)
+        {
+                dest->val = strlen(src);
+                if(dest->lines->len > 0) dest->val += g_array_index(dest->lines, int,
+                                                                        dest->lines->len-1);
+                g_string_append(dest->text, src);
+                g_array_append_val(dest->lines, dest->val);
+                return;
+        }
+        if(len > 1 || dest->val == 0) 
+        {
+                dest->val = len;       
+                if(dest->lines->len > 0) dest->val += g_array_index(dest->lines, int,
+                                                                        dest->lines->len-1);
+        }
+        else if (len == 1 && dest->val != 0) dest->val = 0;
+                                
+        if(dest->val > 0)
+        { 
+                g_string_append_len(dest->text, src, len);
+                g_array_append_val(dest->lines, dest->val);
+        }
+}
+
+void formed_text_init(formed_text *text)
+{
+        if(text->text != NULL) g_string_free(text->text, TRUE);        
+        text->text = g_string_new("");
+        
+        if(text->lines != NULL) g_array_free(text->lines, TRUE);
+        text->lines = g_array_new(FALSE, TRUE, 4);
+        
+        text->val = 0;
+}
+
+#ifdef ENABLE_LYRSRC_LEOSLYRICS
+int deregister_lyr_leoslyrics ();
+int register_lyr_leoslyrics (src_lyr *source_descriptor);
+#endif
+
+#ifdef ENABLE_LYRSRC_HD
+int deregister_lyr_hd ();
+int register_lyr_hd (src_lyr *source_descriptor);
+#endif
+
+int init_src_lyr_stack ()
+{
+  src_lyr_stack = g_array_new (TRUE, FALSE, sizeof (src_lyr*));
+
+#ifdef ENABLE_LYRSRC_HD
+  src_lyr *src_lyr_hd = malloc (sizeof (src_lyr));
+  src_lyr_hd->register_src_lyr = register_lyr_hd; 
+  g_array_append_val (src_lyr_stack, src_lyr_hd);
+#endif
+#ifdef ENABLE_LYRSRC_LEOSLYRICS 
+  src_lyr *src_lyr_leoslyrics = malloc (sizeof (src_lyr));
+  src_lyr_leoslyrics->register_src_lyr = register_lyr_leoslyrics; 
+  g_array_append_val (src_lyr_stack, src_lyr_leoslyrics);
+#endif
+
+#ifndef DISABLE_PLUGIN_SYSTEM
+  src_lyr_plugins_load ();
+#endif
+
+}
+
+int init_src_lyr ()
+{
+  init_src_lyr_stack();
+
+  int i = 0;
+  while (g_array_index (src_lyr_stack, src_lyr*, i) != NULL)
+    {
+      src_lyr *i_stack;
+      i_stack = g_array_index (src_lyr_stack, src_lyr*, i);
+      i_stack->register_src_lyr (i_stack);
+      i++;
+    }
+  return 0;
+}
+
+int get_lyr_by_src (int priority, char *artist, char *title)
+{
+  //if (g_array_index (src_lyr_stack, src_lyr*, priority)->check_lyr() == 0)
+    //{
+       g_array_index (src_lyr_stack, src_lyr*, priority)->get_lyr (artist, title);
+    //}
+  return 0;
+}
+
+int src_lyr_load_plugin_file (const char *file)
+{
+  GString *path;
+  path = g_string_new (PLUGIN_DIR_SYSTEM);
+  g_string_append (path, "/");
+  g_string_append (path, file);
+
+  src_lyr_plugin_register register_func;
+  src_lyr *new_src = malloc (sizeof (src_lyr));
+  new_src->module = g_module_open (path->str, G_MODULE_BIND_LAZY);
+  //if (new_src->module == NULL) for (;;) fprintf (stderr, g_module_error());
+  if (!g_module_symbol (new_src->module, "register_me", (gpointer*) &register_func)) 
+    return -1;
+  new_src->register_src_lyr = register_func;
+  g_array_append_val (src_lyr_stack, new_src);
+  return 0;
+}
+  
+void src_lyr_plugins_load_from_dir (GDir *plugin_dir)
+{
+  const gchar *cur_file;
+
+  for (;;)
+    {
+      cur_file = g_dir_read_name (plugin_dir);
+      if (cur_file == NULL) break;
+      src_lyr_load_plugin_file (cur_file);
+    }
+}
+
+
+
+int src_lyr_plugins_load ()
+{
+  GDir *plugin_dir;
+
+  plugin_dir = g_dir_open (PLUGIN_DIR_SYSTEM, 0, NULL);
+  if (plugin_dir == NULL)
+    return -1;
+  src_lyr_plugins_load_from_dir (plugin_dir);
+  plugin_dir = g_dir_open (PLUGIN_DIR_USER, 0, NULL);
+  if (plugin_dir == NULL)
+    return -1;
+  src_lyr_plugins_load_from_dir (plugin_dir);
+
+  return 0;
+}
+
+      
diff --git a/src/src_lyrics.h b/src/src_lyrics.h
new file mode 100644 (file)
index 0000000..dd52e72
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef SOURCE_LYRICS
+#define SOURCE_LYRICS
+
+#include <stdlib.h>
+#include <glib.h>
+#include "list_window.h"
+#include "mpdclient.h"
+#include <gmodule.h>
+
+typedef struct _formed_text
+{
+        GString *text;
+        GArray *lines;
+        int val;
+} formed_text;
+
+void formed_text_init(formed_text *text);
+void add_text_line(formed_text *dest, const char *src, int len);
+
+typedef struct _retrieval_spec
+{
+        mpdclient_t *client;
+        int way;
+} retrieval_spec;
+
+
+
+static int lyrics_text_rows = -1;
+static list_window_t *lw = NULL;
+
+GTimer *dltime;
+short int lock;
+formed_text lyr_text;
+
+guint8 result;
+
+/* result is a bitset in which the success when searching 4 lyrics is logged
+countend by position - backwards
+0: lyrics in database
+1: proper access  to the lyrics provider
+2: lyrics found
+3: exact match
+4: lyrics downloaded
+5: lyrics saved
+wasting 3 bits doesn't mean being a fat memory hog like kde.... does it?
+*/
+
+
+typedef struct src_lyr src_lyr;
+
+struct src_lyr
+{
+  char *name;
+  char *source_name;
+  char *description;
+  
+  int (*register_src_lyr) (src_lyr *source_descriptor);
+  int (*deregister_src_lyr) ();
+
+  int (*check_lyr) (char *artist, char *title, char *url);
+  int (*get_lyr) (char *artist, char *title);
+  int (*state_lyr) ();
+
+#ifndef DISABLE_PLUGIN_SYSTEM
+  GModule *module;
+#endif
+};
+
+typedef int (*src_lyr_plugin_register) (src_lyr *source_descriptor);
+
+GArray *src_lyr_stack;
+
+int init_src_lyr_stack ();
+int init_src_lyr ();
+int get_lyr_by_src (int priority, char *artist, char *title);
+
+#endif