diff --git a/src/browser.cpp b/src/browser.cpp index 54552a21..0624d98f 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -76,7 +76,7 @@ void Browser::SwitchTo() std::string Browser::Title() { string result = "Browse: "; - result += TO_STRING(Scroller(itsBrowsedDir, COLS-volume_state.length(), itsScrollBeginning)); + result += TO_STRING(Scroller(itsBrowsedDir, COLS-result.length()-volume_state.length(), itsScrollBeginning)); return result; } diff --git a/src/global.h b/src/global.h index 86e66d76..1dcb0e65 100644 --- a/src/global.h +++ b/src/global.h @@ -59,7 +59,7 @@ namespace Global // extern Menu *myPlaylistEditor->Content; // extern Scrollpad *sHelp; - extern Scrollpad *sLyrics; +// extern Scrollpad *sLyrics; extern Scrollpad *sInfo; extern Window *wHeader; @@ -76,7 +76,7 @@ namespace Global // extern size_t browsed_dir_scroll_begin; extern size_t main_start_y; extern size_t main_height; - extern size_t lyrics_scroll_begin; +// extern size_t lyrics_scroll_begin; extern time_t timer; @@ -99,7 +99,7 @@ namespace Global extern bool messages_allowed; extern bool redraw_header; - extern bool reload_lyrics; +// extern bool reload_lyrics; extern std::string volume_state; @@ -117,7 +117,7 @@ namespace Global extern std::vector vFoundPositions; extern int found_pos; - extern MPD::Song lyrics_song; +// extern MPD::Song lyrics_song; } #endif diff --git a/src/lyrics.cpp b/src/lyrics.cpp index c7afd84d..cb6f173e 100644 --- a/src/lyrics.cpp +++ b/src/lyrics.cpp @@ -21,11 +21,13 @@ #include #include +#include "lyrics.h" + #include "browser.h" #include "charset.h" #include "global.h" #include "helpers.h" -#include "lyrics.h" + #include "media_library.h" #include "playlist.h" #include "playlist_editor.h" @@ -39,52 +41,50 @@ using namespace Global; using std::vector; using std::string; -Scrollpad *Global::sLyrics; +const std::string Lyrics::Folder = home_folder + "/.lyrics"; -MPD::Song Global::lyrics_song; - -const string lyrics_folder = home_folder + "/.lyrics"; +bool Lyrics::Reload = 0; #ifdef HAVE_CURL_CURL_H pthread_mutex_t Global::curl = PTHREAD_MUTEX_INITIALIZER; + +bool Lyrics::Ready = 0; +pthread_t Lyrics::Downloader = 0; #endif -namespace -{ -# ifdef HAVE_CURL_CURL_H - pthread_t lyrics_downloader; - bool lyrics_ready; -# endif - - void *GetLyrics(void *); -} +Lyrics *myLyrics = new Lyrics; void Lyrics::Init() { - sLyrics = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); - sLyrics->SetTimeout(ncmpcpp_window_timeout); + w = new Scrollpad(0, main_start_y, COLS, main_height, "", Config.main_color, brNone); + w->SetTimeout(ncmpcpp_window_timeout); } void Lyrics::Resize() { - sLyrics->Resize(COLS, main_height); + w->Resize(COLS, main_height); } void Lyrics::Update() { - if (!reload_lyrics) +# ifdef HAVE_CURL_CURL_H + if (myLyrics->Ready) + myLyrics->Take(); +# endif // HAVE_CURL_CURL_H + + if (!Reload) return; const MPD::Song &s = myPlaylist->NowPlayingSong(); if (!s.GetArtist().empty() && !s.GetTitle().empty()) - Get(); + SwitchTo(); else - reload_lyrics = 0; + Reload = 0; } -void Lyrics::Get() +void Lyrics::SwitchTo() { - if (wCurrent == sLyrics && !reload_lyrics) + if (wCurrent == w && !Reload) { wCurrent->Hide(); current_screen = prev_screen; @@ -107,7 +107,7 @@ void Lyrics::Get() # endif // HAVE_TAGLIB_H } else if ( - reload_lyrics + Reload || (wCurrent == myPlaylist->Main() && !myPlaylist->Main()->Empty()) || (wCurrent == myBrowser->Main() && myBrowser->Main()->Current().type == MPD::itSong) || (wCurrent == mySearcher->Main() && !mySearcher->Main()->Current().first) @@ -119,21 +119,26 @@ void Lyrics::Get() ) { # ifdef HAVE_CURL_CURL_H - if (lyrics_downloader) + if (Downloader && !Ready) { ShowMessage("Lyrics are being downloaded..."); return; } + else if (Ready) + { + Take(); + return; + } # endif MPD::Song *s = 0; int id; - if (reload_lyrics) + if (Reload) { current_screen = csPlaylist; wCurrent = myPlaylist->Main(); - reload_lyrics = 0; + Reload = 0; id = myPlaylist->NowPlaying; } else @@ -166,104 +171,37 @@ void Lyrics::Get() } if (!s->GetArtist().empty() && !s->GetTitle().empty()) { - lyrics_scroll_begin = 0; - lyrics_song = *s; + itsScrollBegin = 0; + itsSong = *s; wPrev = wCurrent; prev_screen = current_screen; - wCurrent = sLyrics; + wCurrent = w; current_screen = csLyrics; redraw_header = 1; - sLyrics->Clear(); - sLyrics->WriteXY(0, 0, 0, "Fetching lyrics..."); - sLyrics->Refresh(); + w->Clear(); + w->WriteXY(0, 0, 0, "Fetching lyrics..."); + w->Refresh(); # ifdef HAVE_CURL_CURL_H - if (!lyrics_downloader) + if (!Downloader) { - pthread_create(&lyrics_downloader, NULL, GetLyrics, s); + pthread_create(&Downloader, NULL, Get, &itsSong); } # else - GetLyrics(s); - sLyrics->Flush(); + Get(s); + w->Flush(); # endif } } } -#ifdef HAVE_CURL_CURL_H -bool Lyrics::Ready() +std::string Lyrics::Title() { - if (!lyrics_ready) - return false; - pthread_join(lyrics_downloader, NULL); - sLyrics->Flush(); - lyrics_downloader = 0; - lyrics_ready = 0; - return true; + string result = "Lyrics: "; + result += TO_STRING(Scroller(itsSong.toString("%a - %t"), COLS-result.length()-volume_state.length(), itsScrollBegin)); + return result; } -namespace -{ - bool lyricwiki_not_found(const string &s) - { - return s == "Not found"; - } - - bool lyricsplugin_not_found(const string &s) - { - if (s.empty()) - return true; - for (string::const_iterator it = s.begin(); it != s.end(); it++) - if (isprint(*it)) - return false; - return true; - } - - const LyricsPlugin lyricwiki = - { - "http://lyricwiki.org/api.php?artist=%artist%&song=%title%&fmt=xml", - "", - "", - lyricwiki_not_found - }; - - const LyricsPlugin lyricsplugin = - { - "http://www.lyricsplugin.com/winamp03/plugin/?artist=%artist%&title=%title%", - "
", - "
", - lyricsplugin_not_found - }; - - const char *lyricsplugins_list[] = - { - "lyricwiki.org", - "lyricsplugin.com", - 0 - }; - - const LyricsPlugin *ChooseLyricsPlugin(int i) - { - switch (i) - { - case 0: - return &lyricwiki; - case 1: - return &lyricsplugin; - default: - return &lyricwiki; - } - } -} - -const char *GetLyricsPluginName(int offset) -{ - return lyricsplugins_list[offset]; -} - -#endif // HAVE_CURL_CURL_H - -namespace { -void *GetLyrics(void *song) +void *Lyrics::Get(void *song) { string artist = static_cast(song)->GetArtist(); string title = static_cast(song)->GetTitle(); @@ -273,9 +211,9 @@ void *GetLyrics(void *song) string filename = artist + " - " + title + ".txt"; EscapeUnallowedChars(filename); - const string fullpath = lyrics_folder + "/" + filename; + const string fullpath = Folder + "/" + filename; - mkdir(lyrics_folder.c_str(), 0755); + mkdir(Folder.c_str(), 0755); std::ifstream input(fullpath.c_str()); @@ -286,20 +224,20 @@ void *GetLyrics(void *song) while (getline(input, line)) { if (!first) - *sLyrics << "\n"; + *myLyrics->Main() << "\n"; utf_to_locale(line); - *sLyrics << line; + *myLyrics->Main() << line; first = 0; } # ifdef HAVE_CURL_CURL_H - lyrics_ready = 1; + Ready = 1; pthread_exit(NULL); # endif } # ifdef HAVE_CURL_CURL_H CURLcode code; - const LyricsPlugin *my_lyrics = ChooseLyricsPlugin(Config.lyrics_db); + const Plugin *my_lyrics = ChoosePlugin(Config.lyrics_db); string result; @@ -326,8 +264,8 @@ void *GetLyrics(void *song) if (code != CURLE_OK) { - *sLyrics << "Error while fetching lyrics: " << curl_easy_strerror(code); - lyrics_ready = 1; + *myLyrics->Main() << "Error while fetching lyrics: " << curl_easy_strerror(code); + Ready = 1; pthread_exit(NULL); } @@ -338,8 +276,8 @@ void *GetLyrics(void *song) if (my_lyrics->not_found(result)) { - *sLyrics << "Not found"; - lyrics_ready = 1; + *myLyrics->Main() << "Not found"; + Ready = 1; pthread_exit(NULL); } @@ -351,7 +289,7 @@ void *GetLyrics(void *song) EscapeHtml(result); Trim(result); - *sLyrics << utf_to_locale_cpy(result); + *myLyrics->Main() << utf_to_locale_cpy(result); std::ofstream output(fullpath.c_str()); if (output.is_open()) @@ -359,12 +297,82 @@ void *GetLyrics(void *song) output << result; output.close(); } - lyrics_ready = 1; + Ready = 1; pthread_exit(NULL); # else else - *sLyrics << "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."; + *myLyrics->Main() << "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."; return NULL; # endif } + +#ifdef HAVE_CURL_CURL_H + +void Lyrics::Take() +{ + if (!Ready) + return; + pthread_join(Downloader, NULL); + w->Flush(); + Downloader = 0; + Ready = 0; } + +const char *Lyrics::GetPluginName(int offset) +{ + return PluginsList[offset]; +} + +bool Lyrics::LyricWiki_NotFound(const string &s) +{ + return s == "Not found"; +} + +bool Lyrics::LyricsPlugin_NotFound(const string &s) +{ + if (s.empty()) + return true; + for (string::const_iterator it = s.begin(); it != s.end(); it++) + if (isprint(*it)) + return false; + return true; +} + +const Lyrics::Plugin Lyrics::LyricWiki = +{ + "http://lyricwiki.org/api.php?artist=%artist%&song=%title%&fmt=xml", + "", + "", + LyricWiki_NotFound +}; + +const Lyrics::Plugin Lyrics::LyricsPlugin = +{ + "http://www.lyricsplugin.com/winamp03/plugin/?artist=%artist%&title=%title%", + "
", + "
", + LyricsPlugin_NotFound +}; + +const char *Lyrics::PluginsList[] = +{ + "lyricwiki.org", + "lyricsplugin.com", + 0 +}; + +const Lyrics::Plugin *Lyrics::ChoosePlugin(int i) +{ + switch (i) + { + case 0: + return &LyricWiki; + case 1: + return &LyricsPlugin; + default: + return &LyricWiki; + } +} + +#endif // HAVE_CURL_CURL_H + diff --git a/src/lyrics.h b/src/lyrics.h index 51855de5..f021e82f 100644 --- a/src/lyrics.h +++ b/src/lyrics.h @@ -22,34 +22,67 @@ #define _LYRICS_H #include "ncmpcpp.h" - -namespace Lyrics -{ - void Init(); - void Resize(); - void Update(); - - void Get(); -# ifdef HAVE_CURL_CURL_H - bool Ready(); -# endif // HAVE_CURL_CURL_H -} +#include "mpdpp.h" +#include "screen.h" #ifdef HAVE_CURL_CURL_H # include # include "curl/curl.h" +#endif -struct LyricsPlugin +class Lyrics : public Screen { - const char *url; - const char *tag_open; - const char *tag_close; - bool (*not_found)(const std::string &); + struct Plugin + { + const char *url; + const char *tag_open; + const char *tag_close; + bool (*not_found)(const std::string &); + }; + + public: + Lyrics() : itsScrollBegin(0) { } + ~Lyrics() { } + + virtual void Init(); + virtual void Resize(); + virtual void SwitchTo(); + + virtual std::string Title(); + + virtual void Update(); + + static bool Reload; + +# ifdef HAVE_CURL_CURL_H + static const char *GetPluginName(int offset); +# endif // HAVE_CURL_CURL_H + + protected: + static void *Get(void *); + + static const std::string Folder; + +# ifdef HAVE_CURL_CURL_H + void Take(); + + static const Plugin *ChoosePlugin(int); + static bool LyricWiki_NotFound(const std::string &); + static bool LyricsPlugin_NotFound(const std::string &); + + static bool Ready; + static pthread_t Downloader; + + static const char *PluginsList[]; + static const Plugin LyricWiki; + static const Plugin LyricsPlugin; +# endif // HAVE_CURL_CURL_H + + size_t itsScrollBegin; + MPD::Song itsSong; }; -const char *GetLyricsPluginName(int); - -#endif // HAVE_CURL_CURL_H +extern Lyrics *myLyrics; #endif diff --git a/src/ncmpcpp.cpp b/src/ncmpcpp.cpp index 1c6972b3..5991ca72 100644 --- a/src/ncmpcpp.cpp +++ b/src/ncmpcpp.cpp @@ -75,7 +75,7 @@ int Global::lock_statusbar_delay = -1; size_t Global::main_start_y; size_t Global::main_height; -size_t Global::lyrics_scroll_begin = 0; +//size_t Global::lyrics_scroll_begin = 0; time_t Global::timer; @@ -93,7 +93,6 @@ bool Global::block_item_list_update = 0; bool Global::messages_allowed = 0; bool Global::redraw_header = 1; -bool Global::reload_lyrics = 0; vector Global::vFoundPositions; int Global::found_pos = 0; @@ -164,7 +163,7 @@ int main(int argc, char *argv[]) myHelp->Init(); Info::Init(); - Lyrics::Init(); + myLyrics->Init(); if (Config.header_visibility) { @@ -259,7 +258,7 @@ int main(int argc, char *argv[]) screen_title = myLibrary->Title(); break; case csLyrics: - screen_title = "Lyrics: "; + screen_title = myLyrics->Title(); break; case csPlaylistEditor: screen_title = myPlaylistEditor->Title(); @@ -278,14 +277,6 @@ int main(int argc, char *argv[]) wHeader->Bold(1); wHeader->WriteXY(0, 0, 1, "%s", screen_title.c_str()); wHeader->Bold(0); - - if (current_screen == csLyrics) - { - - wHeader->Bold(1); - *wHeader << Scroller(lyrics_song.toString("%a - %t"), max_allowed_title_length, lyrics_scroll_begin); - wHeader->Bold(0); - } } else { @@ -340,11 +331,10 @@ int main(int argc, char *argv[]) # endif if (current_screen == csLyrics) { - Lyrics::Update(); + myLyrics->Update(); } # ifdef HAVE_CURL_CURL_H - if (!Info::Ready()) - Lyrics::Ready(); + Info::Ready(); # endif wCurrent->Display(); @@ -510,7 +500,7 @@ int main(int argc, char *argv[]) myLibrary->Resize(); myPlaylistEditor->Resize(); Info::Resize(); - Lyrics::Resize(); + myLyrics->Resize(); # ifdef HAVE_TAGLIB_H myTinyTagEditor->Resize(); @@ -1187,10 +1177,10 @@ int main(int argc, char *argv[]) # ifdef HAVE_CURL_CURL_H else if (Keypressed(input, Key.ToggleLyricsDB)) { - const char *current_lyrics_plugin = GetLyricsPluginName(++Config.lyrics_db); + const char *current_lyrics_plugin = Lyrics::GetPluginName(++Config.lyrics_db); if (!current_lyrics_plugin) { - current_lyrics_plugin = GetLyricsPluginName(Config.lyrics_db = 0); + current_lyrics_plugin = Lyrics::GetPluginName(Config.lyrics_db = 0); } ShowMessage("Using lyrics database: %s", current_lyrics_plugin); } @@ -2016,7 +2006,7 @@ int main(int argc, char *argv[]) # endif // HAVE_CURL_CURL_H else if (Keypressed(input, Key.Lyrics)) { - Lyrics::Get(); + myLyrics->SwitchTo(); } else if (Keypressed(input, Key.Help)) { diff --git a/src/status_checker.cpp b/src/status_checker.cpp index 7e780d9f..8865e814 100644 --- a/src/status_checker.cpp +++ b/src/status_checker.cpp @@ -25,6 +25,7 @@ #include "charset.h" #include "global.h" #include "helpers.h" +#include "lyrics.h" #include "media_library.h" #include "playlist.h" #include "playlist_editor.h" @@ -317,7 +318,7 @@ void NcmpcppStatusChanged(Connection *Mpd, StatusChanges changed, void *) mvwhline(wFooter->Raw(), 0, 0, 0, wFooter->GetWidth()); if (Config.now_playing_lyrics && !Config.repeat_one_mode && current_screen == csLyrics && prev_screen == csPlaylist) - reload_lyrics = 1; + Lyrics::Reload = 1; } playing_song_scroll_begin = 0;