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;
}
Exemple #3
0
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;
}