diff options
-rw-r--r-- | configure.ac | 125 | ||||
-rwxr-xr-x | lyrics/hd.py | 22 | ||||
-rwxr-xr-x | lyrics/leoslyrics.py | 68 | ||||
-rwxr-xr-x | lyrics/lyricswiki.rb | 16 | ||||
-rw-r--r-- | plugins/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/hd/Makefile.am | 40 | ||||
-rw-r--r-- | plugins/hd/lyrics_hd.c | 52 | ||||
-rw-r--r-- | plugins/leoslyrics/Makefile.am | 43 | ||||
-rw-r--r-- | plugins/leoslyrics/easy_download.c | 89 | ||||
-rw-r--r-- | plugins/leoslyrics/easy_download.h | 31 | ||||
-rw-r--r-- | plugins/leoslyrics/lyrics_leoslyrics.c | 162 | ||||
-rw-r--r-- | src/Makefile.am | 20 | ||||
-rw-r--r-- | src/lyrics.c | 243 | ||||
-rw-r--r-- | src/lyrics.h | 48 | ||||
-rw-r--r-- | src/lyrics_hd.c | 50 | ||||
-rw-r--r-- | src/lyrics_leoslyrics.c | 162 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/screen_lyrics.c | 355 | ||||
-rw-r--r-- | src/src_lyrics.c | 202 | ||||
-rw-r--r-- | src/src_lyrics.h | 75 |
20 files changed, 589 insertions, 1224 deletions
diff --git a/configure.ac b/configure.ac index 8382c32cb..9c0fd9dfa 100644 --- a/configure.ac +++ b/configure.ac @@ -134,35 +134,6 @@ 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], - [libcurl=yes], - #[libcurl=yes,LIBS="$LIBS -lcurl"], #doesn't work for me on arch - [AC_MSG_WARN([libcurl is required for the lyrics screen])]) - -if test "x$libcurl" = "xyes"; then - LIBS="$LIBS -lcurl" -fi - -dnl check for expat -expat=expat -AC_CHECK_LIB([$expat], - [XML_ParserCreate], - [have_expat=yes], - [AC_MSG_WARN($expat library is required for lyrics screen)]) -if test "x$have_expat" = "xyes"; then -LIBS="$LIBS -l$expat" -fi - #if test "x$gthread-2.0" != "xyes"; then # PKG_CHECK_MODULES([GTHREAD], # [glib-2.0 >= 2.2], @@ -250,23 +221,6 @@ 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], @@ -343,78 +297,6 @@ 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], @@ -445,10 +327,5 @@ 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_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_CONFIG_FILES([Makefile src/Makefile doc/Makefile po/Makefile]) AC_OUTPUT -AC_MSG_WARN([TO BUILD AN INSTALL THE PLUGINS cd TO THE plugins DIRECTORY AND EXECUTE make && make install THERE]) diff --git a/lyrics/hd.py b/lyrics/hd.py new file mode 100755 index 000000000..173342c98 --- /dev/null +++ b/lyrics/hd.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +# +# Load lyrics from the user's home directory +# +# Author: Max Kellermann <max@duempel.org> +# + +from sys import argv, exit, stdout +from os import environ +from os.path import expanduser + +path = expanduser("~/.lyrics/%s - %s.txt" % (argv[1], argv[2])) +try: + f = file(path) +except IOError: + exit(2) + +while True: + x = f.read(4096) + if not x: + break + stdout.write(x) diff --git a/lyrics/leoslyrics.py b/lyrics/leoslyrics.py new file mode 100755 index 000000000..0cee65aee --- /dev/null +++ b/lyrics/leoslyrics.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +# +# Load lyrics from leoslyrics.com +# +# Author: Max Kellermann <max@duempel.org> +# + +from sys import argv, exit +from urllib import urlencode, urlopen +from xml.sax import make_parser, SAXException +from xml.sax.handler import ContentHandler + +class SearchContentHandler(ContentHandler): + def __init__(self): + self.code = None + self.hid = None + + def startElement(self, name, attrs): + if name == 'response': + self.code = int(attrs['code']) + elif name == 'result': + if self.hid is None or attrs['exactMatch'] == 'true': + self.hid = attrs['hid'] + +def search(artist, title): + query = urlencode({'auth': 'ncmpc', + 'artist': artist, + 'songtitle': title}) + url = "http://api.leoslyrics.com/api_search.php?" + query + f = urlopen(url) + handler = SearchContentHandler() + parser = make_parser() + parser.setContentHandler(handler) + parser.parse(f) + return handler.hid + +class LyricsContentHandler(ContentHandler): + def __init__(self): + self.code = None + self.is_text = False + self.text = None + + def startElement(self, name, attrs): + if name == 'text': + self.text = '' + self.is_text = True + else: + self.is_text = False + + def characters(self, chars): + if self.is_text: + self.text += chars + +def lyrics(hid): + query = urlencode({'auth': 'ncmpc', + 'hid': hid}) + url = "http://api.leoslyrics.com/api_lyrics.php?" + query + f = urlopen(url) + handler = LyricsContentHandler() + parser = make_parser() + parser.setContentHandler(handler) + parser.parse(f) + return handler.text + +hid = search(argv[1], argv[2]) +if hid is None: + exit(2) +print lyrics(hid) diff --git a/lyrics/lyricswiki.rb b/lyrics/lyricswiki.rb new file mode 100755 index 000000000..39aa4a5b7 --- /dev/null +++ b/lyrics/lyricswiki.rb @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# Load lyrics from lyricswiki.org +# +# Author: Max Kellermann <max@duempel.org> +# + +require 'uri' +require 'net/http' + +url = "http://lyricwiki.org/api.php" + \ + "?artist=#{URI.escape(ARGV[0])}&song=#{URI.escape(ARGV[1])}" +response = Net::HTTP.get(URI.parse(url)) + +exit(2) unless response =~ /<pre>\s*(.*?)\s*<\/pre>/im +puts $1 diff --git a/plugins/Makefile.am b/plugins/Makefile.am deleted file mode 100644 index 9bb784fa3..000000000 --- a/plugins/Makefile.am +++ /dev/null @@ -1,6 +0,0 @@ -SUBDIRS = \ - ${src_lyr_plugins} - -AUTOMAKE_OPTIONS = foreign 1.6 - - diff --git a/plugins/hd/Makefile.am b/plugins/hd/Makefile.am deleted file mode 100644 index f4d4608d8..000000000 --- a/plugins/hd/Makefile.am +++ /dev/null @@ -1,40 +0,0 @@ -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 deleted file mode 100644 index 7a3a8b745..000000000 --- a/plugins/hd/lyrics_hd.c +++ /dev/null @@ -1,52 +0,0 @@ -#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 - result |= 2; - 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; - result |= 4; - 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 deleted file mode 100644 index 4eb76f3ee..000000000 --- a/plugins/leoslyrics/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ -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 deleted file mode 100644 index 83616cf87..000000000 --- a/plugins/leoslyrics/easy_download.c +++ /dev/null @@ -1,89 +0,0 @@ -/* 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 deleted file mode 100644 index 92dc22e9e..000000000 --- a/plugins/leoslyrics/easy_download.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5bcb32242..000000000 --- a/plugins/leoslyrics/lyrics_leoslyrics.c +++ /dev/null @@ -1,162 +0,0 @@ -#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 = strdup (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) - { - if (s[0] == 13 ) return; //ignore any single carriage returns - 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 - - CURL *curl = curl_easy_init (); - char *esc_hid = curl_easy_escape (curl, hid, 0); - free (hid); - - 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_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"; -} diff --git a/src/Makefile.am b/src/Makefile.am index 21bef4d20..31cabfda0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,21 +3,18 @@ AM_CPPFLAGS = \ $(GLIB_CFLAGS)\ $(GTHREAD_CFLAGS)\ - $(GMODULE_CFLAGS)\ -DLOCALE_DIR=\""$(datadir)/locale"\"\ -DSYSCONFDIR=\""$(sysconfdir)"\" ncmpc_LDADD = \ $(GLIB_LIBS)\ - $(GTHREAD_LIBS)\ - $(GMODULE_LIBS) + $(GTHREAD_LIBS) ncmpc_headers = \ libmpdclient.h\ song.h \ mpdclient.h\ playlist.h \ - easy_download.h\ options.h\ conf.h\ command.h\ @@ -31,7 +28,7 @@ ncmpc_headers = \ utils.h\ ncmpc.h\ screen_browse.h\ - src_lyrics.h \ + lyrics.h \ str_pool.h \ gcc.h @@ -50,7 +47,6 @@ ncmpc_SOURCES = \ options.c\ conf.c\ command.c\ - easy_download.c\ screen.c\ screen_utils.c\ screen_play.c\ @@ -67,19 +63,9 @@ ncmpc_SOURCES = \ wreadln.c\ strfsong.c\ utils.c\ - src_lyrics.c \ + lyrics.c \ str_pool.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} diff --git a/src/lyrics.c b/src/lyrics.c new file mode 100644 index 000000000..10ba2a909 --- /dev/null +++ b/src/lyrics.c @@ -0,0 +1,243 @@ +/* ncmpc + * Copyright (C) 2008 Max Kellermann <max@duempel.org> + * This project's homepage is: http://www.musicpd.org + * + * 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 "lyrics.h" + +#include <assert.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/signal.h> +#include <sys/wait.h> +#include <pthread.h> + +static GPtrArray *plugins; + +struct lyrics_loader { + char *artist, *title; + + enum lyrics_loader_result result; + + pthread_t thread; + pthread_mutex_t mutex; + + pid_t pid; + int fd; + + GString *data; +}; + +static int lyrics_register_plugin(const char *path0) +{ + int ret; + struct stat st; + char *path; + + ret = stat(path0, &st); + if (ret < 0) + return -1; + + path = g_strdup(path0); + g_ptr_array_add(plugins, path); + return 0; +} + +void lyrics_init(void) +{ + plugins = g_ptr_array_new(); + + /* XXX configurable paths */ + lyrics_register_plugin("./lyrics/hd.py"); + lyrics_register_plugin("./lyrics/leoslyrics.py"); + lyrics_register_plugin("./lyrics/lyricswiki.rb"); +} + +void lyrics_deinit(void) +{ + guint i; + + for (i = 0; i < plugins->len; ++i) + free(g_ptr_array_index(plugins, i)); + g_ptr_array_free(plugins, TRUE); +} + +static int +lyrics_start_plugin(struct lyrics_loader *loader, const char *plugin_path) +{ + int ret, fds[2]; + pid_t pid; + + assert(loader != NULL); + assert(loader->result == LYRICS_BUSY); + assert(loader->pid < 0); + + ret = pipe(fds); + if (ret < 0) + return -1; + + pid = fork(); + + if (pid < 0) { + close(fds[0]); + close(fds[1]); + return -1; + } + + if (pid == 0) { + dup2(fds[1], 1); + dup2(fds[1], 1); + close(fds[0]); + close(fds[1]); + close(0); + /* XXX close other fds? */ + + execl(plugin_path, plugin_path, + loader->artist, loader->title, NULL); + _exit(1); + } + + close(fds[1]); + + loader->pid = pid; + loader->fd = fds[0]; + loader->data = g_string_new(NULL); + + /* XXX CLOEXEC? */ + + return 0; +} + +static int +lyrics_try_plugin(struct lyrics_loader *loader, const char *plugin_path) +{ + int ret, status; + char buffer[256]; + ssize_t nbytes; + + assert(loader != NULL); + assert(loader->fd >= 0); + + ret = lyrics_start_plugin(loader, plugin_path); + if (ret != 0) + return ret; + + assert(loader->pid > 0); + + while ((nbytes = read(loader->fd, buffer, sizeof(buffer))) > 0) + g_string_append_len(loader->data, buffer, nbytes); + + ret = waitpid(loader->pid, &status, 0); + loader->pid = -1; + + if (ret < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { + g_string_free(loader->data, TRUE); + return -1; + } + + return 0; +} + +static void * +lyrics_thread(void *arg) +{ + struct lyrics_loader *loader = arg; + guint next_plugin = 0; + int ret = -1; + + while (next_plugin < plugins->len && ret != 0) { + const char *plugin_path = g_ptr_array_index(plugins, + next_plugin++); + ret = lyrics_try_plugin(loader, plugin_path); + assert(loader->pid < 0); + } + + pthread_mutex_lock(&loader->mutex); + loader->result = ret == 0 ? LYRICS_SUCCESS : LYRICS_FAILED; + loader->thread = 0; + pthread_mutex_unlock(&loader->mutex); + return NULL; +} + +struct lyrics_loader * +lyrics_load(const char *artist, const char *title) +{ + struct lyrics_loader *loader = g_new(struct lyrics_loader, 1); + int ret; + + assert(artist != NULL); + assert(title != NULL); + + if (loader == NULL) + return NULL; + + loader->artist = g_strdup(artist); + loader->title = g_strdup(title); + loader->result = LYRICS_BUSY; + loader->pid = -1; + + pthread_mutex_init(&loader->mutex, NULL); + + ret = pthread_create(&loader->thread, NULL, lyrics_thread, loader); + if (ret != 0) { + lyrics_free(loader); + return NULL; + } + + return loader; +} + +void +lyrics_free(struct lyrics_loader *loader) +{ + pid_t pid = loader->pid; + pthread_t thread = loader->thread; + + if (pid > 0) + kill(pid, SIGTERM); + + if (loader->thread != 0) + pthread_join(thread, NULL); + + assert(loader->pid < 0); + assert(loader->thread == 0); + + if (loader->result == LYRICS_SUCCESS && loader->data != NULL) + g_string_free(loader->data, TRUE); +} + +enum lyrics_loader_result +lyrics_result(struct lyrics_loader *loader) +{ + return loader->result; +} + +const GString * +lyrics_get(struct lyrics_loader *loader) +{ + /* sync with thread */ + pthread_mutex_lock(&loader->mutex); + pthread_mutex_unlock(&loader->mutex); + + assert(loader->result == LYRICS_SUCCESS); + assert(loader->pid < 0); + assert(loader->thread == 0); + assert(loader->data != NULL); + + return loader->data; +} diff --git a/src/lyrics.h b/src/lyrics.h new file mode 100644 index 000000000..34380c344 --- /dev/null +++ b/src/lyrics.h @@ -0,0 +1,48 @@ +/* ncmpc + * Copyright (C) 2008 Max Kellermann <max@duempel.org> + * This project's homepage is: http://www.musicpd.org + * + * 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 + */ + +#ifndef LYRICS_H +#define LYRICS_H + +#include <glib.h> + +enum lyrics_loader_result { + LYRICS_SUCCESS, + LYRICS_BUSY, + LYRICS_FAILED +}; + +struct lyrics_loader; + +void lyrics_init(void); + +void lyrics_deinit(void); + +struct lyrics_loader * +lyrics_load(const char *artist, const char *title); + +void +lyrics_free(struct lyrics_loader *loader); + +enum lyrics_loader_result +lyrics_result(struct lyrics_loader *loader); + +const GString * +lyrics_get(struct lyrics_loader *loader); + +#endif diff --git a/src/lyrics_hd.c b/src/lyrics_hd.c deleted file mode 100644 index e7acfc252..000000000 --- a/src/lyrics_hd.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "src_lyrics.h" - -#include <stdlib.h> -#include <unistd.h> - -char *check_lyr_hd(char *artist, char *title, int how) -{ //checking whether for lyrics file existence and proper access - result |= 2; - 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; - result |= 4; - 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 deleted file mode 100644 index 99dac9dde..000000000 --- a/src/lyrics_leoslyrics.c +++ /dev/null @@ -1,162 +0,0 @@ -#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 = strdup (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) - { - if (s[0] == 13 ) return; //ignore any single carriage returns - 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]; - CURL *curl = curl_easy_init (); - - - //this replacess the whitespaces with '+' - char *esc_title = curl_easy_escape (curl, title, 0); - char *esc_artist = curl_easy_escape (curl, artist, 0); - //we insert the artist and the title into the url - snprintf(url_avail, 512, LEOSLYRICS_SEARCH_URL, esc_artist, esc_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 - - char *esc_hid = curl_easy_escape (curl, hid, 0); - free (hid); - - snprintf(url, 512, LEOSLYRICS_CONTENT_URL, esc_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 52cbd4758..d54fd3717 100644 --- a/src/main.c +++ b/src/main.c @@ -25,7 +25,7 @@ #include "options.h" #include "conf.h" #include "command.h" -#include "src_lyrics.h" +#include "lyrics.h" #include "screen.h" #include "screen_utils.h" #include "strfsong.h" @@ -252,7 +252,7 @@ main(int argc, const char *argv[]) ncurses_init(); - src_lyr_init (); + lyrics_init(); /* connect to our music player daemon */ mpd = mpdclient_new(); diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c index 99487da33..2f63fb0ae 100644 --- a/src/screen_lyrics.c +++ b/src/screen_lyrics.c @@ -1,8 +1,6 @@ -/* - * $Id: screen_lyrics.c 3355 2006-09-1 17:44:04Z tradiaz $ - * +/* * (c) 2006 by Kalle Wallin <kaw@linux.se> - * Tue Aug 1 23:17:38 2006 + * Copyright (C) 2008 Max Kellermann <max@duempel.org> * * 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 @@ -28,9 +26,8 @@ #include "command.h" #include "screen.h" #include "screen_utils.h" -#include "easy_download.h" #include "strfsong.h" -#include "src_lyrics.h" +#include "lyrics.h" #include "gcc.h" #define _GNU_SOURCE @@ -38,160 +35,192 @@ #include <string.h> #include <glib.h> #include <ncurses.h> -#include <expat.h> #include <unistd.h> -#include <glib/gstdio.h> #include <stdio.h> static list_window_t *lw = NULL; static int lyrics_text_rows = -1; -static int src_selection; -static void lyrics_paint(screen_t *screen, mpdclient_t *c); +static struct { + const struct mpd_song *song; -static FILE *create_lyr_file(char *artist, char *title) -{ - char path[1024]; + char *artist, *title; - snprintf(path, 1024, "%s/.lyrics", - getenv("HOME")); - if(g_access(path, W_OK) != 0) if(mkdir(path, S_IRWXU) != 0) return NULL; + struct lyrics_loader *loader; - snprintf(path, 1024, "%s/.lyrics/%s", - getenv("HOME"), artist); - if(g_access(path, W_OK) != 0) if(mkdir(path, S_IRWXU) != 0) return NULL; + GPtrArray *lines; +} current; - snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", - getenv("HOME"), artist, title); +static void +screen_lyrics_abort(void) +{ + if (current.loader != NULL) { + lyrics_free(current.loader); + current.loader = NULL; + } - return fopen(path, "w"); + if (current.artist != NULL) { + g_free(current.artist); + current.artist = NULL; + } + + if (current.title != NULL) { + g_free(current.title); + current.artist = NULL; + } + + current.song = NULL; } +static void +screen_lyrics_clear(void) +{ + guint i; + + assert(current.loader == NULL || + lyrics_result(current.loader) == LYRICS_SUCCESS); -static int store_lyr_hd(void) + current.song = NULL; + + for (i = 0; i < current.lines->len; ++i) + g_free(g_ptr_array_index(current.lines, i)); + + g_ptr_array_set_size(current.lines, 0); +} + +static void +screen_lyrics_set(const GString *str) { - char artist[512]; - char title[512]; - static char path[1024]; - FILE *lyr_file; - unsigned i; - char line_buf[1024]; + const char *p, *eol, *next; - get_text_line(&lyr_text, 0, artist, 512); - get_text_line(&lyr_text, 1, title, 512); - artist[strlen(artist)-1] = '\0'; - title[strlen(title)-1] = '\0'; + screen_lyrics_clear(); - snprintf(path, 1024, "%s/.lyrics/%s/%s.lyric", - getenv("HOME"), artist, title); - lyr_file = create_lyr_file(artist, title); - if (lyr_file == NULL) - return -1; + p = str->str; + while ((eol = strchr(p, '\n')) != NULL) { + char *line; + + next = eol + 1; + + /* strip whitespace at end */ + + while (eol > p && (unsigned char)eol[-1] <= 0x20) + --eol; - for (i = 3; i <= lyr_text.text->len; i++) { - if (get_text_line(&lyr_text, i, line_buf, 1024) == -1) - break; - fputs(line_buf, lyr_file); + /* create copy and append it to current.lines*/ + + line = g_malloc(eol - p + 1); + memcpy(line, p, eol - p); + line[eol - p] = 0; + + g_ptr_array_add(current.lines, line); + + /* reset control characters */ + + for (eol = line + (eol - p); line < eol; ++line) + if ((unsigned char)*line < 0x20) + *line = ' '; + + p = next; } - fclose(lyr_file); - return 0; + if (*p != 0) + g_ptr_array_add(current.lines, g_strdup(p)); } +static int +screen_lyrics_poll(void) +{ + assert(current.loader != NULL); + + switch (lyrics_result(current.loader)) { + case LYRICS_BUSY: + return 0; + + case LYRICS_SUCCESS: + screen_lyrics_set(lyrics_get(current.loader)); + lyrics_free(current.loader); + current.loader = NULL; + return 1; + + case LYRICS_FAILED: + lyrics_free(current.loader); + current.loader = NULL; + screen_status_message (_("No lyrics")); + return -1; + } + + assert(0); + return -1; +} -static void check_repaint(void) +static void +screen_lyrics_load(struct mpd_song *song) { - if(screen_get_id("lyrics") == get_cur_mode_id())lyrics_paint(NULL, NULL); + char buffer[MAX_SONGNAME_LENGTH]; + + assert(song != NULL); + + screen_lyrics_abort(); + screen_lyrics_clear(); + + strfsong(buffer, sizeof(buffer), "%artist%", song); + current.artist = g_strdup(buffer); + + strfsong(buffer, sizeof(buffer), "%title%", song); + current.title = g_strdup(buffer); + + current.loader = lyrics_load(current.artist, current.title); } +static void lyrics_paint(screen_t *screen, mpdclient_t *c); -static gpointer get_lyr(void *c) +static FILE *create_lyr_file(const char *artist, const char *title) { - mpd_Status *status = ((retrieval_spec*)c)->client->status; - mpd_Song *cur = ((retrieval_spec*)c)->client->song; - char artist[MAX_SONGNAME_LENGTH]; - char title[MAX_SONGNAME_LENGTH]; - - //mpdclient_update((mpdclient_t*)c); + char path[1024]; - if(!(IS_PAUSED(status->state)||IS_PLAYING(status->state))) { - formed_text_init(&lyr_text); - return NULL; - } + snprintf(path, 1024, "%s/.lyrics", + getenv("HOME")); + mkdir(path, S_IRWXU); + snprintf(path, 1024, "%s/.lyrics/%s - %s.txt", + getenv("HOME"), artist, title); - lock=2; - result = 0; + return fopen(path, "w"); +} - formed_text_init(&lyr_text); +static int store_lyr_hd(void) +{ + FILE *lyr_file; + unsigned i; - strfsong(artist, MAX_SONGNAME_LENGTH, "%artist%", cur); - strfsong(title, MAX_SONGNAME_LENGTH, "%title%", cur); + lyr_file = create_lyr_file(current.artist, current.title); + if (lyr_file == NULL) + return -1; - //write header.. - formed_text_init(&lyr_text); - add_text_line(&lyr_text, artist, 0); - add_text_line(&lyr_text, title, 0); - add_text_line(&lyr_text, "", 0); - add_text_line(&lyr_text, "", 0); + for (i = 0; i < current.lines->len; ++i) + fprintf(lyr_file, "%s\n", + (const char*)g_ptr_array_index(current.lines, i)); - if (((retrieval_spec*)c)->way != -1) /*till it'S of use*/ { - if(get_lyr_by_src (src_selection, artist, title) != 0) { - lock=0; - return NULL; - } - } - /*else{ - if(get_lyr_hd(artist, title) != 0) - { - if(get_lyr_hd(artist, title) != 0) return NULL; - } - else result |= 1; - }*/ - //return NULL; - lw->start = 0; - check_repaint(); - lock = 1; - return &lyr_text; + fclose(lyr_file); + return 0; } static const char * -list_callback(unsigned idx, int *highlight, mpd_unused void *data) +list_callback(unsigned idx, mpd_unused int *highlight, mpd_unused void *data) { - static char buf[512]; - - //i think i'ts fine to write it into the 1st line... - if ((idx == lyr_text.lines->len && lyr_text.lines->len > 4) || - ((lyr_text.lines->len == 0 || lyr_text.lines->len == 4) && - idx == 0)) { - src_lyr* selected = g_array_index(src_lyr_stack, src_lyr*, src_selection); - *highlight=3; - if (selected != NULL) - return selected->description; + if (current.lines == NULL || idx >= current.lines->len) return ""; - } - - if (idx < 2 && lyr_text.lines->len > 4) - *highlight=3; - else if(idx >= lyr_text.lines->len || - (idx < 4 && idx != 0 && lyr_text.lines->len < 5)) { - return ""; - } - get_text_line(&lyr_text, idx, buf, 512); - return buf; + return g_ptr_array_index(current.lines, idx); } static void -lyrics_init(WINDOW *w, int cols, int rows) +lyrics_screen_init(WINDOW *w, int cols, int rows) { + current.lines = g_ptr_array_new(); lw = list_window_init(w, cols, rows); lw->flags = LW_HIDE_CURSOR; - //lyr_text.lines = g_array_new(FALSE, TRUE, 4); - formed_text_init(&lyr_text); - if (!g_thread_supported()) - g_thread_init(NULL); } static void @@ -205,46 +234,36 @@ static void lyrics_exit(void) { list_window_free(lw); -} + screen_lyrics_abort(); + screen_lyrics_clear(); -static const char * -lyrics_title(mpd_unused char *str, mpd_unused size_t size) -{ - 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 > (int)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"); - } + g_ptr_array_free(current.lines, TRUE); + current.lines = NULL; +} - if(lyr_text.lines->len == 4) { - if(lock == 1) { - if(!(result & 1)) { - g_string_append (msg, " - "); - if(!(result & 2)) g_string_append (msg, _("No access")); - else if(!(result & 4)||!(result & 16)) g_string_append (msg, _("Not found")); - } - } - if(lock == 2) { - g_string_append (msg, " - "); - g_string_append (msg, _("retrieving")); - } - } +static void +lyrics_open(mpd_unused screen_t *screen, mpdclient_t *c) +{ + if (c->song != NULL && c->song != current.song) + screen_lyrics_load(c->song); + else if (current.loader != NULL) + screen_lyrics_poll(); +} - g_string_append_c (msg, ']'); - return msg->str; +static const char * +lyrics_title(char *str, size_t size) +{ + if (current.loader != NULL) + return "Lyrics (loading)"; + else if (current.artist != NULL && current.title != NULL && + current.lines->len > 0) { + snprintf(str, size, "Lyrics: %s - %s", + current.artist, current.title); + return str; + } else + return "Lyrics"; } static void @@ -270,12 +289,10 @@ lyrics_update(mpd_unused screen_t *screen, mpd_unused mpdclient_t *c) static int lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd) { - static retrieval_spec spec; - lw->repaint=1; switch(cmd) { case CMD_LIST_NEXT: - if( lw->start+lw->rows < lyr_text.lines->len+1 ) + if (current.lines != NULL && lw->start+lw->rows < current.lines->len+1) lw->start++; return 1; case CMD_LIST_PREVIOUS: @@ -307,29 +324,29 @@ lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd) lw->start = 0; return 1; case CMD_SELECT: - spec.client = c; - spec.way = 0; - g_thread_create(get_lyr, &spec, FALSE, NULL); + /* XXX */ + if (current.loader != NULL) { + int ret = screen_lyrics_poll(); + if (ret != 0) + lyrics_paint(NULL, NULL); + } return 1; case CMD_INTERRUPT: - if(lock > 1) lock = 4; + if (current.loader != NULL) { + screen_lyrics_abort(); + screen_lyrics_clear(); + } return 1; case CMD_ADD: - if(lock > 0 && lock != 4) { - if(store_lyr_hd() == 0) - screen_status_message (_("Lyrics saved!")); - } + if (current.loader == NULL && current.artist != NULL && + current.title != NULL && store_lyr_hd() == 0) + screen_status_message (_("Lyrics saved!")); return 1; case CMD_LYRICS_UPDATE: - spec.client = c; - spec.way = 1; - g_thread_create(get_lyr, &spec, FALSE, NULL); - return 1; - case CMD_SEARCH_MODE: - //while (0==0) fprintf (stderr, "%i", src_lyr_stack->len); - if (src_selection == (int)src_lyr_stack->len - 1) - src_selection = -1; - src_selection++; + if (c->song != NULL) { + screen_lyrics_load(c->song); + lyrics_paint(NULL, NULL); + } return 1; default: break; @@ -365,9 +382,9 @@ get_screen_lyrics(void) static screen_functions_t functions; memset(&functions, 0, sizeof(screen_functions_t)); - functions.init = lyrics_init; + functions.init = lyrics_screen_init; functions.exit = lyrics_exit; - functions.open = NULL; + functions.open = lyrics_open; functions.close = NULL; functions.resize = lyrics_resize; functions.paint = lyrics_paint; diff --git a/src/src_lyrics.c b/src/src_lyrics.c deleted file mode 100644 index 21e6437be..000000000 --- a/src/src_lyrics.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * - * (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 <stdlib.h> -#include <unistd.h> -#include <string.h> - -#define PLUGIN_DIR_USER "/.ncmpc/plugins" - -int get_text_line(formed_text *text, unsigned num, char *dest, size_t len) -{ - int linelen; - - memset(dest, '\0', len*sizeof(char)); - if (num >= text->lines->len - 1) - return -1; - - 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 < 6 && 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 - -static int src_lyr_plugins_load(void); - -void src_lyr_stack_init(void) -{ - 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 src_lyr_init(void) -{ - int i = 0; - - src_lyr_stack_init (); - - 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(src_lyr_stack->len == 0) return -1; - g_array_index (src_lyr_stack, src_lyr*, priority)->get_lyr (artist, title); - return 0; -} - -static int src_lyr_load_plugin_file(const char *file) -{ - GString *path; - src_lyr *new_src; - src_lyr_plugin_register register_func; - - path = g_string_new (PLUGIN_DIR_SYSTEM); - g_string_append (path, "/"); - g_string_append (path, file); - - new_src = malloc(sizeof(src_lyr)); - new_src->module = g_module_open (path->str, G_MODULE_BIND_LAZY); - 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; -} - -static 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); - } -} - -static int src_lyr_plugins_load(void) -{ - GDir *plugin_dir; - GString *user_dir_path; - - plugin_dir = g_dir_open (PLUGIN_DIR_SYSTEM, 0, NULL); - if (plugin_dir == NULL) - return -1; - src_lyr_plugins_load_from_dir (plugin_dir); - - user_dir_path = g_string_new (g_get_home_dir()); - g_string_append (user_dir_path, PLUGIN_DIR_USER); - - plugin_dir = g_dir_open (user_dir_path->str, 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 deleted file mode 100644 index 98c695dac..000000000 --- a/src/src_lyrics.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef SOURCE_LYRICS -#define SOURCE_LYRICS - -#include "config.h" -#include "mpdclient.h" - -#include <sys/types.h> -#include <glib.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; - -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)(void); - - int (*check_lyr) (char *artist, char *title, char *url); - int (*get_lyr) (char *artist, char *title); - int (*state_lyr)(void); - -#ifndef DISABLE_PLUGIN_SYSTEM - GModule *module; -#endif -}; - -typedef int (*src_lyr_plugin_register) (src_lyr *source_descriptor); - -GArray *src_lyr_stack; - -int get_text_line(formed_text *text, unsigned num, char *dest, size_t len); - -void src_lyr_stack_init(void); -int src_lyr_init(void); -int get_lyr_by_src (int priority, char *artist, char *title); - -#endif |