Merge branch '0.7.x'

This commit is contained in:
Andrzej Rybczak
2016-10-30 23:44:26 +01:00
18 changed files with 128 additions and 51 deletions

View File

@@ -2124,11 +2124,15 @@ void AddRandomItems::run()
Statusbar::put() << "Number of random " << tag_type_str << "s: ";
number = fromString<unsigned>(wFooter->prompt());
}
if (number && (rnd_type == 's' ? Mpd.AddRandomSongs(number) : Mpd.AddRandomTag(tag_type, number)))
if (number > 0)
{
Statusbar::printf("%1% random %2%%3% added to playlist",
number, tag_type_str, number == 1 ? "" : "s"
);
bool success;
if (rnd_type == 's')
success = Mpd.AddRandomSongs(number, Global::RNG);
else
success = Mpd.AddRandomTag(tag_type, number, Global::RNG);
if (success)
Statusbar::printf("%1% random %2%%3% added to playlist", number, tag_type_str, number == 1 ? "" : "s");
}
}

View File

@@ -38,4 +38,6 @@ bool SeekingInProgress = false;
std::string VolumeState;
boost::posix_time::ptime Timer;
std::mt19937 RNG;
}

View File

@@ -22,6 +22,8 @@
#define NCMPCPP_GLOBAL_H
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <random>
#include "mpdpp.h"
#include "screen.h"
@@ -58,6 +60,9 @@ extern std::string VolumeState;
// global timer
extern boost::posix_time::ptime Timer;
// global RNG
extern std::mt19937 RNG;
}
#endif // NCMPCPP_GLOBAL_H

View File

@@ -53,7 +53,7 @@ MPD::SongIterator getDatabaseIterator(MPD::Connection &mpd)
{
// If we can't get the database, display appropriate
// error message and reconnect with the MPD server.
Statusbar::print("Unable to fetch the data, increase max_buffer_output_size in your MPD configuration file");
Statusbar::print("Unable to fetch the data, increase max_output_buffer_size in your MPD configuration file");
mpd.Disconnect();
mpd.Connect();
}

View File

@@ -25,7 +25,9 @@
#include <cstdlib>
#include <cstring>
#include <boost/algorithm/string/join.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/regex.hpp>
@@ -105,6 +107,15 @@ std::vector<std::string> LyricsFetcher::getContent(const char *regex_, const std
void LyricsFetcher::postProcess(std::string &data) const
{
stripHtmlTags(data);
// Remove indentation from each line and collapse multiple newlines into one.
std::vector<std::string> lines;
boost::split(lines, data, boost::is_any_of("\r\n"));
for (auto &line : lines)
boost::trim(line);
std::unique(lines.begin(), lines.end(), [](std::string &a, std::string &b) {
return a.empty() && b.empty();
});
data = boost::algorithm::join(lines, "\n");
boost::trim(data);
}
@@ -126,7 +137,7 @@ LyricsFetcher::Result LyricwikiFetcher::fetch(const std::string &artist, const s
return result;
}
auto lyrics = getContent("<div class='lyricbox'>(.*?)<!--", data);
auto lyrics = getContent("<div class='lyricbox'>(.*?)</div>", data);
if (lyrics.empty())
{
@@ -224,6 +235,14 @@ void Sing365Fetcher::postProcess(std::string &data) const
/**********************************************************************/
void JustSomeLyricsFetcher::postProcess(std::string &data) const
{
data = unescapeHtmlUtf8(data);
LyricsFetcher::postProcess(data);
}
/**********************************************************************/
void MetrolyricsFetcher::postProcess(std::string &data) const
{
// some of lyrics have both \n chars and <br />, html tags

View File

@@ -108,7 +108,9 @@ struct JustSomeLyricsFetcher : public GoogleLyricsFetcher
virtual const char *name() const OVERRIDE { return "justsomelyrics.com"; }
protected:
virtual const char *regex() const OVERRIDE { return "<div class=\"content.*?</div>(.*?)</div>"; }
virtual const char *regex() const OVERRIDE { return "<div class=\"content.*?</div>\\s*</div>(.*?)<div"; }
virtual void postProcess(std::string &data) const OVERRIDE;
};
struct AzLyricsFetcher : public GoogleLyricsFetcher

View File

@@ -353,13 +353,33 @@ template <typename ItemT> struct Menu : Window, List
Iterator current() { return Iterator(m_items.begin() + m_highlight); }
ConstIterator current() const { return ConstIterator(m_items.begin() + m_highlight); }
ReverseIterator rcurrent() { return ReverseIterator(++current()); }
ConstReverseIterator rcurrent() const { return ReverseIterator(++current()); }
ReverseIterator rcurrent() {
if (empty())
return rend();
else
return ReverseIterator(++current());
}
ConstReverseIterator rcurrent() const {
if (empty())
return rend();
else
return ConstReverseIterator(++current());
}
ValueIterator currentV() { return ValueIterator(m_items.begin() + m_highlight); }
ConstValueIterator currentV() const { return ConstValueIterator(m_items.begin() + m_highlight); }
ReverseValueIterator rcurrentV() { return ReverseValueIterator(++currentV()); }
ConstReverseValueIterator rcurrentV() const { return ConstReverseValueIterator(++currentV()); }
ReverseValueIterator rcurrentV() {
if (empty())
return rendV();
else
return ReverseValueIterator(++currentV());
}
ConstReverseValueIterator rcurrentV() const {
if (empty())
return rendV();
else
return ConstReverseValueIterator(++currentV());
}
Iterator begin() { return Iterator(m_items.begin()); }
ConstIterator begin() const { return ConstIterator(m_items.begin()); }

View File

@@ -561,7 +561,7 @@ void Connection::Add(const std::string &path)
}
}
bool Connection::AddRandomTag(mpd_tag_type tag, size_t number)
bool Connection::AddRandomTag(mpd_tag_type tag, size_t number, std::mt19937 &rng)
{
std::vector<std::string> tags(
std::make_move_iterator(GetList(tag)),
@@ -570,7 +570,7 @@ bool Connection::AddRandomTag(mpd_tag_type tag, size_t number)
if (number > tags.size())
return false;
std::random_shuffle(tags.begin(), tags.end());
std::shuffle(tags.begin(), tags.end(), rng);
auto it = tags.begin();
for (size_t i = 0; i < number && it != tags.end(); ++i)
{
@@ -588,7 +588,7 @@ bool Connection::AddRandomTag(mpd_tag_type tag, size_t number)
return true;
}
bool Connection::AddRandomSongs(size_t number)
bool Connection::AddRandomSongs(size_t number, std::mt19937 &rng)
{
prechecksNoCommandsList();
std::vector<std::string> files;
@@ -609,7 +609,7 @@ bool Connection::AddRandomSongs(size_t number)
}
else
{
std::random_shuffle(files.begin(), files.end());
std::shuffle(files.begin(), files.end(), rng);
StartCommandsList();
auto it = files.begin();
for (size_t i = 0; i < number && it != files.end(); ++i, ++it)

View File

@@ -23,6 +23,7 @@
#include <cassert>
#include <exception>
#include <random>
#include <set>
#include <vector>
@@ -524,8 +525,8 @@ struct Connection
int AddSong(const std::string &, int = -1); // returns id of added song
int AddSong(const Song &, int = -1); // returns id of added song
bool AddRandomTag(mpd_tag_type, size_t);
bool AddRandomSongs(size_t);
bool AddRandomTag(mpd_tag_type, size_t, std::mt19937 &rng);
bool AddRandomSongs(size_t number, std::mt19937 &rng);
void Add(const std::string &path);
void Delete(unsigned int pos);
void PlaylistDelete(const std::string &playlist, unsigned int pos);

View File

@@ -89,7 +89,6 @@ int main(int argc, char **argv)
using Global::VolumeState;
using Global::Timer;
srand(time(nullptr));
std::setlocale(LC_ALL, "");
std::locale::global(Charset::internalLocale());
@@ -131,6 +130,9 @@ int main(int argc, char **argv)
// initialize global timer
Timer = boost::posix_time::microsec_clock::local_time();
// initialize global random number generator
Global::RNG.seed(std::random_device()());
// initialize playlist
myPlaylist->switchTo();

View File

@@ -147,13 +147,23 @@ void PlaylistEditor::update()
{
m_playlists_update_requested = false;
size_t idx = 0;
for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it, ++idx)
try
{
if (idx < Playlists.size())
Playlists[idx].value() = std::move(*it);
for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it, ++idx)
{
if (idx < Playlists.size())
Playlists[idx].value() = std::move(*it);
else
Playlists.addItem(std::move(*it));
};
}
catch (MPD::ServerError &e)
{
if (e.code() == MPD_SERVER_ERROR_SYSTEM) // no playlists directory
Statusbar::print(e.what());
else
Playlists.addItem(std::move(*it));
};
throw;
}
if (idx < Playlists.size())
Playlists.resizeList(idx);
std::sort(Playlists.beginV(), Playlists.endV(),

View File

@@ -160,6 +160,12 @@ std::string adjust_directory(std::string s)
return s;
}
std::string adjust_path(std::string s)
{
expand_home(s);
return s;
}
// parser worker for buffer
template <typename ValueT, typename TransformT>
option_parser::worker buffer(NC::Buffer &arg, ValueT &&value, TransformT &&map)
@@ -237,8 +243,8 @@ bool Configuration::read(const std::vector<std::string> &config_paths, bool igno
p.add("mpd_crossfade_time", assign_default(
crossfade_time, 5
));
p.add("visualizer_fifo_path", assign_default(
visualizer_fifo_path, "/tmp/mpd.fifo"
p.add("visualizer_fifo_path", assign_default<std::string>(
visualizer_fifo_path, "/tmp/mpd.fifo", adjust_path
));
p.add("visualizer_output_name", assign_default(
visualizer_output_name, "Visualizer feed"
@@ -372,8 +378,8 @@ bool Configuration::read(const std::vector<std::string> &config_paths, bool igno
song_columns_mode_format = columns_to_format(columns);
return v;
}));
p.add("execute_on_song_change", assign_default(
execute_on_song_change, ""
p.add("execute_on_song_change", assign_default<std::string>(
execute_on_song_change, "", adjust_path
));
p.add("execute_on_player_state_change", assign_default(
execute_on_player_state_change, ""
@@ -647,8 +653,8 @@ bool Configuration::read(const std::vector<std::string> &config_paths, bool igno
boundsCheck(v, 1u, 3u);
return --v;
}));
p.add("external_editor", assign_default(
external_editor, "nano"
p.add("external_editor", assign_default<std::string>(
external_editor, "nano", adjust_path
));
p.add("use_console_editor", yes_no(
use_console_editor, true

View File

@@ -197,7 +197,7 @@ void SortPlaylistDialog::sort() const
quick_sort = [this, &song_cmp, &quick_sort, &iter_swap](Iterator first, Iterator last) {
if (last-first > 1)
{
Iterator pivot = first+rand()%(last-first);
Iterator pivot = first+Global::RNG()%(last-first);
iter_swap(pivot, last-1);
pivot = last-1;

View File

@@ -66,7 +66,7 @@ void stripHtmlTags(std::string &s)
for (size_t i = s.find("<"); i != std::string::npos; i = s.find("<"))
{
size_t j = s.find(">", i)+1;
if (s.compare(i, j-i, "<p>") == 0 || s.compare(i, j-i, "</p>") == 0)
if (s.compare(i, std::min(3ul, j-i), "<p ") == 0 || s.compare(i, j-i, "</p>") == 0)
s.replace(i, j-i, "\n");
else
s.replace(i, j-i, "");
@@ -87,4 +87,4 @@ void stripHtmlTags(std::string &s)
else if (s[i] == '\t')
s[i] = ' ';
}
}
}