add lyrics screen

This commit is contained in:
unknown
2008-08-15 20:31:36 +02:00
parent 8deaa0a9e3
commit ea3778da7c
11 changed files with 260 additions and 46 deletions

View File

@@ -11,28 +11,25 @@ AM_PROG_LIBTOOL
AC_ARG_ENABLE(unicode, AS_HELP_STRING([--enable-unicode], [Enable utf8 support]), [unicode=$enableval], [unicode=yes])
AC_ARG_WITH(taglib, AS_HELP_STRING([--with-taglib], [Enable tag editor]), [taglib=$withval], [taglib=no])
AC_ARG_WITH(curl, AS_HELP_STRING([--with-curl], [Enable fetching lyrics from the Internet]), [curl=$withval], [curl=no])
dnl ========================
dnl = checking for ncurses =
dnl ========================
if test "$unicode" = "yes" ; then
AC_PATH_PROG(NCURSESW5_CONFIG, ncursesw5-config)
if test "$NCURSESW5_CONFIG" != "" ; then
CPPFLAGS="$CPPFLAGS -DUTF8_ENABLED `$NCURSESW5_CONFIG --cflags`"
LDFLAGS="$LDFLAGS `$NCURSESW5_CONFIG --libs`"
AC_CHECK_LIB(ncursesw, initscr, , AC_MSG_ERROR([ncursesw library is required]))
else
AC_MSG_ERROR([ncursesw5-config executable is missing])
fi
ncurses_config_bin=ncursesw5-config
ncurses_lib=ncursesw
else
AC_PATH_PROG(NCURSES5_CONFIG, ncurses5-config)
if test "$NCURSES5_CONFIG" != "" ; then
CPPFLAGS="$CPPFLAGS `$NCURSES5_CONFIG --cflags`"
LDFLAGS="$LDFLAGS `$NCURSES5_CONFIG --libs`"
AC_CHECK_LIB(ncurses, initscr, , AC_MSG_ERROR([ncurses library is required]))
else
AC_MSG_ERROR([ncurses5-config executable is missing])
fi
ncurses_config_bin=ncurses5-config
ncurses_lib=ncurses
fi
AC_PATH_PROG(NCURSES_CONFIG, $ncurses_config_bin)
if test "$NCURSES_CONFIG" != "" ; then
CPPFLAGS="$CPPFLAGS -DUTF8_ENABLED `$NCURSES_CONFIG --cflags`"
LDFLAGS="$LDFLAGS `$NCURSES_CONFIG --libs`"
AC_CHECK_LIB($ncurses_lib, initscr, , AC_MSG_ERROR([$ncurses_lib library is required]))
else
AC_MSG_ERROR([$ncurses_config_bin executable is missing])
fi
AC_CHECK_HEADERS([ncurses.h], , AC_MSG_ERROR([missing ncurses.h header]))
@@ -46,6 +43,20 @@ CPPFLAGS="$CPPFLAGS $libmpd_CFLAGS"
LDFLAGS="$LDFLAGS $libmpd_LIBS"
AC_CHECK_HEADERS([libmpd/libmpd.h], , AC_MSG_ERROR([missing libmpd.h header]))
dnl =====================
dnl = checking for curl =
dnl =====================
if test "$curl" = "yes" ; then
AC_PATH_PROG(CURL_CONFIG, curl-config)
if test "$CURL_CONFIG" != "" ; then
CPPFLAGS="$CPPFLAGS `$CURL_CONFIG --cflags`"
AC_CHECK_LIB(curl, curl_easy_init, LDFLAGS="$LDFLAGS `$CURL_CONFIG --libs`", AC_MSG_ERROR([curl library is required]))
AC_CHECK_HEADERS([curl/curl.h], , AC_MSG_ERROR([missing curl.h header]))
else
AC_MSG_ERROR([curl-config executable is missing])
fi
fi
dnl =======================
dnl = checking for taglib =
dnl =======================

View File

@@ -1,11 +1,11 @@
bin_PROGRAMS = ncmpcpp
ncmpcpp_SOURCES = color_parser.cpp helpers.cpp menu.cpp misc.cpp ncmpcpp.cpp \
scrollpad.cpp settings.cpp song.cpp status_checker.cpp window.cpp
ncmpcpp_SOURCES = color_parser.cpp helpers.cpp lyrics.cpp menu.cpp misc.cpp \
ncmpcpp.cpp scrollpad.cpp settings.cpp song.cpp status_checker.cpp window.cpp
# set the include path found by configure
INCLUDES= $(all_includes)
# the library search path.
ncmpcpp_LDFLAGS = $(all_libraries)
noinst_HEADERS = helpers.h menu.h scrollpad.h settings.h song.h \
noinst_HEADERS = helpers.h lyrics.h menu.h scrollpad.h settings.h song.h \
status_checker.h window.h

View File

@@ -37,7 +37,7 @@ extern Window *wFooter;
extern vector<Song *> vPlaylist;
extern vector<BrowsedItem> vBrowser;
extern CurrScreen current_screen;
extern NcmpcppScreen current_screen;
extern Song edited_song;
extern Song searched_song;

107
src/lyrics.cpp Normal file
View File

@@ -0,0 +1,107 @@
/***************************************************************************
* Copyright (C) 2008 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* 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"
const string lyrics_folder = home_folder + "/" + ".lyrics";
const string mkdir_command = "mkdir " + lyrics_folder + " &>/dev/null";
size_t write_data(char *buffer, size_t size, size_t nmemb, string data)
{
int result = 0;
if (buffer)
{
data += buffer;
result = size*nmemb;
}
return result;
}
string GetLyrics(string artist, string song)
{
const string filename = artist + " - " + song + ".txt";
const string fullpath = lyrics_folder + "/" + filename;
system(mkdir_command.c_str());
string result;
std::ifstream input(fullpath.c_str());
if (input.is_open())
{
string line;
while (getline(input, line))
result += line + "\n";
return result;
}
# ifdef HAVE_CURL_CURL_H
for (string::iterator it = artist.begin(); it != artist.end(); it++)
if (*it == ' ')
*it = '+';
for (string::iterator it = song.begin(); it != song.end(); it++)
if (*it == ' ')
*it = '+';
CURLcode code;
string url = "http://lyricwiki.org/api.php?artist=" + artist + "&song=" + song + "&fmt=xml";
CURL *lyrics = curl_easy_init();
curl_easy_setopt(lyrics, CURLOPT_URL, url.c_str());
curl_easy_setopt(lyrics, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(lyrics, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(lyrics, CURLOPT_CONNECTTIMEOUT, 30);
code = curl_easy_perform(lyrics);
curl_easy_cleanup(lyrics);
if (code != CURLE_OK)
{
result = "Error while fetching lyrics: " + string(curl_easy_strerror(code));
return result;
}
int a, b;
a = result.find("<lyrics>")+8;
b = result.find("</lyrics>");
result = result.substr(a, b-a);
if (result == "Not found")
return result;
for (int i = result.find("&#039;"); i != string::npos; i = result.find("&#039;"))
result.replace(i, 6, "'");
for (int i = result.find("&quot;"); i != string::npos; i = result.find("&quot;"))
result.replace(i, 6, "\"");
std::ofstream output(fullpath.c_str());
if (output.is_open())
{
output << result;
output.close();
}
# else
result = "Local lyrics not found. As ncmpcpp has been compiled without curl support, you can put appropriate lyrics into ~/.lyrics directory (file syntax is \"ARTIST - TITLE.txt\") or recompile ncmpcpp with curl support.";
# endif
return result + '\n';
}

34
src/lyrics.h Normal file
View File

@@ -0,0 +1,34 @@
/***************************************************************************
* Copyright (C) 2008 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* 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 HAVE_LYRICS_H
#define HAVE_LYRICS_H
#include "ncmpcpp.h"
#include <fstream>
#ifdef HAVE_CURL_CURL_H
# include <curl/curl.h>
#endif
string GetLyrics(string, string);
#endif

View File

@@ -23,6 +23,7 @@
#include "helpers.h"
#include "settings.h"
#include "song.h"
#include "lyrics.h"
#define FOR_EACH_MPD_DATA(x) for (; (x); (x) = mpd_data_get_next(x))
@@ -43,6 +44,13 @@
block_progressbar_update = 0; \
}
#define REFRESH_MEDIA_LIBRARY_SCREEN \
mLibArtists->Display(redraw_me); \
mvvline(main_start_y, lib_albums_start_x-1, 0, main_height); \
mLibAlbums->Display(redraw_me); \
mvvline(main_start_y, lib_songs_start_x-1, 0, main_height); \
mLibSongs->Display(redraw_me)
#ifdef HAVE_TAGLIB_H
const string tag_screen = "Tag editor";
const string tag_screen_keydesc = "\tE e : Edit song's tags\n";
@@ -77,6 +85,7 @@ Menu *mLibArtists;
Menu *mLibAlbums;
Menu *mLibSongs;
Scrollpad *sHelp;
Scrollpad *sLyrics;
Window *wHeader;
Window *wFooter;
@@ -107,8 +116,8 @@ string mpd_random;
string mpd_crossfade;
string mpd_db_updating;
CurrScreen current_screen;
CurrScreen prev_screen;
NcmpcppScreen current_screen;
NcmpcppScreen prev_screen;
Song edited_song;
Song searched_song;
@@ -189,6 +198,7 @@ int main(int argc, char *argv[])
mLibSongs = new Menu(lib_songs_start_x, main_start_y, lib_songs_width, main_height, "Songs", Config.main_color, brNone);
sHelp = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
sLyrics = new Scrollpad(sHelp->EmptyClone());
sHelp->Add(" [b]Keys - Movement\n -----------------------------------------[/b]\n");
sHelp->Add("\tUp : Move Cursor up\n");
@@ -224,7 +234,8 @@ int main(int argc, char *argv[])
sHelp->Add("\t? : Backward find\n");
sHelp->Add("\t. : Go to next/previous found position\n");
sHelp->Add(tag_screen_keydesc);
sHelp->Add("\tg : Go to chosen position in current song\n\n");
sHelp->Add("\tg : Go to chosen position in current song\n");
sHelp->Add("\tl : Show/hide song's lyrics\n\n");
sHelp->Add("\tQ q : Quit\n\n\n");
@@ -292,6 +303,7 @@ int main(int argc, char *argv[])
mLibArtists->Timeout(ncmpcpp_window_timeout);
mLibAlbums->Timeout(ncmpcpp_window_timeout);
mLibSongs->Timeout(ncmpcpp_window_timeout);
sLyrics->Timeout(ncmpcpp_window_timeout);
wFooter->Timeout(ncmpcpp_window_timeout);
while (!main_exit)
@@ -326,6 +338,9 @@ int main(int argc, char *argv[])
case csLibrary:
title = "Media library";
break;
case csLyrics:
title = "Lyrics";
break;
}
if (title_allowed)
@@ -523,6 +538,8 @@ int main(int argc, char *argv[])
mBrowser->Resize(COLS, main_height);
mTagEditor->Resize(COLS, main_height);
mSearcher->Resize(COLS, main_height);
sLyrics->Resize(COLS, main_height);
sLyrics->Timeout(ncmpcpp_window_timeout);
lib_artist_width = COLS/3-1;
lib_albums_start_x = lib_artist_width+1;
@@ -550,13 +567,9 @@ int main(int argc, char *argv[])
if (current_screen == csLibrary)
{
mLibArtists->Hide();
mLibArtists->Display(redraw_me);
mvvline(main_start_y, lib_albums_start_x-1, 0, main_height);
mLibAlbums->Hide();
mLibAlbums->Display(redraw_me);
mvvline(main_start_y, lib_songs_start_x-1, 0, main_height);
mLibSongs->Hide();
mLibSongs->Display(redraw_me);
REFRESH_MEDIA_LIBRARY_SCREEN;
}
header_update_status = 1;
@@ -786,11 +799,7 @@ int main(int argc, char *argv[])
# else
wCurrent = wPrev;
# endif
mLibArtists->Display(redraw_me);
mvvline(main_start_y, lib_albums_start_x-1, 0, main_height);
mLibAlbums->Display(redraw_me);
mvvline(main_start_y, lib_songs_start_x-1, 0, main_height);
mLibSongs->Display(redraw_me);
REFRESH_MEDIA_LIBRARY_SCREEN;
}
# ifdef HAVE_TAGLIB_H
break;
@@ -1599,6 +1608,60 @@ int main(int argc, char *argv[])
}
break;
}
case 'l': // show lyrics
{
if (wCurrent == sLyrics)
{
wCurrent->Hide();
current_screen = prev_screen;
wCurrent = wPrev;
redraw_me = 1;
if (current_screen == csLibrary)
{
REFRESH_MEDIA_LIBRARY_SCREEN;
}
break;
}
if ((wCurrent == mPlaylist && !vPlaylist.empty())
|| (wCurrent == mBrowser && vBrowser[mBrowser->GetChoice()-1].type == MPD_DATA_TYPE_SONG)
|| (wCurrent == mSearcher && !vSearched.empty() && mSearcher->GetChoice() > search_engine_static_option)
|| (wCurrent == mLibSongs))
{
Song s;
switch (current_screen)
{
case csPlaylist:
s = *vPlaylist[mPlaylist->GetChoice()-1];
break;
case csBrowser:
s = mpd_database_get_fileinfo(conn, vBrowser[mBrowser->GetChoice()-1].name.c_str());
break;
case csSearcher:
s = vSearched[mSearcher->GetChoice()-search_engine_static_option-1];
break;
case csLibrary:
s = vSongs[mLibSongs->GetChoice()-1];
break;
}
if (s.GetArtist() != UNKNOWN_ARTIST && s.GetTitle() != UNKNOWN_TITLE)
{
wPrev = wCurrent;
prev_screen = current_screen;
wCurrent = sLyrics;
wCurrent->Hide();
wCurrent->Clear();
current_screen = csLyrics;
sLyrics->WriteXY(0, 0, "Fetching lyrics...");
sLyrics->Refresh();
sLyrics->Add("[b]" + s.GetArtist() + " - " + s.GetTitle() + "[/b]\n\n");
sLyrics->Add(GetLyrics(s.GetArtist(), s.GetTitle()));
sLyrics->Timeout(ncmpcpp_window_timeout);
}
}
break;
}
case '1': // help screen
{
if (wCurrent != sHelp)
@@ -1606,7 +1669,6 @@ int main(int argc, char *argv[])
wCurrent = sHelp;
wCurrent->Hide();
current_screen = csHelp;
redraw_me = 1;
}
break;
}
@@ -1722,11 +1784,7 @@ int main(int argc, char *argv[])
wCurrent->Hide();
mLibArtists->Display();
mvvline(main_start_y, lib_albums_start_x-1, 0, main_height);
mLibAlbums->Display();
mvvline(main_start_y, lib_songs_start_x-1, 0, main_height);
mLibSongs->Display();
REFRESH_MEDIA_LIBRARY_SCREEN;
wCurrent = mLibArtists;
current_screen = csLibrary;

View File

@@ -55,11 +55,12 @@ const bool UNICODE = 0;
#include "scrollpad.h"
#include "misc.h"
enum CurrScreen { csHelp, csPlaylist, csBrowser, csTagEditor, csSearcher, csLibrary };
enum NcmpcppScreen { csHelp, csPlaylist, csBrowser, csTagEditor, csSearcher, csLibrary, csLyrics };
const int ncmpcpp_window_timeout = 500;
const int search_engine_static_option = 17;
const string home_folder = getenv("HOME");
const string TERMINAL_TYPE = getenv("TERM");
const string search_mode_one = "Match if tag contains searched phrase";

View File

@@ -22,7 +22,7 @@
void Scrollpad::Add(string str)
{
if (itsXPos > 0 && str[0] != ' ')
if (itsXPos > 0 && (str[0] != ' ' || str[0] != '\n'))
str = " " + str;
itsRawContent += str;
@@ -39,8 +39,13 @@ void Scrollpad::Add(string str)
int space_pos = 0;
bool collect = 0;
for (size_t i = 0; i <= s.length(); i++, itsXPos++)
for (size_t i = 0; i < s.length(); i++)
{
if (s[i] != '\t')
itsXPos++;
else
itsXPos += 8;
if (BBEnabled)
{
if (s[i] == '[')

View File

@@ -26,7 +26,7 @@
class Scrollpad: public Window
{
public:
Scrollpad(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsBeginning(0), itsRealHeight(1), itsXPos(0) { delwin(itsWindow); itsWindow = newpad(0,0); }
Scrollpad(int startx, int starty, int width, int height, string title, COLOR color, BORDER border) : Window(startx, starty, width, height, title, color, border), itsBeginning(0), itsRealHeight(1), itsXPos(0) { delwin(itsWindow); itsWindow = newpad(itsHeight,itsWidth); }
virtual ~Scrollpad() {}
virtual void Add(string);
virtual void Display(bool = 0);

View File

@@ -25,8 +25,6 @@
#include "ncmpcpp.h"
const string home_folder = getenv("HOME");
struct ncmpcpp_config
{
string mpd_music_dir;

View File

@@ -65,7 +65,7 @@ extern string mpd_random;
extern string mpd_crossfade;
extern string mpd_db_updating;
extern CurrScreen current_screen;
extern NcmpcppScreen current_screen;
extern bool header_update_status;