From: Andreas Obergrusberger Date: Wed, 3 Jan 2007 20:12:16 +0000 (+0000) Subject: added a plugin system for lyrics sources X-Git-Tag: v0.12_alpha1~350 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=6d9b28ec69212a2542ab2958ed0b012c124dbc07;p=ncmpc.git added a plugin system for lyrics sources git-svn-id: https://svn.musicpd.org/ncmpc/branches/tradiaz@5217 09075e82-0dd4-0310-85a5-a0d7c8717e4f --- diff --git a/ChangeLog b/ChangeLog index 6fb81d0..6ae9dbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-01-03 Andreas Obergrusberger + * added plugin support for lyrics + * changed the build system heavily, look at INSTALL + * build system now GNU standardized + 2006-11-11 Andreas Obergrusberger * fixed advanced search * go root/parent also for artist screen diff --git a/INSTALL b/INSTALL index 56b077d..38893ad 100644 --- 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 + diff --git a/Makefile.am b/Makefile.am index 574d8a2..9a01c2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS = \ doc\ po -AUTOMAKE_OPTIONS = foreign 1.6 +AUTOMAKE_OPTIONS = gnu 1.6 # $Id$ diff --git a/configure.ac b/configure.ac index 1baa12f..987c4d2 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 0000000..9bb784f --- /dev/null +++ b/plugins/Makefile.am @@ -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 index 0000000..f4d4608 --- /dev/null +++ b/plugins/hd/Makefile.am @@ -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 index 0000000..a90ee9d --- /dev/null +++ b/plugins/hd/lyrics_hd.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#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 index 0000000..4eb76f3 --- /dev/null +++ b/plugins/leoslyrics/Makefile.am @@ -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 index 0000000..83616cf --- /dev/null +++ b/plugins/leoslyrics/easy_download.c @@ -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 +#include +#include +#include +#include "ncmpc.h" + +#ifdef ENABLE_LYRICS_SCREEN + +#include +#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 index 0000000..92dc22e --- /dev/null +++ b/plugins/leoslyrics/easy_download.h @@ -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 + +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 index 0000000..47aabe1 --- /dev/null +++ b/plugins/leoslyrics/lyrics_leoslyrics.c @@ -0,0 +1,158 @@ +#include "src_lyrics.h" +#include "easy_download.h" +#include +#include +#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 diff --git a/src/Makefile.am b/src/Makefile.am index 427c1f5..3ceef6a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) diff --git a/src/list_window.h b/src/list_window.h index 9d1211e..79d2525 100644 --- a/src/list_window.h +++ b/src/list_window.h @@ -1,6 +1,8 @@ #ifndef LIST_WINDOW_H #define LIST_WINDOW_H +#include +#include #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 index 0000000..2d91adc --- /dev/null +++ b/src/lyrics_hd.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +#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 index 0000000..f497376 --- /dev/null +++ b/src/lyrics_leoslyrics.c @@ -0,0 +1,156 @@ +#include "src_lyrics.h" +#include "easy_download.h" +#include +#include +#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"; +} diff --git a/src/main.c b/src/main.c index 02311ad..ed7c70c 100644 --- a/src/main.c +++ b/src/main.c @@ -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(); diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c index 0732fb3..8d70e00 100644 --- a/src/screen_lyrics.c +++ b/src/screen_lyrics.c @@ -3,8 +3,6 @@ * * (c) 2006 by Kalle Wallin * Tue Aug 1 23:17:38 2006 - * lyrics enhancement written by Andreas Obergrusberger - * 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 @@ -42,245 +40,12 @@ #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 index 0000000..ee7c852 --- /dev/null +++ b/src/src_lyrics.c @@ -0,0 +1,201 @@ +/* + * + * (c) 2006 by Kalle Wallin + * 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 +#include +#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*) ®ister_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 index 0000000..dd52e72 --- /dev/null +++ b/src/src_lyrics.h @@ -0,0 +1,77 @@ +#ifndef SOURCE_LYRICS +#define SOURCE_LYRICS + +#include +#include +#include "list_window.h" +#include "mpdclient.h" +#include + +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