void Lyrics::DownloadInBackground(const MPD::Song &s) { if (s.empty() || s.getArtist().empty() || s.getTitle().empty()) return; std::string filename = GenerateFilename(s); std::ifstream f(filename.c_str()); if (f.is_open()) { f.close(); return; } Statusbar::msg("Fetching lyrics for \"%s\"...", s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str()); MPD::Song *s_copy = new MPD::Song(s); pthread_mutex_lock(&itsDIBLock); if (itsWorkersNumber == itsMaxWorkersNumber) itsToDownload.push(s_copy); else { ++itsWorkersNumber; pthread_t t; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&t, &attr, DownloadInBackgroundImpl, s_copy); } pthread_mutex_unlock(&itsDIBLock); }
bool addSongToPlaylist(const MPD::Song &s, bool play, size_t position) { bool result = false; if (Config.ncmpc_like_songs_adding && myPlaylist->checkForSong(s)) { auto &w = myPlaylist->main(); if (play) { auto song = std::find(w.beginV(), w.endV(), s); assert(song != w.endV()); Mpd.PlayID(song->getID()); result = true; } else { Mpd.StartCommandsList(); for (auto it = w.rbeginV(); it != w.rendV(); ++it) if (*it == s) Mpd.Delete(it->getPosition()); Mpd.CommitCommandsList(); // we return false in this case } } else { position = std::min(position, Mpd.GetPlaylistLength()); int id = Mpd.AddSong(s, position); if (id >= 0) { Statusbar::msg("Added to playlist: %s", s.toString(Config.song_status_format_no_colors, Config.tags_separator).c_str() ); if (play) Mpd.PlayID(id); result = true; } } return result; }
void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu) { if (!s.Localized()) const_cast<MPD::Song *>(&s)->Localize(); bool is_now_playing = menu == myPlaylist->Items && (menu->isFiltered() ? s.GetPosition() : menu->CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying); if (is_now_playing) *menu << Config.now_playing_prefix; assert(data); bool separate_albums = false; if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size()) { MPD::Song *next = static_cast<ScreenFormat *>(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1); if (next && next->GetAlbum() != s.GetAlbum()) separate_albums = true; } if (separate_albums) { *menu << fmtUnderline; mvwhline(menu->Raw(), menu->Y(), 0, ' ', menu->GetWidth()); } bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition()); std::string line = s.toString(*static_cast<ScreenFormat *>(data)->format, "$"); for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) { if (*it == '$') { if (++it == line.end()) // end of format { *menu << '$'; break; } else if (isdigit(*it)) // color { if (!discard_colors) *menu << Color(*it-'0'); } else if (*it == 'R') // right align { basic_buffer<my_char_t> buf; buf << U(" "); String2Buffer(TO_WSTRING(line.substr(it-line.begin()+1)), buf); if (discard_colors) buf.RemoveFormatting(); if (is_now_playing) buf << Config.now_playing_suffix; *menu << XY(menu->GetWidth()-buf.Str().length()-(menu->isSelected(menu->CurrentlyDrawedPosition()) ? Config.selected_item_suffix_length : 0), menu->Y()) << buf; if (separate_albums) *menu << fmtUnderlineEnd; return; } else // not a color nor right align, just a random character *menu << *--it; } else if (*it == MPD::Song::FormatEscapeCharacter) { // treat '$' as a normal character if song format escape char is prepended to it if (++it == line.end() || *it != '$') --it; *menu << *it; } else *menu << *it; } if (is_now_playing) *menu << Config.now_playing_suffix; if (separate_albums) *menu << fmtUnderlineEnd; }