Upgraded code to switch to C++17. Tested on Debian Buster

This commit is contained in:
emeric
2019-09-10 13:07:06 +02:00
parent 178c400067
commit 2c5917235a
82 changed files with 723 additions and 755 deletions
+3 -3
View File
@@ -25,8 +25,8 @@ lms_SOURCES = \
$(srcdir)/database/Artist.hpp \
$(srcdir)/database/Cluster.cpp \
$(srcdir)/database/Cluster.hpp \
$(srcdir)/database/Database.cpp \
$(srcdir)/database/Database.hpp \
$(srcdir)/database/Db.cpp \
$(srcdir)/database/Db.hpp \
$(srcdir)/database/TrackArtistLink.cpp \
$(srcdir)/database/TrackArtistLink.hpp \
$(srcdir)/database/TrackFeatures.cpp \
@@ -147,6 +147,6 @@ lms_SOURCES = \
$(srcdir)/utils/Utils.cpp \
$(srcdir)/utils/Utils.hpp
lms_CXXFLAGS=-std=c++14 -Wall -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT
lms_CXXFLAGS=-std=c++17 -I$(srcdir)/ui $(MAGICKXX_CFLAGS) -D_REENTRANT
lms_LDADD=$(MAGICKXX_LIBS)
+4 -4
View File
@@ -27,7 +27,7 @@
namespace API::Subsonic
{
boost::optional<Id>
std::optional<Id>
IdFromString(const std::string& id)
{
if (id == "root")
@@ -35,7 +35,7 @@ IdFromString(const std::string& id)
std::vector<std::string> values {splitString(id, "-")};
if (values.size() != 2)
return boost::none;
return std::nullopt;
Id res;
@@ -49,11 +49,11 @@ IdFromString(const std::string& id)
else if (type == "pl")
res.type = Id::Type::Playlist;
else
return boost::none;
return std::nullopt;
auto optId {readAs<Database::IdType>(values[1])};
if (!optId)
return boost::none;
return std::nullopt;
res.value = *optId;
+2 -2
View File
@@ -17,7 +17,7 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/optional.hpp>
#include <optional>
#include "database/Types.hpp"
@@ -39,7 +39,7 @@ struct Id
Database::IdType value {};
};
boost::optional<Id> IdFromString(const std::string& id);
std::optional<Id> IdFromString(const std::string& id);
std::string IdToString(const Id& id);
} // namespace API::Subsonic
+38 -37
View File
@@ -31,6 +31,7 @@
#include "cover/CoverArtGrabber.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/Track.hpp"
#include "database/TrackList.hpp"
@@ -53,14 +54,14 @@ static const Av::Encoding transcodeEncoding {Av::Encoding::MP3};
static const std::string reportedStarredDate {"2000-01-01T00:00:00"};
template<>
boost::optional<API::Subsonic::Id>
std::optional<API::Subsonic::Id>
readAs(const std::string& str)
{
return API::Subsonic::IdFromString(str);
}
template<>
boost::optional<bool>
std::optional<bool>
readAs(const std::string& str)
{
if (str == "true")
@@ -82,31 +83,31 @@ struct ClientVersion
}
template<>
boost::optional<API::Subsonic::ClientVersion>
std::optional<API::Subsonic::ClientVersion>
readAs(const std::string& str)
{
// Expects "X.Y.Z"
const auto numbers {splitString(str, ".")};
if (numbers.size() < 2 || numbers.size() > 3)
return boost::none;
return std::nullopt;
API::Subsonic::ClientVersion version;
auto number {readAs<unsigned>(numbers[0])};
if (!number)
return boost::none;
return std::nullopt;
version.major = *number;
number = {readAs<unsigned>(numbers[1])};
if (!number)
return boost::none;
return std::nullopt;
version.minor = *number;
if (numbers.size() == 3)
{
number = {readAs<unsigned>(numbers[2])};
if (!number)
return boost::none;
return std::nullopt;
version.patch = *number;
}
@@ -132,12 +133,12 @@ struct RequestContext
std::string userName;
};
using SessionMap = std::map<Database::Database*, std::unique_ptr<Session>>;
using SessionMap = std::map<Db*, std::unique_ptr<Session>>;
static std::map<std::thread::id, SessionMap> dbSessions;
static
Session&
getOrCreateDbSession(Database::Database& db)
getOrCreateDbSession(Db& db)
{
static std::mutex mutex;
@@ -152,12 +153,12 @@ getOrCreateDbSession(Database::Database& db)
if (it != std::end(*sessionMap))
return *it->second;
auto res {sessionMap->emplace(&db, db.createSession())};
auto res { sessionMap->try_emplace(&db, db.createSession())};
assert(res.second);
LMS_LOG(API_SUBSONIC, DEBUG) << "Created db session";
return *(res.first->second);
return *res.first->second;
}
static
@@ -209,7 +210,7 @@ getMandatoryMultiParametersAs(const Wt::Http::ParameterMap& parameterMap, const
}
template<typename T>
boost::optional<T>
std::optional<T>
getParameterAs(const Wt::Http::ParameterMap& parameterMap, const std::string& param)
{
std::vector<T> params {getMultiParametersAs<T>(parameterMap, param)};
@@ -277,7 +278,7 @@ struct MediaRetrievalResult
Wt::cpp17::any continuationData;
};
SubsonicResource::SubsonicResource(Database::Database& db)
SubsonicResource::SubsonicResource(Db& db)
: _db {db}
{
}
@@ -571,7 +572,7 @@ userToResponseNode(const User::pointer& user)
static
Response
handlePingRequest(RequestContext& context)
handlePingRequest(RequestContext&)
{
return Response::createOkResponse();
}
@@ -731,12 +732,12 @@ handleDeleteUserRequest(RequestContext& context)
static
Response
handleGetLicenseRequest(RequestContext& context)
handleGetLicenseRequest(RequestContext&)
{
Response response {Response::createOkResponse()};
Response::Node& licenseNode {response.createNode("license")};
licenseNode.setAttribute("licenseExpires", "2019-09-03T14:46:43");
licenseNode.setAttribute("licenseExpires", "2025-09-03T14:46:43");
licenseNode.setAttribute("email", "foo@bar.com");
licenseNode.setAttribute("valid", "true");
@@ -748,7 +749,7 @@ Response
handleGetRandomSongsRequest(RequestContext& context)
{
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(50)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(50)};
size = std::min(size, std::size_t {500});
auto transaction {context.dbSession.createSharedTransaction()};
@@ -776,8 +777,8 @@ handleGetAlbumListRequestCommon(const RequestContext& context, bool id3)
std::string type {getMandatoryParameterAs<std::string>(context.parameters, "type")};
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(10)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").get_value_or(0)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(10)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
std::vector<Release::pointer> releases;
@@ -932,7 +933,7 @@ handleGetArtistInfoRequestCommon(RequestContext& context, bool id3)
throw BadParameterGenericError {"id"};
// Optional params
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(20)};
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(20)};
Response response {Response::createOkResponse()};
Response::Node& artistInfoNode {response.createNode(id3 ? "artistInfo2" : "artistInfo")};
@@ -1075,7 +1076,7 @@ handleGetMusicDirectoryRequest(RequestContext& context)
static
Response
handleGetMusicFoldersRequest(RequestContext& context)
handleGetMusicFoldersRequest(RequestContext&)
{
Response response {Response::createOkResponse()};
Response::Node& musicFoldersNode {response.createNode("musicFolders")};
@@ -1142,7 +1143,7 @@ handleGetSimilarSongsRequestCommon(RequestContext& context, bool id3)
throw BadParameterGenericError {"id"};
// Optional params
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(50)};
std::size_t count {getParameterAs<std::size_t>(context.parameters, "count").value_or(50)};
auto similarArtistsId {getService<Similarity::Searcher>()->getSimilarArtists(context.dbSession, id.value, 5)};
@@ -1248,7 +1249,7 @@ handleGetStarred2Request(RequestContext& context)
static
Response::Node
tracklistToResponseNode(const TrackList::pointer& tracklist, Session& dbSession)
tracklistToResponseNode(const TrackList::pointer& tracklist, Session&)
{
Response::Node playlistNode;
@@ -1322,10 +1323,10 @@ handleGetSongsByGenreRequest(RequestContext& context)
std::string genre {getMandatoryParameterAs<std::string>(context.parameters, "genre")};
// Optional params
std::size_t size {getParameterAs<std::size_t>(context.parameters, "count").get_value_or(10)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "count").value_or(10)};
size = std::min(size, std::size_t {500});
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").get_value_or(0)};
std::size_t offset {getParameterAs<std::size_t>(context.parameters, "offset").value_or(0)};
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1398,12 +1399,12 @@ handleSearchRequestCommon(RequestContext& context, bool id3)
std::vector<std::string> keywords {splitString(query, " ")};
// Optional params
std::size_t artistCount {getParameterAs<std::size_t>(context.parameters, "artistCount").get_value_or(20)};
std::size_t artistOffset {getParameterAs<std::size_t>(context.parameters, "artistOffset").get_value_or(0)};
std::size_t albumCount {getParameterAs<std::size_t>(context.parameters, "albumCount").get_value_or(20)};
std::size_t albumOffset {getParameterAs<std::size_t>(context.parameters, "albumOffset").get_value_or(0)};
std::size_t songCount {getParameterAs<std::size_t>(context.parameters, "songCount").get_value_or(20)};
std::size_t songOffset {getParameterAs<std::size_t>(context.parameters, "songOffset").get_value_or(0)};
std::size_t artistCount {getParameterAs<std::size_t>(context.parameters, "artistCount").value_or(20)};
std::size_t artistOffset {getParameterAs<std::size_t>(context.parameters, "artistOffset").value_or(0)};
std::size_t albumCount {getParameterAs<std::size_t>(context.parameters, "albumCount").value_or(20)};
std::size_t albumOffset {getParameterAs<std::size_t>(context.parameters, "albumOffset").value_or(0)};
std::size_t songCount {getParameterAs<std::size_t>(context.parameters, "songCount").value_or(20)};
std::size_t songOffset {getParameterAs<std::size_t>(context.parameters, "songOffset").value_or(0)};
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1585,8 +1586,8 @@ Response
handleUpdateUserRequest(RequestContext& context)
{
std::string username {getMandatoryParameterAs<std::string>(context.parameters, "username")};
boost::optional<std::string> password {getParameterAs<std::string>(context.parameters, "password")};
boost::optional<Bitrate> maxBitRate {getParameterAs<Bitrate>(context.parameters, "maxBitRate")};
std::optional<std::string> password {getParameterAs<std::string>(context.parameters, "password")};
std::optional<Bitrate> maxBitRate {getParameterAs<Bitrate>(context.parameters, "maxBitRate")};
User::PasswordHash hash;
if (password)
@@ -1693,9 +1694,9 @@ createTranscoder(RequestContext& context)
Id id {getMandatoryParameterAs<Id>(context.parameters, "id")};
// Optional params
boost::optional<std::size_t> maxBitRate {getParameterAs<std::size_t>(context.parameters, "maxBitRate")};
std::optional<std::size_t> maxBitRate {getParameterAs<std::size_t>(context.parameters, "maxBitRate")};
boost::filesystem::path trackPath;
std::filesystem::path trackPath;
{
auto transaction {context.dbSession.createSharedTransaction()};
@@ -1771,7 +1772,7 @@ handleGetCoverArt(RequestContext& context, Wt::Http::ResponseContinuation*)
// Mandatory params
Id id {getMandatoryParameterAs<Id>(context.parameters, "id")};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").get_value_or(256)};
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(256)};
size = clamp(size, std::size_t {32}, std::size_t {1024});
MediaRetrievalResult res;
@@ -1861,7 +1862,7 @@ SubsonicResource::handleRequest(const Wt::Http::Request &request, Wt::Http::Resp
const Wt::Http::ParameterMap& parameters {request.getParameterMap()};
// Optional parameters
ResponseFormat format {getParameterAs<std::string>(parameters, "f").get_value_or("xml") == "json" ? ResponseFormat::json : ResponseFormat::xml};
const ResponseFormat format {getParameterAs<std::string>(parameters, "f").value_or("xml") == "json" ? ResponseFormat::json : ResponseFormat::xml};
try
{
+6 -5
View File
@@ -18,12 +18,13 @@
*/
#pragma once
#include <boost/optional.hpp>
#include <Wt/WResource.h>
#include <Wt/Http/Response.h>
#include "database/Database.hpp"
namespace Database
{
class Db;
}
namespace API::Subsonic
{
@@ -31,7 +32,7 @@ namespace API::Subsonic
class SubsonicResource final : public Wt::WResource
{
public:
SubsonicResource(Database::Database& db);
SubsonicResource(Database::Db& db);
~SubsonicResource();
static std::string getPath() { return "/rest/"; }
@@ -39,7 +40,7 @@ class SubsonicResource final : public Wt::WResource
void handleRequest(const Wt::Http::Request &request, Wt::Http::Response &response) override;
Database::Database& _db;
Database::Db& _db;
};
} // namespace
+3 -3
View File
@@ -62,7 +62,7 @@ AuthTokenService::createAuthToken(Database::Session& session, Database::IdType u
}
static
boost::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
std::optional<AuthTokenService::AuthTokenProcessResult::AuthTokenInfo>
processAuthToken(Database::Session& session, const std::string& secret)
{
const std::string secretHash {sha1Function.compute(secret, {})};
@@ -71,12 +71,12 @@ processAuthToken(Database::Session& session, const std::string& secret)
Database::AuthToken::pointer authToken {Database::AuthToken::getByValue(session, secretHash)};
if (!authToken)
return boost::none;
return std::nullopt;
if (authToken->getExpiry() < Wt::WDateTime::currentDateTime())
{
authToken.remove();
return boost::none;
return std::nullopt;
}
LMS_LOG(UI, DEBUG) << "Found auth token for user '" << authToken->getUser()->getLoginName() << "'!";
+3 -3
View File
@@ -21,9 +21,9 @@
#pragma once
#include <optional>
#include <string>
#include <boost/optional.hpp>
#include <boost/asio/ip/address.hpp>
#include "LoginThrottler.hpp"
@@ -69,8 +69,8 @@ namespace Auth {
Wt::WDateTime expiry;
};
State state;
boost::optional<AuthTokenInfo> authTokenInfo;
State state {State::NotFound};
std::optional<AuthTokenInfo> authTokenInfo {};
};
// Removed if found
+2 -2
View File
@@ -83,7 +83,7 @@ LoginThrottler::onGoodClientAttempt(const boost::asio::ip::address& address)
{
const boost::asio::ip::address clientAddress {getAddressToThrottle(address)};
_attemptsInfo.erase(address);
_attemptsInfo.erase(clientAddress);
}
bool
@@ -91,7 +91,7 @@ LoginThrottler::isClientThrottled(const boost::asio::ip::address& address) const
{
const boost::asio::ip::address clientAddress {getAddressToThrottle(address)};
auto it {_attemptsInfo.find(address)};
auto it {_attemptsInfo.find(clientAddress)};
if (it == _attemptsInfo.end())
return false;
+1 -2
View File
@@ -23,7 +23,6 @@
#include <string>
#include <boost/optional.hpp>
#include <boost/asio/ip/address.hpp>
#include "LoginThrottler.hpp"
@@ -81,7 +80,7 @@ namespace Auth {
};
State state;
boost::optional<AuthTokenInfo> authTokenInfo;
std::optional<AuthTokenInfo> authTokenInfo;
};
// Removed if found
+4 -12
View File
@@ -43,16 +43,8 @@ MediaFileException::MediaFileException(int avError)
{
}
void AvInit()
{
/* register all the codecs */
avcodec_register_all();
av_register_all();
LMS_LOG(AV, INFO) << "avcodec version = " << avcodec_version();
}
MediaFile::MediaFile(const boost::filesystem::path& p)
MediaFile::MediaFile(const std::filesystem::path& p)
: _p {p}
{
int error = avformat_open_input(&_context, _p.string().c_str(), nullptr, nullptr);
@@ -155,7 +147,7 @@ MediaFile::getStreamInfo() const
return res;
}
boost::optional<std::size_t>
std::optional<std::size_t>
MediaFile::getBestStream() const
{
int res = av_find_best_stream(_context,
@@ -166,7 +158,7 @@ MediaFile::getBestStream() const
0);
if (res < 0)
return boost::none;
return std::nullopt;
return res;
}
@@ -238,7 +230,7 @@ MediaFile::getAttachedPictures(std::size_t nbMaxPictures) const
return pictures;
}
boost::optional<MediaFileFormat> guessMediaFileFormat(const boost::filesystem::path& file)
std::optional<MediaFileFormat> guessMediaFileFormat(const std::filesystem::path& file)
{
AVOutputFormat* format {av_guess_format(NULL,file.string().c_str(),NULL)};
if (!format || !format->name)
+10 -12
View File
@@ -29,14 +29,12 @@ extern "C"
#include <libavutil/error.h>
}
#include <vector>
#include <string>
#include <cstdint>
#include <map>
#include <chrono>
#include <boost/optional.hpp>
#include <boost/filesystem/path.hpp>
#include <filesystem>
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "AvTypes.hpp"
@@ -66,7 +64,7 @@ class MediaFileException : public AvException
class MediaFile
{
public:
MediaFile(const boost::filesystem::path& p);
MediaFile(const std::filesystem::path& p);
~MediaFile();
MediaFile(const MediaFile&) = delete;
@@ -76,19 +74,19 @@ class MediaFile
std::string getFormatName() const;
const boost::filesystem::path& getPath() const {return _p;};
const std::filesystem::path& getPath() const {return _p;};
std::chrono::milliseconds getDuration() const;
std::map<std::string, std::string> getMetaData(void);
std::vector<StreamInfo> getStreamInfo() const;
boost::optional<std::size_t> getBestStream() const; // none if failure/unknown
std::optional<std::size_t> getBestStream() const; // none if failure/unknown
bool hasAttachedPictures(void) const;
std::vector<Picture> getAttachedPictures(std::size_t nbMaxPictures) const;
private:
boost::filesystem::path _p;
std::filesystem::path _p;
AVFormatContext* _context {};
};
@@ -99,7 +97,7 @@ struct MediaFileFormat
std::string format;
};
boost::optional<MediaFileFormat> guessMediaFileFormat(const boost::filesystem::path& file);
std::optional<MediaFileFormat> guessMediaFileFormat(const std::filesystem::path& file);
} // namespace Av
+47 -47
View File
@@ -37,16 +37,15 @@ static const std::vector<std::string> execNames =
"ffmpeg",
};
static std::mutex transcoderMutex;
static boost::filesystem::path avConvPath = boost::filesystem::path();
static std::filesystem::path avConvPath = std::filesystem::path();
static std::atomic<size_t> globalId = {0};
void
Transcoder::init()
{
for (std::string execName : execNames)
for (const std::string& execName : execNames)
{
boost::filesystem::path p = searchExecPath(execName);
const std::filesystem::path p {searchExecPath(execName)};
if (!p.empty())
{
avConvPath = p;
@@ -60,11 +59,10 @@ Transcoder::init()
throw AvException("Cannot find any transcoder binary!");
}
Transcoder::Transcoder(boost::filesystem::path filePath, TranscodeParameters parameters)
: _filePath(filePath),
_parameters(parameters),
_isComplete(false),
_id(globalId++)
Transcoder::Transcoder(const std::filesystem::path& filePath, const TranscodeParameters& parameters)
: _filePath {filePath},
_parameters {parameters},
_id {globalId++}
{
}
@@ -72,84 +70,84 @@ Transcoder::Transcoder(boost::filesystem::path filePath, TranscodeParameters par
bool
Transcoder::start()
{
if (!boost::filesystem::exists(_filePath))
if (!std::filesystem::exists(_filePath))
return false;
else if (!boost::filesystem::is_regular( _filePath) )
else if (!std::filesystem::is_regular_file( _filePath) )
return false;
LMS_LOG_TRANSCODE(INFO) << "Transcoding file '" << _filePath.string() << "'";
std::vector<std::string> args;
args.push_back(avConvPath.string());
args.emplace_back(avConvPath.string());
// Make sure we do not produce anything in the stderr output
// in order not to block the whole forked process
args.push_back("-loglevel");
args.push_back("quiet");
args.push_back("-nostdin");
args.emplace_back("-loglevel");
args.emplace_back("quiet");
args.emplace_back("-nostdin");
// input Offset
if (_parameters.offset)
{
args.push_back("-ss");
args.push_back(std::to_string((*_parameters.offset).count()));
args.emplace_back("-ss");
args.emplace_back(std::to_string((*_parameters.offset).count()));
}
// Input file
args.push_back("-i");
args.push_back(_filePath.string());
args.emplace_back("-i");
args.emplace_back(_filePath.string());
// Stream mapping, if set
if (_parameters.stream)
{
args.push_back("-map");
args.push_back("0:" + std::to_string(*_parameters.stream));
args.emplace_back("-map");
args.emplace_back("0:" + std::to_string(*_parameters.stream));
}
if (_parameters.stripMetadata)
{
// Strip metadata
args.push_back("-map_metadata");
args.push_back("-1");
args.emplace_back("-map_metadata");
args.emplace_back("-1");
}
// Skip video flows (including covers)
args.push_back("-vn");
args.emplace_back("-vn");
// Codecs and formats
if (_parameters.encoding)
{
// Output bitrates
args.push_back("-b:a");
args.push_back(std::to_string(_parameters.bitrate));
args.emplace_back("-b:a");
args.emplace_back(std::to_string(_parameters.bitrate));
switch (*_parameters.encoding)
{
case Encoding::MP3:
args.push_back("-f");
args.push_back("mp3");
args.emplace_back("-f");
args.emplace_back("mp3");
break;
case Encoding::OGG_OPUS:
args.push_back("-acodec");
args.push_back("libopus");
args.push_back("-f");
args.push_back("ogg");
args.emplace_back("-acodec");
args.emplace_back("libopus");
args.emplace_back("-f");
args.emplace_back("ogg");
break;
case Encoding::OGG_VORBIS:
args.push_back("-acodec");
args.push_back("libvorbis");
args.push_back("-f");
args.push_back("ogg");
args.emplace_back("-acodec");
args.emplace_back("libvorbis");
args.emplace_back("-f");
args.emplace_back("ogg");
break;
case Encoding::WEBM_VORBIS:
args.push_back("-acodec");
args.push_back("libvorbis");
args.push_back("-f");
args.push_back("webm");
args.emplace_back("-acodec");
args.emplace_back("libvorbis");
args.emplace_back("-f");
args.emplace_back("webm");
break;
@@ -169,23 +167,25 @@ Transcoder::start()
return false;
}
args.push_back("-acodec");
args.push_back("copy");
args.push_back("-f");
args.push_back(mediaFileFormat->format);
args.emplace_back("-acodec");
args.emplace_back("copy");
args.emplace_back("-f");
args.emplace_back(mediaFileFormat->format);
_outputMimeType = mediaFileFormat->mimeType;
}
args.push_back("pipe:1");
args.emplace_back("pipe:1");
LMS_LOG_TRANSCODE(DEBUG) << "Dumping args (" << args.size() << ")";
for (std::string arg : args)
for (const std::string& arg : args)
LMS_LOG_TRANSCODE(DEBUG) << "Arg = '" << arg << "'";
// make sure only one thread is executing this part of code
{
std::lock_guard<std::mutex> lock(transcoderMutex);
static std::mutex transcoderMutex;
std::lock_guard<std::mutex> lock {transcoderMutex};
_child = std::make_shared<redi::ipstream>();
+17 -20
View File
@@ -20,12 +20,11 @@
#pragma once
#include <chrono>
#include <filesystem>
#include <optional>
#include <pstreams/pstream.h>
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include "AvTypes.hpp"
namespace Av {
@@ -34,10 +33,10 @@ namespace Av {
struct TranscodeParameters
{
boost::optional<Encoding> encoding; // If not set, no transcoding is performed
std::optional<Encoding> encoding; // If not set, no transcoding is performed
std::size_t bitrate {128000};
boost::optional<std::size_t> stream; // Id of the stream to be transcoded (auto detect by default)
boost::optional<std::chrono::seconds> offset {};
std::optional<std::size_t> stream; // Id of the stream to be transcoded (auto detect by default)
std::optional<std::chrono::seconds> offset {};
bool stripMetadata {true};
};
@@ -46,32 +45,30 @@ class Transcoder
public:
static void init();
Transcoder(boost::filesystem::path file, TranscodeParameters parameters);
Transcoder(const std::filesystem::path& file, const TranscodeParameters& parameters);
~Transcoder();
// non copyable
Transcoder(const Transcoder&) = delete;
Transcoder& operator=(const Transcoder&) = delete;
Transcoder(Transcoder&&) = delete;
Transcoder& operator=(Transcoder&&) = delete;
bool start();
const std::string& getOutputMimeType() const { return _outputMimeType; }
void process(std::vector<unsigned char>& output, std::size_t maxSize);
bool isComplete(void) const { return _isComplete; }
bool start();
const std::string& getOutputMimeType() const { return _outputMimeType; }
void process(std::vector<unsigned char>& output, std::size_t maxSize);
bool isComplete(void) const { return _isComplete; }
const TranscodeParameters& getParameters() const { return _parameters; }
private:
Transcoder();
boost::filesystem::path _filePath;
TranscodeParameters _parameters;
const std::filesystem::path _filePath;
const TranscodeParameters _parameters;
std::shared_ptr<redi::ipstream> _child;
bool _isComplete = false;
std::size_t _total = 0;
std::size_t _id;
bool _isComplete {};
std::size_t _total {};
const std::size_t _id {};
std::string _outputMimeType;
};
-1
View File
@@ -20,7 +20,6 @@
#pragma once
#include <string>
#include <boost/filesystem.hpp>
#include "utils/Exception.hpp"
+29 -29
View File
@@ -19,8 +19,6 @@
#include "CoverArtGrabber.hpp"
#include <boost/filesystem.hpp>
#include "av/AvInfo.hpp"
#include "database/Release.hpp"
@@ -32,9 +30,9 @@
namespace {
bool
isFileSupported(const boost::filesystem::path& file, const std::vector<boost::filesystem::path> extensions)
isFileSupported(const std::filesystem::path& file, const std::vector<std::filesystem::path> extensions)
{
boost::filesystem::path fileExtension = file.extension();
std::filesystem::path fileExtension = file.extension();
for (auto extension : extensions)
{
@@ -54,7 +52,7 @@ Grabber::Grabber()
}
void
Grabber::setDefaultCover(boost::filesystem::path p)
Grabber::setDefaultCover(const std::filesystem::path& p)
{
if (!_defaultCover.load(p))
throw LmsException("Cannot read default cover file '" + p.string() + "'");
@@ -84,7 +82,7 @@ Grabber::getDefaultCover(std::size_t size)
return it->second;
}
static boost::optional<Image::Image>
static std::optional<Image::Image>
getFromAvMediaFile(const Av::MediaFile& input)
{
std::vector<Image::Image> res;
@@ -100,11 +98,11 @@ getFromAvMediaFile(const Av::MediaFile& input)
}
LMS_LOG(COVER, DEBUG) << "No cover found in media file '" << input.getPath().string() << "'";
return boost::none;
return std::nullopt;
}
boost::optional<Image::Image>
Grabber::getFromDirectory(const boost::filesystem::path& p) const
std::optional<Image::Image>
Grabber::getFromDirectory(const std::filesystem::path& p) const
{
for (auto coverPath : getCoverPaths(p))
{
@@ -117,33 +115,33 @@ Grabber::getFromDirectory(const boost::filesystem::path& p) const
}
LMS_LOG(COVER, DEBUG) << "No cover found in directory '" << p.string() << "'";
return boost::none;
return std::nullopt;
}
std::vector<boost::filesystem::path>
Grabber::getCoverPaths(const boost::filesystem::path& directoryPath) const
std::vector<std::filesystem::path>
Grabber::getCoverPaths(const std::filesystem::path& directoryPath) const
{
std::vector<boost::filesystem::path> res;
boost::system::error_code ec;
std::vector<std::filesystem::path> res;
std::error_code ec;
// TODO handle preferred file names
boost::filesystem::directory_iterator itPath(directoryPath, ec);
boost::filesystem::directory_iterator itEnd;
std::filesystem::directory_iterator itPath(directoryPath, ec);
std::filesystem::directory_iterator itEnd;
while (!ec && itPath != itEnd)
{
boost::filesystem::path path = *itPath;
std::filesystem::path path = *itPath;
itPath.increment(ec);
if (!boost::filesystem::is_regular(path))
if (!std::filesystem::is_regular_file(path))
continue;
if (!isFileSupported(path, _fileExtensions))
continue;
if (boost::filesystem::file_size(path) > _maxFileSize)
if (std::filesystem::file_size(path) > _maxFileSize)
{
LMS_LOG(COVER, INFO) << "Cover file '" << path.string() << " is too big (" << boost::filesystem::file_size(path) << "), limit is " << _maxFileSize;
LMS_LOG(COVER, INFO) << "Cover file '" << path.string() << " is too big (" << std::filesystem::file_size(path) << "), limit is " << _maxFileSize;
continue;
}
@@ -153,8 +151,8 @@ Grabber::getCoverPaths(const boost::filesystem::path& directoryPath) const
return res;
}
boost::optional<Image::Image>
Grabber::getFromTrack(const boost::filesystem::path& p) const
std::optional<Image::Image>
Grabber::getFromTrack(const std::filesystem::path& p) const
{
try
{
@@ -165,7 +163,7 @@ Grabber::getFromTrack(const boost::filesystem::path& p) const
catch (Av::MediaFileException& e)
{
LMS_LOG(COVER, ERROR) << "Cannot get covers from track " << p.string() << ": " << e.what();
return boost::none;
return std::nullopt;
}
}
@@ -174,10 +172,10 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::IdType trackId, st
{
using namespace Database;
boost::optional<Image::Image> cover;
std::optional<Image::Image> cover;
bool hasCover {};
boost::filesystem::path trackPath;
std::filesystem::path trackPath;
{
auto transaction {dbSession.createSharedTransaction()};
@@ -208,9 +206,9 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::IdType trackId, st
Image::Image
Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId, std::size_t size)
{
boost::optional<Image::Image> cover;
std::optional<Image::Image> cover;
boost::optional<Database::IdType> trackId;
std::optional<Database::IdType> trackId;
{
auto transaction {session.createSharedTransaction()};
@@ -239,7 +237,8 @@ Grabber::getFromTrack(Database::Session& session, Database::IdType trackId, Imag
{
const Image::Image cover {getFromTrack(session, trackId, size)};
return cover.save(Image::Format::JPEG);
assert(format == Image::Format::JPEG);
return cover.save(format);
}
std::vector<uint8_t>
@@ -247,7 +246,8 @@ Grabber::getFromRelease(Database::Session& session, Database::IdType releaseId,
{
const Image::Image cover {getFromRelease(session, releaseId, size)};
return cover.save(Image::Format::JPEG);
assert(format == Image::Format::JPEG);
return cover.save(format);
}
} // namespace CoverArt
+8 -8
View File
@@ -19,12 +19,12 @@
#pragma once
#include <filesystem>
#include <map>
#include <mutex>
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include "database/Types.hpp"
#include "image/Image.hpp"
@@ -44,7 +44,7 @@ class Grabber
Grabber(Grabber&&) = delete;
Grabber& operator=(Grabber&&) = delete;
void setDefaultCover(boost::filesystem::path defaultCoverPath);
void setDefaultCover(const std::filesystem::path& defaultCoverPath);
std::vector<uint8_t> getFromTrack(Database::Session& dbSession, Database::IdType trackId, Image::Format format, std::size_t size);
std::vector<uint8_t> getFromRelease(Database::Session& dbSession, Database::IdType releaseId, Image::Format format, std::size_t size);
@@ -54,9 +54,9 @@ class Grabber
Image::Image getFromTrack(Database::Session& dbSession, Database::IdType trackId, std::size_t size);
Image::Image getFromRelease(Database::Session& dbSession, Database::IdType releaseId, std::size_t size);
boost::optional<Image::Image> getFromTrack(const boost::filesystem::path& path) const;
std::vector<boost::filesystem::path> getCoverPaths(const boost::filesystem::path& directoryPath) const;
boost::optional<Image::Image> getFromDirectory(const boost::filesystem::path& path) const;
std::optional<Image::Image> getFromTrack(const std::filesystem::path& path) const;
std::vector<std::filesystem::path> getCoverPaths(const std::filesystem::path& directoryPath) const;
std::optional<Image::Image> getFromDirectory(const std::filesystem::path& path) const;
Image::Image getDefaultCover(std::size_t size);
@@ -65,12 +65,12 @@ class Grabber
std::mutex _mutex;
std::map<std::size_t /* size */, Image::Image> _defaultCovers;
std::vector<boost::filesystem::path> _fileExtensions
std::vector<std::filesystem::path> _fileExtensions
= {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize
std::size_t _maxFileSize = 5000000;
std::vector<boost::filesystem::path> _preferredFileNames
std::vector<std::filesystem::path> _preferredFileNames
= {"cover", "front"}; // TODO parametrize
};
+13 -8
View File
@@ -75,7 +75,7 @@ Artist::create(Session& session, const std::string& name, const std::string& MBI
}
std::vector<Artist::pointer>
Artist::getAll(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Artist::getAll(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
Wt::Dbo::collection<pointer> res = session.getDboSession().find<Artist>()
@@ -151,8 +151,8 @@ std::vector<Artist::pointer>
Artist::getByFilter(Session& session,
const std::set<IdType>& clusters,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
session.checkSharedLocked();
@@ -174,7 +174,7 @@ Artist::getByFilter(Session& session,
}
std::vector<Artist::pointer>
Artist::getLastAdded(Session& session, Wt::WDateTime after, boost::optional<std::size_t> limit)
Artist::getLastAdded(Session& session, Wt::WDateTime after, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
Wt::Dbo::collection<Artist::pointer> res = session.getDboSession().query<Artist::pointer>("SELECT a from artist a INNER JOIN track_artist_link t_a_l ON t_a_l.artist_id = a.id INNER JOIN track t ON t.id = t_a_l.track_id")
@@ -243,7 +243,7 @@ Artist::getReleaseCount() const
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getTracks(boost::optional<TrackArtistLink::Type> linkType) const
Artist::getTracks(std::optional<TrackArtistLink::Type> linkType) const
{
assert(self());
assert(IdIsValid(self()->id()));
@@ -262,22 +262,27 @@ Artist::getTracks(boost::optional<TrackArtistLink::Type> linkType) const
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getTracksWithRelease(boost::optional<TrackArtistLink::Type> linkType) const
Artist::getTracksWithRelease(std::optional<TrackArtistLink::Type> linkType) const
{
assert(self());
assert(IdIsValid(self()->id()));
assert(session());
Wt::Dbo::collection<Wt::Dbo::ptr<Track>> tracks {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN release r ON r.id = t.release_id")
auto query {session()->query<Wt::Dbo::ptr<Track>>("SELECT t FROM track t INNER JOIN artist a ON a.id = t_a_l.artist_id INNER JOIN track_artist_link t_a_l ON t_a_l.track_id = t.id INNER JOIN release r ON r.id = t.release_id")
.where("a.id = ?").bind(self()->id())
.orderBy("t.year,r.name,t.disc_number,t.track_number")};
if (linkType)
query.where("t_a_l.type = ?").bind(*linkType);
Wt::Dbo::collection<Wt::Dbo::ptr<Track>> tracks {query.resultList()};
return std::vector<Wt::Dbo::ptr<Track>>(tracks.begin(), tracks.end());
}
std::vector<Wt::Dbo::ptr<Track>>
Artist::getRandomTracks(boost::optional<std::size_t> count) const
Artist::getRandomTracks(std::optional<std::size_t> count) const
{
assert(self());
assert(IdIsValid(self()->id()));
+8 -9
View File
@@ -19,11 +19,10 @@
#pragma once
#include <optional>
#include <string>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/WDateTime.h>
#include <Wt/Dbo/Dbo.h>
@@ -58,13 +57,13 @@ class Artist : public Wt::Dbo::Dbo<Artist>
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrphans(Session& session); // No track related
static std::vector<pointer> getLastAdded(Session& session, Wt::WDateTime after, boost::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, Wt::WDateTime after, std::optional<std::size_t> size = {});
// Accessors
const std::string& getName(void) const { return _name; }
@@ -72,9 +71,9 @@ class Artist : public Wt::Dbo::Dbo<Artist>
std::vector<Wt::Dbo::ptr<Release>> getReleases(const std::set<IdType>& clusterIds = std::set<IdType>()) const;
std::size_t getReleaseCount() const;
std::vector<Wt::Dbo::ptr<Track>> getTracks(boost::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getTracksWithRelease(boost::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getRandomTracks(boost::optional<std::size_t> count) const;
std::vector<Wt::Dbo::ptr<Track>> getTracks(std::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getTracksWithRelease(std::optional<TrackArtistLink::Type> linkType = {}) const;
std::vector<Wt::Dbo::ptr<Track>> getRandomTracks(std::optional<std::size_t> count) const;
// Get the cluster of the tracks made by this artist
// Each clusters are grouped by cluster type, sorted by the number of occurence
@@ -17,7 +17,7 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Database.hpp"
#include "Db.hpp"
#include <Wt/Dbo/FixedSqlConnectionPool.h>
#include <Wt/Dbo/backend/Sqlite3.h>
@@ -28,7 +28,7 @@
namespace Database {
// Session living class handling the database and the login
Database::Database(const boost::filesystem::path& dbPath)
Db::Db(const std::filesystem::path& dbPath)
{
LMS_LOG(DB, INFO) << "Creating connection pool on file " << dbPath.string();
@@ -49,9 +49,9 @@ Database::Database(const boost::filesystem::path& dbPath)
}
std::unique_ptr<Session>
Database::createSession()
Db::createSession()
{
return std::unique_ptr<Session>{new Session {_sharedMutex, *_connectionPool.get()}};
return std::unique_ptr<Session>(new Session {_sharedMutex, *_connectionPool.get()});
}
} // namespace Database
@@ -19,10 +19,9 @@
#pragma once
#include <filesystem>
#include <shared_mutex>
#include <boost/filesystem.hpp>
#include <Wt/Dbo/SqlConnectionPool.h>
#include "Session.hpp"
@@ -30,17 +29,17 @@
namespace Database {
// Session living class handling the database and the login
class Database
class Db
{
public:
Database(const boost::filesystem::path& dbPath);
Db(const std::filesystem::path& dbPath);
std::unique_ptr<Session> createSession();
private:
std::shared_timed_mutex _sharedMutex;
std::unique_ptr<Wt::Dbo::SqlConnectionPool> _connectionPool;
std::shared_mutex _sharedMutex;
std::unique_ptr<Wt::Dbo::SqlConnectionPool> _connectionPool;
};
} // namespace Database
+18 -18
View File
@@ -84,7 +84,7 @@ Release::getCount(Session& session)
}
std::vector<Release::pointer>
Release::getAll(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Release::getAll(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -97,7 +97,7 @@ Release::getAll(Session& session, boost::optional<std::size_t> offset, boost::op
}
std::vector<Release::pointer>
Release::getAllOrderedByArtist(Session& session, boost::optional<std::size_t> offset, boost::optional<std::size_t> size)
Release::getAllOrderedByArtist(Session& session, std::optional<std::size_t> offset, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -114,7 +114,7 @@ Release::getAllOrderedByArtist(Session& session, boost::optional<std::size_t> of
}
std::vector<Release::pointer>
Release::getAllRandom(Session& session, boost::optional<std::size_t> size)
Release::getAllRandom(Session& session, std::optional<std::size_t> size)
{
session.checkSharedLocked();
@@ -136,7 +136,7 @@ Release::getAllOrphans(Session& session)
}
std::vector<Release::pointer>
Release::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> offset, boost::optional<std::size_t> limit)
Release::getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> offset, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -151,7 +151,7 @@ Release::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optio
}
std::vector<Release::pointer>
Release::getByYear(Session& session, int yearFrom, int yearTo, boost::optional<std::size_t> offset, boost::optional<std::size_t> limit)
Release::getByYear(Session& session, int yearFrom, int yearTo, std::optional<std::size_t> offset, std::optional<std::size_t> limit)
{
Wt::Dbo::collection<Release::pointer> res = session.getDboSession().query<Release::pointer>
("SELECT DISTINCT r from release r INNER JOIN track t ON r.id = t.release_id")
@@ -216,8 +216,8 @@ std::vector<Release::pointer>
Release::getByFilter(Session& session,
const std::set<IdType>& clusterIds,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
Wt::Dbo::collection<pointer> collection = getQuery(session, clusterIds, keywords)
@@ -237,19 +237,19 @@ Release::getByFilter(Session& session,
return res;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Release::getTotalTrackNumber(void) const
{
return (_totalTrackNumber > 0) ? boost::make_optional<std::size_t>(_totalTrackNumber) : boost::none;
return (_totalTrackNumber > 0) ? std::make_optional<std::size_t>(_totalTrackNumber) : std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Release::getTotalDiscNumber(void) const
{
return (_totalDiscNumber > 0) ? boost::make_optional<std::size_t>(_totalDiscNumber) : boost::none;
return (_totalDiscNumber > 0) ? std::make_optional<std::size_t>(_totalDiscNumber) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Release::getReleaseYear(bool original) const
{
assert(session());
@@ -264,17 +264,17 @@ Release::getReleaseYear(bool original) const
// various dates => no date
if (dates.empty() || dates.size() > 1)
return boost::none;
return std::nullopt;
auto date {dates.front()};
if (date > 0)
return date;
else
return boost::none;
return std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Release::getCopyright() const
{
assert(session());
@@ -289,12 +289,12 @@ Release::getCopyright() const
// various copyrights => no copyright
if (values.empty() || values.size() > 1 || values.front().empty())
return boost::none;
return std::nullopt;
return values.front();
}
boost::optional<std::string>
std::optional<std::string>
Release::getCopyrightURL() const
{
assert(session());
@@ -309,7 +309,7 @@ Release::getCopyrightURL() const
// various copyright URLs => no copyright URL
if (values.empty() || values.size() > 1 || values.front().empty())
return boost::none;
return std::nullopt;
return values.front();
}
+13 -13
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/Dbo/WtSqlTraits.h>
@@ -51,18 +51,18 @@ class Release : public Wt::Dbo::Dbo<Release>
static std::vector<pointer> getByName(Session& session, const std::string& name);
static pointer getById(Session& session, IdType id);
static std::vector<pointer> getAllOrphans(Session& session); // no track related
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrderedByArtist(Session& session, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAllRandom(Session& session, boost::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getByYear(Session& session, int yearFrom, int yearTo, boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllOrderedByArtist(Session& session, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getAllRandom(Session& session, std::optional<std::size_t> size = {});
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getByYear(Session& session, int yearFrom, int yearTo, std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {});
static std::vector<pointer> getByFilter(Session& session, const std::set<IdType>& clusters);
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // at least one track that belongs to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
std::vector<Wt::Dbo::ptr<Track>> getTracks(const std::set<IdType>& clusters = std::set<IdType>()) const;
@@ -77,9 +77,9 @@ class Release : public Wt::Dbo::Dbo<Release>
static pointer create(Session& session, const std::string& name, const std::string& MBID = "");
// Utility functions
boost::optional<int> getReleaseYear(bool originalDate = false) const; // 0 if unknown or various
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
std::optional<int> getReleaseYear(bool originalDate = false) const; // 0 if unknown or various
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
// Modifiers
void setTotalDiscNumber(std::size_t num) { _totalDiscNumber = static_cast<int>(num); }
@@ -88,8 +88,8 @@ class Release : public Wt::Dbo::Dbo<Release>
// Accessors
std::string getName() const { return _name; }
std::string getMBID() const { return _MBID; }
boost::optional<std::size_t> getTotalTrackNumber() const;
boost::optional<std::size_t> getTotalDiscNumber() const;
std::optional<std::size_t> getTotalTrackNumber() const;
std::optional<std::size_t> getTotalDiscNumber() const;
std::chrono::milliseconds getDuration() const;
// Get the artists of this release
+4 -4
View File
@@ -62,11 +62,11 @@ ScanSettings::get(Session& session)
return session.getDboSession().find<ScanSettings>();
}
std::set<boost::filesystem::path>
std::set<std::filesystem::path>
ScanSettings::getAudioFileExtensions() const
{
auto extensions = splitString(_audioFileExtensions, " ");
return std::set<boost::filesystem::path>(std::cbegin(extensions), std::cend(extensions));
return std::set<std::filesystem::path>(std::cbegin(extensions), std::cend(extensions));
}
std::vector<ClusterType::pointer>
@@ -76,7 +76,7 @@ ScanSettings::getClusterTypes() const
}
void
ScanSettings::setMediaDirectory(boost::filesystem::path p)
ScanSettings::setMediaDirectory(std::filesystem::path p)
{
_mediaDirectory = stringTrimEnd(p.string(), "/\\");
}
@@ -85,7 +85,7 @@ template <typename It>
std::set<std::string> getNames(It begin, It end)
{
std::set<std::string> names;
std::transform(begin, end, std::inserter(names, std::begin(names)),
std::transform(begin, end, std::inserter(names, std::cbegin(names)),
[](const ClusterType::pointer& clusterType)
{
return clusterType->getName();
+5 -5
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WTime.h>
@@ -47,18 +47,18 @@ class ScanSettings : public Wt::Dbo::Dbo<ScanSettings>
// Getters
std::size_t getScanVersion() const { return _scanVersion; }
boost::filesystem::path getMediaDirectory() const { return _mediaDirectory; }
std::filesystem::path getMediaDirectory() const { return _mediaDirectory; }
Wt::WTime getUpdateStartTime() const { return _startTime; }
UpdatePeriod getUpdatePeriod() const { return _updatePeriod; }
std::vector<Wt::Dbo::ptr<ClusterType>> getClusterTypes() const;
std::set<boost::filesystem::path> getAudioFileExtensions() const;
std::set<std::filesystem::path> getAudioFileExtensions() const;
// Setters
void setMediaDirectory(boost::filesystem::path p);
void setMediaDirectory(std::filesystem::path p);
void setUpdateStartTime(Wt::WTime t) { _startTime = t; }
void setUpdatePeriod(UpdatePeriod p) { _updatePeriod = p; }
void setClusterTypes(Session& session, const std::set<std::string>& clusterTypeNames);
void setAudioFileExtensions(std::set<boost::filesystem::path> fileExtensions);
void setAudioFileExtensions(std::set<std::filesystem::path> fileExtensions);
template<class Action>
void persist(Action& a)
+8 -8
View File
@@ -110,7 +110,7 @@ Session::doDatabaseMigrationIfNeeded()
VersionInfo::get(*this).modify()->setVersion(LMS_DATABASE_VERSION);
}
Session::Session(std::shared_timed_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool)
Session::Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool)
: _mutex {mutex}
{
_session.setConnectionPool(connectionPool);
@@ -140,9 +140,9 @@ enum class OwnedLock
Unique,
};
static thread_local std::map<std::shared_timed_mutex*, OwnedLock> lockDebug;
static thread_local std::map<std::shared_mutex*, OwnedLock> lockDebug;
UniqueTransaction::UniqueTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session)
UniqueTransaction::UniqueTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
@@ -156,7 +156,7 @@ UniqueTransaction::~UniqueTransaction()
lockDebug[_lock.mutex()] = OwnedLock::None;
}
SharedTransaction::SharedTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session)
SharedTransaction::SharedTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session)
: _lock {mutex},
_transaction {session}
{
@@ -182,16 +182,16 @@ Session::checkSharedLocked()
assert(lockDebug[&_mutex] != OwnedLock::None);
}
std::unique_ptr<UniqueTransaction>
UniqueTransaction
Session::createUniqueTransaction()
{
return std::unique_ptr<UniqueTransaction>(new UniqueTransaction{_mutex, _session});
return UniqueTransaction{_mutex, _session};
}
std::unique_ptr<SharedTransaction>
SharedTransaction
Session::createSharedTransaction()
{
return std::unique_ptr<SharedTransaction>(new SharedTransaction{_mutex, _session});
return SharedTransaction{_mutex, _session};
}
void
+10 -11
View File
@@ -21,7 +21,6 @@
#include <shared_mutex>
#include <mutex>
#include <boost/filesystem.hpp>
#include <memory>
#include <Wt/Dbo/Dbo.h>
@@ -36,9 +35,9 @@ class UniqueTransaction
private:
friend class Session;
UniqueTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session);
UniqueTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session);
std::unique_lock<std::shared_timed_mutex> _lock;
std::unique_lock<std::shared_mutex> _lock;
Wt::Dbo::Transaction _transaction;
};
@@ -49,9 +48,9 @@ class SharedTransaction
private:
friend class Session;
SharedTransaction(std::shared_timed_mutex& mutex, Wt::Dbo::Session& session);
SharedTransaction(std::shared_mutex& mutex, Wt::Dbo::Session& session);
std::shared_lock<std::shared_timed_mutex> _lock;
std::shared_lock<std::shared_mutex> _lock;
Wt::Dbo::Transaction _transaction;
};
@@ -63,8 +62,8 @@ class Session
Session& operator=(const Session&) = delete;
Session& operator=(Session&&) = delete;
std::unique_ptr<UniqueTransaction> createUniqueTransaction();
std::unique_ptr<SharedTransaction> createSharedTransaction();
UniqueTransaction createUniqueTransaction();
SharedTransaction createSharedTransaction();
void checkUniqueLocked();
void checkSharedLocked();
@@ -74,15 +73,15 @@ class Session
Wt::Dbo::Session& getDboSession() { return _session; }
private:
friend class Database;
friend class Db;
Session(std::shared_timed_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
Session(std::shared_mutex& mutex, Wt::Dbo::SqlConnectionPool& connectionPool);
void doDatabaseMigrationIfNeeded();
void prepareTables(); // need to run only once at startup
std::shared_timed_mutex& _mutex;
Wt::Dbo::Session _session;
std::shared_mutex& _mutex;
Wt::Dbo::Session _session;
};
} // namespace Database
+23 -23
View File
@@ -32,14 +32,14 @@
namespace Database {
Track::Track(const boost::filesystem::path& p)
Track::Track(const std::filesystem::path& p)
:
_filePath( p.string() )
{
}
std::vector<Track::pointer>
Track::getAll(Session& session, boost::optional<std::size_t> limit)
Track::getAll(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -50,7 +50,7 @@ Track::getAll(Session& session, boost::optional<std::size_t> limit)
}
std::vector<Track::pointer>
Track::getAllRandom(Session& session, boost::optional<std::size_t> limit)
Track::getAllRandom(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -71,7 +71,7 @@ Track::getAllIds(Session& session)
}
Track::pointer
Track::getByPath(Session& session, const boost::filesystem::path& p)
Track::getByPath(Session& session, const std::filesystem::path& p)
{
session.checkSharedLocked();
@@ -97,7 +97,7 @@ Track::getByMBID(Session& session, const std::string& mbid)
}
Track::pointer
Track::create(Session& session, const boost::filesystem::path& p)
Track::create(Session& session, const std::filesystem::path& p)
{
session.checkUniqueLocked();
@@ -107,13 +107,13 @@ Track::create(Session& session, const boost::filesystem::path& p)
return res;
}
std::vector<boost::filesystem::path>
std::vector<std::filesystem::path>
Track::getAllPaths(Session& session)
{
session.checkSharedLocked();
Wt::Dbo::collection<std::string> res = session.getDboSession().query<std::string>("SELECT file_path FROM track");
return std::vector<boost::filesystem::path>(res.begin(), res.end());
return std::vector<std::filesystem::path>(res.begin(), res.end());
}
std::vector<Track::pointer>
@@ -126,7 +126,7 @@ Track::getMBIDDuplicates(Session& session)
}
std::vector<Track::pointer>
Track::getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> limit)
Track::getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -151,7 +151,7 @@ Track::getAllWithMBIDAndMissingFeatures(Session& session)
}
std::vector<IdType>
Track::getAllIdsWithFeatures(Session& session, boost::optional<std::size_t> limit)
Track::getAllIdsWithFeatures(Session& session, std::optional<std::size_t> limit)
{
session.checkSharedLocked();
@@ -224,8 +224,8 @@ std::vector<Track::pointer>
Track::getByFilter(Session& session,
const std::set<IdType>& clusterIds,
const std::vector<std::string>& keywords,
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreResults)
{
session.checkSharedLocked();
@@ -289,40 +289,40 @@ Track::setFeatures(const Wt::Dbo::ptr<TrackFeatures>& features)
_trackFeatures = features;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Track::getTrackNumber(void) const
{
return (_trackNumber > 0) ? boost::make_optional<std::size_t>(_trackNumber) : boost::none;
return (_trackNumber > 0) ? std::make_optional<std::size_t>(_trackNumber) : std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
Track::getDiscNumber(void) const
{
return (_discNumber > 0) ? boost::make_optional<std::size_t>(_discNumber) : boost::none;
return (_discNumber > 0) ? std::make_optional<std::size_t>(_discNumber) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Track::getYear() const
{
return (_year > 0) ? boost::make_optional<int>(_year) : boost::none;
return (_year > 0) ? std::make_optional<int>(_year) : std::nullopt;
}
boost::optional<int>
std::optional<int>
Track::getOriginalYear() const
{
return (_originalYear > 0) ? boost::make_optional<int>(_originalYear) : boost::none;
return (_originalYear > 0) ? std::make_optional<int>(_originalYear) : std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Track::getCopyright() const
{
return _copyright != "" ? boost::make_optional<std::string>(_copyright) : boost::none;
return _copyright != "" ? std::make_optional<std::string>(_copyright) : std::nullopt;
}
boost::optional<std::string>
std::optional<std::string>
Track::getCopyrightURL() const
{
return _copyrightURL != "" ? boost::make_optional<std::string>(_copyrightURL) : boost::none;
return _copyrightURL != "" ? std::make_optional<std::string>(_copyrightURL) : std::nullopt;
}
std::vector<Wt::Dbo::ptr<Artist>>
+22 -23
View File
@@ -19,12 +19,11 @@
#pragma once
#include <string>
#include <vector>
#include <chrono>
#include <boost/filesystem.hpp>
#include <boost/optional.hpp>
#include <filesystem>
#include <optional>
#include <vector>
#include <string>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WDateTime.h>
@@ -50,10 +49,10 @@ class Track : public Wt::Dbo::Dbo<Track>
using pointer = Wt::Dbo::ptr<Track>;
Track() {}
Track(const boost::filesystem::path& p);
Track(const std::filesystem::path& p);
// Find utility functions
static pointer getByPath(Session& session, const boost::filesystem::path& p);
static pointer getByPath(Session& session, const std::filesystem::path& p);
static pointer getById(Session& session, IdType id);
static pointer getByMBID(Session& session, const std::string& MBID);
static std::vector<pointer> getByFilter(Session& session,
@@ -61,21 +60,21 @@ class Track : public Wt::Dbo::Dbo<Track>
static std::vector<pointer> getByFilter(Session& session,
const std::set<IdType>& clusters, // tracks that belong to these clusters
const std::vector<std::string>& keywords, // name must match all of these keywords
boost::optional<std::size_t> offset,
boost::optional<std::size_t> size,
std::optional<std::size_t> offset,
std::optional<std::size_t> size,
bool& moreExpected);
static std::vector<pointer> getAll(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<pointer> getAllRandom(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<pointer> getAll(Session& session, std::optional<std::size_t> limit = {});
static std::vector<pointer> getAllRandom(Session& session, std::optional<std::size_t> limit = {});
static std::vector<IdType> getAllIds(Session& session); // nested transaction
static std::vector<boost::filesystem::path> getAllPaths(Session& session); // nested transaction
static std::vector<std::filesystem::path> getAllPaths(Session& session); // nested transaction
static std::vector<pointer> getMBIDDuplicates(Session& session);
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, boost::optional<std::size_t> size = 1);
static std::vector<pointer> getLastAdded(Session& session, const Wt::WDateTime& after, std::optional<std::size_t> size = 1);
static std::vector<pointer> getAllWithMBIDAndMissingFeatures(Session& session);
static std::vector<IdType> getAllIdsWithFeatures(Session& session, boost::optional<std::size_t> limit = {});
static std::vector<IdType> getAllIdsWithFeatures(Session& session, std::optional<std::size_t> limit = {});
// Create utility
static pointer create(Session& session, const boost::filesystem::path& p);
static pointer create(Session& session, const std::filesystem::path& p);
// Accessors
void setScanVersion(std::size_t version) { _scanVersion = version; }
@@ -98,20 +97,20 @@ class Track : public Wt::Dbo::Dbo<Track>
void setFeatures(const Wt::Dbo::ptr<TrackFeatures>& features);
std::size_t getScanVersion() const { return _scanVersion; }
boost::optional<std::size_t> getTrackNumber() const;
boost::optional<std::size_t> getDiscNumber() const;
std::optional<std::size_t> getTrackNumber() const;
std::optional<std::size_t> getDiscNumber() const;
std::string getName() const { return _name; }
boost::filesystem::path getPath() const { return _filePath; }
std::filesystem::path getPath() const { return _filePath; }
std::chrono::milliseconds getDuration() const { return _duration; }
boost::optional<int> getYear() const;
boost::optional<int> getOriginalYear() const;
std::optional<int> getYear() const;
std::optional<int> getOriginalYear() const;
Wt::WDateTime getLastWriteTime() const { return _fileLastWrite; }
Wt::WDateTime getAddedTime() const { return _fileAdded; }
bool hasCover() const { return _hasCover; }
const std::string& getMBID() const { return _MBID; }
boost::optional<std::string> getCopyright() const;
boost::optional<std::string> getCopyrightURL() const;
std::vector<Wt::Dbo::ptr<Artist>> getArtists(TrackArtistLink::Type type = {TrackArtistLink::Type::Artist}) const;
std::optional<std::string> getCopyright() const;
std::optional<std::string> getCopyrightURL() const;
std::vector<Wt::Dbo::ptr<Artist>> getArtists(TrackArtistLink::Type type = TrackArtistLink::Type::Artist) const;
std::vector<Wt::Dbo::ptr<TrackArtistLink>> getArtistLinks() const;
Wt::Dbo::ptr<Release> getRelease() const { return _release; }
std::vector<Wt::Dbo::ptr<Cluster>> getClusters() const;
+2 -2
View File
@@ -100,7 +100,7 @@ TrackList::getById(Session& session, IdType id)
std::vector<Wt::Dbo::ptr<TrackListEntry>>
TrackList::getEntries(boost::optional<std::size_t> offset, boost::optional<std::size_t> size) const
TrackList::getEntries(std::optional<std::size_t> offset, std::optional<std::size_t> size) const
{
assert(session());
assert(IdIsValid(self()->id()));
@@ -116,7 +116,7 @@ TrackList::getEntries(boost::optional<std::size_t> offset, boost::optional<std::
}
std::vector<Wt::Dbo::ptr<TrackListEntry>>
TrackList::getEntriesReverse(boost::optional<std::size_t> offset, boost::optional<std::size_t> size) const
TrackList::getEntriesReverse(std::optional<std::size_t> offset, std::optional<std::size_t> size) const
{
assert(session());
assert(IdIsValid(self()->id()));
+4 -5
View File
@@ -19,12 +19,11 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <string>
#include <Wt/Dbo/Dbo.h>
#include <string>
#include "Types.hpp"
namespace Database {
@@ -79,8 +78,8 @@ class TrackList : public Wt::Dbo::Dbo<TrackList>
// Get tracks, ordered by position
std::size_t getCount() const;
Wt::Dbo::ptr<TrackListEntry> getEntry(std::size_t pos) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntries(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntriesReverse(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntries(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<TrackListEntry>> getEntriesReverse(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
std::vector<IdType> getTrackIds() const;
+1 -1
View File
@@ -247,7 +247,7 @@ User::hasStarredRelease(Wt::Dbo::ptr<Release> release) const
}
std::vector<Wt::Dbo::ptr<Release>>
User::getStarredReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit) const
User::getStarredReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit) const
{
Wt::Dbo::collection<Wt::Dbo::ptr<Release>> res = _starredReleases.find()
.offset(offset ? static_cast<int>(*offset) : -1)
+2 -3
View File
@@ -19,10 +19,9 @@
#pragma once
#include <optional>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/Dbo/Dbo.h>
#include <Wt/WDateTime.h>
@@ -162,7 +161,7 @@ class User : public Wt::Dbo::Dbo<User>
void starRelease(Wt::Dbo::ptr<Release> release);
void unstarRelease(Wt::Dbo::ptr<Release> release);
bool hasStarredRelease(Wt::Dbo::ptr<Release> release) const;
std::vector<Wt::Dbo::ptr<Release>> getStarredReleases(boost::optional<std::size_t> offset = {}, boost::optional<std::size_t> size = {}) const;
std::vector<Wt::Dbo::ptr<Release>> getStarredReleases(std::optional<std::size_t> offset = {}, std::optional<std::size_t> size = {}) const;
void starTrack(Wt::Dbo::ptr<Track> track);
void unstarTrack(Wt::Dbo::ptr<Track> track);
+1 -1
View File
@@ -68,7 +68,7 @@ Image::load(const std::vector<unsigned char>& rawData)
}
bool
Image::load(boost::filesystem::path p)
Image::load(const std::filesystem::path& p)
{
try
{
+2 -3
View File
@@ -19,10 +19,9 @@
#pragma once
#include <filesystem>
#include <vector>
#include <boost/filesystem/path.hpp>
#include <Magick++.h>
namespace Image
@@ -49,7 +48,7 @@ class Image
// input
bool load(const std::vector<unsigned char>& rawData);
bool load(boost::filesystem::path p);
bool load(const std::filesystem::path& p);
Geometry getSize() const;
+8 -9
View File
@@ -17,7 +17,6 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/filesystem.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <Wt/WServer.h>
@@ -29,6 +28,7 @@
#include "auth/AuthTokenService.hpp"
#include "auth/PasswordService.hpp"
#include "cover/CoverArtGrabber.hpp"
#include "database/Db.hpp"
#include "image/Image.hpp"
#include "scanner/MediaScanner.hpp"
#include "similarity/features/SimilarityFeaturesScannerAddon.hpp"
@@ -42,9 +42,9 @@ std::vector<std::string> generateWtConfig(std::string execPath)
{
std::vector<std::string> args;
const boost::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"};
const boost::filesystem::path wtLogFilePath {getService<Config>()->getPath("log-file", "/var/log/lms.log")};
const boost::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("access-log-file", "/var/log/lms.access.log")};
const std::filesystem::path wtConfigPath {getService<Config>()->getPath("working-dir") / "wt_config.xml"};
const std::filesystem::path wtLogFilePath {getService<Config>()->getPath("log-file", "/var/log/lms.log")};
const std::filesystem::path wtAccessLogFilePath {getService<Config>()->getPath("access-log-file", "/var/log/lms.access.log")};
args.push_back(execPath);
args.push_back("--config=" + wtConfigPath.string());
@@ -86,7 +86,7 @@ std::vector<std::string> generateWtConfig(std::string execPath)
int main(int argc, char* argv[])
{
boost::filesystem::path configFilePath {"/etc/lms.conf"};
std::filesystem::path configFilePath {"/etc/lms.conf"};
int res = EXIT_FAILURE;
assert(argc > 0);
@@ -110,8 +110,8 @@ int main(int argc, char* argv[])
ServiceProvider<Config>::create(configFilePath);
// Make sure the working directory exists
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir"));
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache");
std::filesystem::create_directories(getService<Config>()->getPath("working-dir"));
std::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache");
// Construct WT configuration and get the argc/argv back
std::vector<std::string> wtServerArgs = generateWtConfig(argv[0]);
@@ -128,11 +128,10 @@ int main(int argc, char* argv[])
// lib init
Image::init(argv[0]);
Av::AvInit();
Av::Transcoder::init();
// Initializing a connection pool to the database that will be shared along services
Database::Database database {getService<Config>()->getPath("working-dir") / "lms.db"};
Database::Db database {getService<Config>()->getPath("working-dir") / "lms.db"};
UserInterface::LmsApplicationGroupContainer appGroups;
+7 -7
View File
@@ -29,21 +29,21 @@ namespace MetaData
using MetadataMap = std::map<std::string, std::string>;
boost::optional<std::string>
std::optional<std::string>
findFirstValueOf(const MetadataMap& metadataMap, std::initializer_list<std::string> tags)
{
auto it = std::find_first_of(std::cbegin(metadataMap), std::cend(metadataMap), std::cbegin(tags), std::cend(tags), [](const auto& it, const auto& str) { return it.first == str; });
if (it == std::cend(metadataMap))
return boost::none;
return std::nullopt;
return stringTrim(it->second);
}
static
boost::optional<Album>
std::optional<Album>
getAlbum(const MetadataMap& metadataMap)
{
boost::optional<Album> res;
std::optional<Album> res;
auto album {findFirstValueOf(metadataMap, {"ALBUM"})};
if (!album)
@@ -115,8 +115,8 @@ getArtists(const MetadataMap& metadataMap)
return artists;
}
boost::optional<Track>
AvFormat::parse(const boost::filesystem::path& p, bool debug)
std::optional<Track>
AvFormat::parse(const std::filesystem::path& p, bool debug)
{
Track track;
@@ -215,7 +215,7 @@ AvFormat::parse(const boost::filesystem::path& p, bool debug)
}
catch(Av::MediaFileException& e)
{
return boost::none;
return std::nullopt;
}
return track;
+1 -4
View File
@@ -19,9 +19,6 @@
#pragma once
#include <map>
#include <string>
#include "MetaData.hpp"
namespace MetaData
@@ -31,7 +28,7 @@ namespace MetaData
class AvFormat : public Parser
{
public:
boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) override;
std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) override;
};
} // namespace MetaData
+10 -11
View File
@@ -20,12 +20,11 @@
#pragma once
#include <chrono>
#include <filesystem>
#include <map>
#include <optional>
#include <set>
#include <boost/optional.hpp>
#include <boost/filesystem.hpp>
namespace MetaData
{
using Clusters = std::map<std::string /* type */, std::set<std::string> /* names */>;
@@ -54,15 +53,15 @@ namespace MetaData
std::string title;
std::string musicBrainzTrackID;
std::string musicBrainzRecordID;
boost::optional<Album> album;
std::optional<Album> album;
Clusters clusters;
std::chrono::milliseconds duration {};
boost::optional<std::size_t> trackNumber;
boost::optional<std::size_t> totalTrack;
boost::optional<std::size_t> discNumber;
boost::optional<std::size_t> totalDisc;
boost::optional<int> year;
boost::optional<int> originalYear;
std::optional<std::size_t> trackNumber;
std::optional<std::size_t> totalTrack;
std::optional<std::size_t> discNumber;
std::optional<std::size_t> totalDisc;
std::optional<int> year;
std::optional<int> originalYear;
bool hasCover {false};
std::vector<AudioStream> audioStreams;
std::string acoustID;
@@ -73,7 +72,7 @@ namespace MetaData
class Parser
{
public:
virtual boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) = 0;
virtual std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) = 0;
void setClusterTypeNames(const std::set<std::string>& clusterTypeNames) { _clusterTypeNames = clusterTypeNames; }
+6 -6
View File
@@ -126,10 +126,10 @@ getAlbumArtists(const TagLib::PropertyMap& properties)
}
static
boost::optional<Album>
std::optional<Album>
getAlbum(const TagLib::PropertyMap& properties)
{
boost::optional<Album> res;
std::optional<Album> res;
std::vector<std::string> albumName {getPropertyValues(properties, "ALBUM")};
if (albumName.empty())
@@ -145,8 +145,8 @@ getAlbum(const TagLib::PropertyMap& properties)
return res;
}
boost::optional<Track>
TagLibParser::parse(const boost::filesystem::path& p, bool debug)
std::optional<Track>
TagLibParser::parse(const std::filesystem::path& p, bool debug)
{
TagLib::FileRef f {p.string().c_str(),
true, // read audio properties
@@ -155,13 +155,13 @@ TagLibParser::parse(const boost::filesystem::path& p, bool debug)
if (f.isNull())
{
LMS_LOG(METADATA, ERROR) << "File '" << p.string() << "': parsing failed";
return boost::none;
return std::nullopt;
}
if (!f.audioProperties())
{
LMS_LOG(METADATA, INFO) << "File '" << p.string() << "': no audio properties";
return boost::none;
return std::nullopt;
}
Track track;
+1 -4
View File
@@ -19,9 +19,6 @@
#pragma once
#include <map>
#include <string>
#include "MetaData.hpp"
namespace MetaData
@@ -31,7 +28,7 @@ namespace MetaData
class TagLibParser : public Parser
{
public:
boost::optional<Track> parse(const boost::filesystem::path& p, bool debug = false) override;
std::optional<Track> parse(const std::filesystem::path& p, bool debug = false) override;
};
} // namespace MetaData
+22 -23
View File
@@ -21,7 +21,6 @@
#include <stdexcept>
#include <boost/filesystem.hpp>
#include <boost/asio/placeholders.hpp>
#include <Wt/WLocalDateTime.h>
@@ -63,15 +62,15 @@ getNextFirstOfMonth(Wt::WDate current)
}
bool
isFileSupported(const boost::filesystem::path& file, const std::set<boost::filesystem::path>& extensions)
isFileSupported(const std::filesystem::path& file, const std::set<std::filesystem::path>& extensions)
{
return (extensions.find(file.extension()) != extensions.end());
}
bool
isPathInParentPath(const boost::filesystem::path& path, const boost::filesystem::path& parentPath)
isPathInParentPath(const std::filesystem::path& path, const std::filesystem::path& parentPath)
{
boost::filesystem::path curPath = path;
std::filesystem::path curPath = path;
while (curPath.has_parent_path())
{
@@ -327,25 +326,25 @@ MediaScanner::scheduleNextScan()
void
MediaScanner::countAllFiles(Stats& stats)
{
boost::system::error_code ec;
std::error_code ec;
stats.totalFiles = 0;
boost::filesystem::recursive_directory_iterator itPath {_mediaDirectory, ec};
std::filesystem::recursive_directory_iterator itPath {_mediaDirectory, ec};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << _mediaDirectory.string() << "': " << ec.message();
return;
}
boost::filesystem::recursive_directory_iterator itEnd;
std::filesystem::recursive_directory_iterator itEnd;
while (_running && itPath != itEnd)
{
const boost::filesystem::path& path {*itPath};
const std::filesystem::path& path {*itPath};
if (!ec)
{
if (boost::filesystem::is_regular(path) && isFileSupported(path, _fileExtensions))
if (std::filesystem::is_regular_file(path) && isFileSupported(path, _fileExtensions))
stats.totalFiles++;
if (stats.totalFiles % 250 == 0)
@@ -498,11 +497,11 @@ void MediaScanner::notifyInProgressIfNeeded(Stats& stats)
}
void
MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan, Stats& stats)
MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, Stats& stats)
{
notifyInProgressIfNeeded(stats);
auto lastWriteTime = Wt::WDateTime::fromTime_t(boost::filesystem::last_write_time(file));
const auto lastWriteTime {Wt::WDateTime::fromTimePoint(std::filesystem::last_write_time(file))};
if (!forceScan)
{
@@ -518,7 +517,7 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan,
}
}
boost::optional<MetaData::Track> trackInfo {_metadataParser.parse(file)};
std::optional<MetaData::Track> trackInfo {_metadataParser.parse(file)};
if (!trackInfo)
{
stats.scanErrors++;
@@ -642,11 +641,11 @@ MediaScanner::scanAudioFile(const boost::filesystem::path& file, bool forceScan,
}
void
MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool forceScan, Stats& stats)
MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bool forceScan, Stats& stats)
{
boost::system::error_code ec;
std::error_code ec;
boost::filesystem::recursive_directory_iterator itPath(mediaDirectory, ec);
std::filesystem::recursive_directory_iterator itPath {mediaDirectory, ec};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << mediaDirectory.string() << "': " << ec.message();
@@ -654,17 +653,17 @@ MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool fo
return;
}
boost::filesystem::recursive_directory_iterator itEnd;
std::filesystem::recursive_directory_iterator itEnd;
while (_running && itPath != itEnd)
{
const boost::filesystem::path& path {*itPath};
const std::filesystem::path& path {*itPath};
if (ec)
{
LMS_LOG(DBUPDATER, ERROR) << "Cannot process entry '" << path.string() << "': " << ec.message();
stats.scanErrors++;
}
else if (boost::filesystem::is_regular(path))
else if (std::filesystem::is_regular_file(path))
{
if (isFileSupported(path, _fileExtensions))
scanAudioFile(path, forceScan, stats );
@@ -678,14 +677,14 @@ MediaScanner::scanMediaDirectory(boost::filesystem::path mediaDirectory, bool fo
// Check if a file exists and is still in a media directory
static bool
checkFile(const boost::filesystem::path& p, const boost::filesystem::path& mediaDirectory, const std::set<boost::filesystem::path>& extensions)
checkFile(const std::filesystem::path& p, const std::filesystem::path& mediaDirectory, const std::set<std::filesystem::path>& extensions)
{
try
{
// For each track, make sure the the file still exists
// and still belongs to a media directory
if (!boost::filesystem::exists( p )
|| !boost::filesystem::is_regular( p ) )
if (!std::filesystem::exists( p )
|| !std::filesystem::is_regular_file( p ) )
{
LMS_LOG(DBUPDATER, INFO) << "Removing '" << p.string() << "': missing";
return false;
@@ -706,7 +705,7 @@ checkFile(const boost::filesystem::path& p, const boost::filesystem::path& media
return true;
}
catch (boost::filesystem::filesystem_error& e)
catch (std::filesystem::filesystem_error& e)
{
LMS_LOG(DBUPDATER, ERROR) << "Caught exception while checking file '" << p.string() << "': " << e.what();
return false;
@@ -716,7 +715,7 @@ checkFile(const boost::filesystem::path& p, const boost::filesystem::path& media
void
MediaScanner::removeMissingTracks(Stats& stats)
{
std::vector<boost::filesystem::path> trackPaths;
std::vector<std::filesystem::path> trackPaths;
{
auto transaction {_dbSession->createSharedTransaction()};
trackPaths = Track::getAllPaths(*_dbSession);;
+10 -9
View File
@@ -21,6 +21,7 @@
#include <chrono>
#include <mutex>
#include <optional>
#include <Wt/WDateTime.h>
#include <Wt/WIOService.h>
@@ -86,8 +87,8 @@ class MediaScanner
{
State currentState {State::NotScheduled};
Wt::WDateTime nextScheduledScan;
boost::optional<Stats> lastScanStats;
boost::optional<Stats> inProgressStats;
std::optional<Stats> lastScanStats;
std::optional<Stats> inProgressStats;
};
Status getStatus();
@@ -110,7 +111,7 @@ class MediaScanner
// Update database (scheduled callback)
void scan(boost::system::error_code ec);
void scanMediaDirectory( boost::filesystem::path mediaDirectory, bool forceScan, Stats& stats);
void scanMediaDirectory( const std::filesystem::path& mediaDirectory, bool forceScan, Stats& stats);
// Helpers
void refreshScanSettings();
@@ -119,8 +120,8 @@ class MediaScanner
void removeMissingTracks(Stats& stats);
void removeOrphanEntries();
void checkDuplicatedAudioFiles(Stats& stats);
void scanAudioFile(const boost::filesystem::path& file, bool forceScan, Stats& stats);
Database::IdType doScanAudioFile(const boost::filesystem::path& file, Stats& stats);
void scanAudioFile(const std::filesystem::path& file, bool forceScan, Stats& stats);
Database::IdType doScanAudioFile(const std::filesystem::path& file, Stats& stats);
void notifyInProgressIfNeeded(Stats& stats);
void notifyInProgress(Stats& stats);
@@ -137,16 +138,16 @@ class MediaScanner
std::mutex _statusMutex;
State _curState {State::NotScheduled};
boost::optional<Stats> _inProgressStats;
boost::optional<Stats> _lastScanStats;
std::optional<Stats> _inProgressStats;
std::optional<Stats> _lastScanStats;
Wt::WDateTime _nextScheduledScan;
// Current scan settings
std::size_t _scanVersion {};
Wt::WTime _startTime;
Database::ScanSettings::UpdatePeriod _updatePeriod {Database::ScanSettings::UpdatePeriod::Never};
std::set<boost::filesystem::path> _fileExtensions;
boost::filesystem::path _mediaDirectory;
std::set<std::filesystem::path> _fileExtensions;
std::filesystem::path _mediaDirectory;
}; // class MediaScanner
@@ -31,24 +31,24 @@ namespace Similarity {
static
boost::filesystem::path getCacheDirectory()
std::filesystem::path getCacheDirectory()
{
return getService<Config>()->getPath("working-dir") / "cache" / "features";
}
static boost::filesystem::path getCacheNetworkFilePath()
static std::filesystem::path getCacheNetworkFilePath()
{
return getCacheDirectory() / "network";
};
static boost::filesystem::path getCacheTrackPositionsFilePath()
static std::filesystem::path getCacheTrackPositionsFilePath()
{
return getCacheDirectory() / "track_positions";
}
static
bool
networkToCacheFile(const SOM::Network& network, boost::filesystem::path path)
networkToCacheFile(const SOM::Network& network, std::filesystem::path path)
{
try
{
@@ -91,8 +91,8 @@ networkToCacheFile(const SOM::Network& network, boost::filesystem::path path)
}
static
boost::optional<SOM::Network>
createNetworkFromCacheFile(boost::filesystem::path path)
std::optional<SOM::Network>
createNetworkFromCacheFile(std::filesystem::path path)
{
try
{
@@ -137,13 +137,13 @@ createNetworkFromCacheFile(boost::filesystem::path path)
catch (boost::property_tree::ptree_error& error)
{
LMS_LOG(SIMILARITY, ERROR) << "Cannot read network cache: " << error.what();
return boost::none;
return std::nullopt;
}
}
static
bool
objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Position>>& objectsPosition, boost::filesystem::path path)
objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Position>>& objectsPosition, std::filesystem::path path)
{
try
{
@@ -178,8 +178,8 @@ objectPositionToCacheFile(const std::map<Database::IdType, std::set<SOM::Positio
}
static
boost::optional<std::map<Database::IdType, std::set<SOM::Position>>>
createObjectPositionsFromCacheFile(boost::filesystem::path path)
std::optional<std::map<Database::IdType, std::set<SOM::Position>>>
createObjectPositionsFromCacheFile(std::filesystem::path path)
{
try
{
@@ -210,21 +210,21 @@ createObjectPositionsFromCacheFile(boost::filesystem::path path)
catch (boost::property_tree::ptree_error& error)
{
LMS_LOG(SIMILARITY, ERROR) << "Cannot create object position from cache file: " << error.what();
return boost::none;
return std::nullopt;
}
}
void
FeaturesCache::invalidate()
{
boost::filesystem::remove(getCacheNetworkFilePath());
boost::filesystem::remove(getCacheTrackPositionsFilePath());
std::filesystem::remove(getCacheNetworkFilePath());
std::filesystem::remove(getCacheTrackPositionsFilePath());
}
boost::optional<FeaturesCache>
std::optional<FeaturesCache>
FeaturesCache::read()
{
boost::optional<FeaturesCache> res;
std::optional<FeaturesCache> res;
auto network{createNetworkFromCacheFile(getCacheNetworkFilePath())};
if (!network)
@@ -240,7 +240,7 @@ FeaturesCache::read()
void
FeaturesCache::write()
{
boost::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache" / "features");
std::filesystem::create_directories(getService<Config>()->getPath("working-dir") / "cache" / "features");
if (!networkToCacheFile(_network, getCacheNetworkFilePath())
|| !objectPositionToCacheFile(_trackPositions, getCacheTrackPositionsFilePath()))
@@ -250,8 +250,8 @@ FeaturesCache::write()
}
FeaturesCache::FeaturesCache(SOM::Network network, ObjectPositions trackPositions)
: _network{std::move(network)},
_trackPositions{std::move(trackPositions)}
: _network {std::move(network)},
_trackPositions {std::move(trackPositions)}
{
}
@@ -20,6 +20,7 @@
#pragma once
#include <map>
#include <optional>
#include <set>
#include "database/Types.hpp"
@@ -33,7 +34,7 @@ class FeaturesCache
static void invalidate();
static boost::optional<FeaturesCache> read();
static std::optional<FeaturesCache> read();
void write();
private:
@@ -56,7 +56,7 @@ getTracksWithMBIDAndMissingFeatures(Database::Session& dbSession)
FeaturesScannerAddon::FeaturesScannerAddon(std::unique_ptr<Database::Session> dbSession)
: _dbSession {std::move(dbSession)}
{
boost::optional<Similarity::FeaturesCache> cache {Similarity::FeaturesCache::read()};
std::optional<Similarity::FeaturesCache> cache {Similarity::FeaturesCache::read()};
if (cache)
{
auto searcher {std::make_shared<Similarity::FeaturesSearcher>(*_dbSession.get(), *cache, [&]() { return _stopRequested; })};
@@ -40,8 +40,8 @@ class FeaturesScannerAddon final : public Scanner::MediaScannerAddon
void requestStop() override;
void preScanComplete() override;
void trackAdded(Database::IdType trackId) override {}
void trackToRemove(Database::IdType trackId) override {}
void trackAdded(Database::IdType) override {}
void trackToRemove(Database::IdType) override {}
void trackUpdated(Database::IdType trackId) override;
bool fetchFeatures(Database::IdType trackId, const std::string& MBID);
@@ -68,10 +68,10 @@ getFeatureInfoMapNbDimensions(const FeatureInfoMap& featureInfoMap)
}
static
boost::optional<SOM::InputVector>
std::optional<SOM::InputVector>
getInputVectorFromTrack(Database::Session& session, Database::IdType trackId, const FeatureInfoMap& featuresInfo, std::size_t nbDimensions)
{
boost::optional<SOM::InputVector> res {SOM::InputVector {nbDimensions}};
std::optional<SOM::InputVector> res {SOM::InputVector {nbDimensions}};
std::map<std::string, std::vector<double>> features;
for (auto itFeatureInfo : featuresInfo)
@@ -150,7 +150,7 @@ FeaturesSearcher::FeaturesSearcher(Database::Session& session, std::function<boo
if (stopRequested())
return;
boost::optional<SOM::InputVector> inputVector {getInputVectorFromTrack(session, trackId, featuresInfo, nbDimensions)};
std::optional<SOM::InputVector> inputVector {getInputVectorFromTrack(session, trackId, featuresInfo, nbDimensions)};
if (!inputVector)
continue;
@@ -456,7 +456,7 @@ FeaturesSearcher::getSimilarObjects(const std::set<Database::IdType>& ids,
break;
// If there is not enough objects, try again with closest neighbour until there is too much distance
boost::optional<SOM::Position> closestRefVectorPosition {_network->getClosestRefVectorPosition(searchedRefVectorsPosition, _networkRefVectorsDistanceMedian * 0.75)};
std::optional<SOM::Position> closestRefVectorPosition {_network->getClosestRefVectorPosition(searchedRefVectorsPosition, _networkRefVectorsDistanceMedian * 0.75)};
if (!closestRefVectorPosition)
break;
+6 -6
View File
@@ -189,10 +189,10 @@ Network::getClosestRefVectorPosition(const InputVector& data) const
});
}
boost::optional<Position>
std::optional<Position>
Network::getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const
{
boost::optional<Position> position {getClosestRefVectorPosition(data)};
std::optional<Position> position {getClosestRefVectorPosition(data)};
if (_distanceFunc(data, _refVectors.get(*position), _weights) > maxDistance)
position.reset();
@@ -200,7 +200,7 @@ Network::getClosestRefVectorPosition(const InputVector& data, InputVector::Dista
return position;
}
boost::optional<Position>
std::optional<Position>
Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const
{
std::set<Position> neighboursPosition;
@@ -221,7 +221,7 @@ Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPositio
neighboursPosition.erase(refVectorPosition);
if (neighboursPosition.empty())
return boost::none;
return std::nullopt;
// Now compute the distance for each neighbour
struct NeighbourInfo
@@ -247,9 +247,9 @@ Network::getClosestRefVectorPosition(const std::set<Position>& refVectorsPositio
}
if (neighboursInfo.empty())
return boost::none;
return std::nullopt;
auto min {std::min_element(neighboursInfo.begin(), neighboursInfo.end(),
auto min {std::min_element(std::cbegin(neighboursInfo), std::cend(neighboursInfo),
[&](const auto& a, const auto& b)
{
return a.distance < b.distance;
+3 -4
View File
@@ -21,11 +21,10 @@
#include <vector>
#include <set>
#include <optional>
#include <ostream>
#include <functional>
#include <boost/optional.hpp>
#include "utils/Exception.hpp"
#include "InputVector.hpp"
#include "Matrix.hpp"
@@ -70,9 +69,9 @@ class Network
const InputVector& getRefVector(const Position& position) const;
Position getClosestRefVectorPosition(const InputVector& data) const;
boost::optional<Position> getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const;
std::optional<Position> getClosestRefVectorPosition(const InputVector& data, InputVector::Distance maxDistance) const;
boost::optional<Position> getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const;
std::optional<Position> getClosestRefVectorPosition(const std::set<Position>& refVectorsPosition, InputVector::Distance maxDistance) const;
InputVector::Distance getRefVectorsDistance(const Position& position1, const Position& position2) const;
+5 -6
View File
@@ -54,12 +54,12 @@ createAuthToken(Database::IdType userId, const Wt::WDateTime& expiry)
}
boost::optional<Database::IdType>
std::optional<Database::IdType>
processAuthToken(const Wt::WEnvironment& env)
{
const std::string* authCookie {env.getCookie(authCookieName)};
if (!authCookie)
return boost::none;
return std::nullopt;
const auto res {getService<::Auth::AuthTokenService>()->processAuthToken(LmsApp->getDbSession(), boost::asio::ip::address::from_string(env.clientAddress()), *authCookie)};
switch (res.state)
@@ -67,7 +67,7 @@ processAuthToken(const Wt::WEnvironment& env)
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::NotFound:
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Throttled:
LmsApp->setCookie(authCookieName, std::string {}, 0, "", "", env.urlScheme() == "https");
return boost::none;
return std::nullopt;
case ::Auth::AuthTokenService::AuthTokenProcessResult::State::Found:
createAuthToken(res.authTokenInfo->userId, res.authTokenInfo->expiry);
@@ -107,7 +107,6 @@ class AuthModel : public Wt::WFormModel
user.modify()->setLastLogin(Wt::WDateTime::currentDateTime());
_userId = user.id();
const Wt::WDateTime now {Wt::WDateTime::currentDateTime()};
isDemo = user->isDemo();
}
@@ -151,11 +150,11 @@ class AuthModel : public Wt::WFormModel
return (validation(field).state() == Wt::ValidationState::Valid);
}
boost::optional<Database::IdType> getUserId() const { return _userId; }
std::optional<Database::IdType> getUserId() const { return _userId; }
private:
boost::optional<Database::IdType> _userId;
std::optional<Database::IdType> _userId;
};
const AuthModel::Field AuthModel::LoginNameField {"login-name"};
+1 -3
View File
@@ -19,15 +19,13 @@
#pragma once
#include <boost/optional.hpp>
#include <Wt/WTemplateFormView.h>
#include "database/Types.hpp"
namespace UserInterface {
boost::optional<Database::IdType>
std::optional<Database::IdType>
processAuthToken(const Wt::WEnvironment& env);
class Auth : public Wt::WTemplateFormView
+7 -6
View File
@@ -33,6 +33,7 @@
#include "cover/CoverArtGrabber.hpp"
#include "database/Artist.hpp"
#include "database/Cluster.hpp"
#include "database/Db.hpp"
#include "database/Release.hpp"
#include "database/User.hpp"
#include "explore/Explore.hpp"
@@ -56,7 +57,7 @@
namespace UserInterface {
std::unique_ptr<Wt::WApplication>
LmsApplication::create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups)
LmsApplication::create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups)
{
return std::make_unique<LmsApplication>(env, db.createSession(), appGroups);
}
@@ -496,13 +497,13 @@ LmsApplication::createHome()
playqueue->playNext();
});
playqueue->loadTrack.connect([=] (Database::IdType trackId, bool play)
playqueue->trackSelected.connect([=] (Database::IdType trackId, bool play)
{
_events.lastLoadedTrackId = trackId;
_events.trackLoaded(trackId, play);
});
playqueue->trackUnload.connect([=]
playqueue->trackUnselected.connect([=]
{
_events.lastLoadedTrackId.reset();
_events.trackUnloaded();
@@ -555,7 +556,7 @@ LmsApplication::createHome()
});
// Events from Application group
_events.appOpen.connect([=] (LmsApplicationInfo info)
_events.appOpen.connect([=] (LmsApplicationInfo)
{
// Only one active session by user
if (!LmsApp->isUserDemo())
@@ -565,10 +566,10 @@ LmsApplication::createHome()
}
});
internalPathChanged().connect(std::bind([=]
internalPathChanged().connect([=]
{
handlePathChange(mainStack, isUserAdmin());
}));
});
handlePathChange(mainStack, isUserAdmin());
}
+7 -10
View File
@@ -17,14 +17,12 @@
* along with LMS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LMS_APPLICATION_HPP
#define LMS_APPLICATION_HPP
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WApplication.h>
#include "database/Database.hpp"
#include "scanner/MediaScanner.hpp"
#include "LmsApplicationGroup.hpp"
@@ -32,6 +30,7 @@
namespace Database {
class Artist;
class Cluster;
class Db;
class Release;
class User;
}
@@ -51,7 +50,7 @@ struct Events
// A track is being loaded
Wt::Signal<Database::IdType /* trackId */, bool /* play */> trackLoaded;
boost::optional<Database::IdType> lastLoadedTrackId;
std::optional<Database::IdType> lastLoadedTrackId;
// Unload current track
Wt::Signal<> trackUnloaded;
@@ -75,7 +74,7 @@ class LmsApplication : public Wt::WApplication
public:
LmsApplication(const Wt::WEnvironment& env, std::unique_ptr<Database::Session> dbSession, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Database& db, LmsApplicationGroupContainer& appGroups);
static std::unique_ptr<Wt::WApplication> create(const Wt::WEnvironment& env, Database::Db& db, LmsApplicationGroupContainer& appGroups);
static LmsApplication* instance();
// Session application data
@@ -124,8 +123,8 @@ class LmsApplication : public Wt::WApplication
std::unique_ptr<Database::Session> _dbSession;
LmsApplicationGroupContainer& _appGroups;
Events _events;
boost::optional<Database::IdType> _userId;
boost::optional<bool> _userAuthStrong;
std::optional<Database::IdType> _userId;
std::optional<bool> _userAuthStrong;
std::shared_ptr<ImageResource> _imageResource;
std::shared_ptr<AudioResource> _audioResource;
};
@@ -136,5 +135,3 @@ class LmsApplication : public Wt::WApplication
} // namespace UserInterface
#endif
+1 -1
View File
@@ -30,7 +30,7 @@ namespace UserInterface {
LmsApplicationInfo
LmsApplicationInfo::fromEnvironment(const Wt::WEnvironment& env)
{
LmsApplicationInfo info = {.userAgent = wApp->environment().agent()};
LmsApplicationInfo info = {.userAgent = env.agent()};
return info;
}
+9 -9
View File
@@ -139,7 +139,7 @@ PlayQueue::PlayQueue()
trackPos = LmsApp->getUser()->getCurPlayingTrackPos();
}
load(trackPos, false);
loadTrack(trackPos, false);
});
trackList = LmsApp->getUser()->getQueuedTrackList(LmsApp->getDbSession());
}
@@ -192,11 +192,11 @@ PlayQueue::stop()
{
updateCurrentTrack(false);
_trackPos.reset();
trackUnload.emit();
trackUnselected.emit();
}
void
PlayQueue::load(std::size_t pos, bool play)
PlayQueue::loadTrack(std::size_t pos, bool play)
{
updateCurrentTrack(false);
@@ -237,7 +237,7 @@ PlayQueue::load(std::size_t pos, bool play)
updateCurrentTrack(true);
loadTrack.emit(trackId, play);
trackSelected.emit(trackId, play);
}
void
@@ -249,7 +249,7 @@ PlayQueue::playPrevious()
if (*_trackPos == 0)
stop();
else
load(*_trackPos - 1, true);
loadTrack(*_trackPos - 1, true);
}
void
@@ -257,11 +257,11 @@ PlayQueue::playNext()
{
if (!_trackPos)
{
load(0, true);
loadTrack(0, true);
return;
}
load(*_trackPos + 1, true);
loadTrack(*_trackPos + 1, true);
}
void
@@ -327,7 +327,7 @@ PlayQueue::playTracks(const std::vector<Database::IdType>& trackIds)
{
clearTracks();
enqueueTracks(trackIds);
load(0, true);
loadTrack(0, true);
LmsApp->notifyMsg(MsgType::Info, Wt::WString::trn("Lms.PlayQueue.nb-tracks-playing", trackIds.size()).arg(trackIds.size()), std::chrono::milliseconds(2000));
}
@@ -377,7 +377,7 @@ PlayQueue::addSome()
{
auto pos = _entriesContainer->indexOf(entry);
if (pos >= 0)
load(pos, true);
loadTrack(pos, true);
}));
Wt::WText* delBtn = entry->bindNew<Wt::WText>("del-btn", Wt::WString::tr("Lms.PlayQueue.template.delete-btn"), Wt::TextFormat::XHTML);
+7 -7
View File
@@ -19,13 +19,13 @@
#pragma once
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WPushButton.h>
#include <Wt/WTemplate.h>
#include <Wt/WText.h>
#include <boost/optional.hpp>
#include "database/Types.hpp"
namespace Similarity {
@@ -53,10 +53,10 @@ class PlayQueue : public Wt::WTemplate
void playPrevious();
// Signal emitted when a track is to be load(and optionally played)
Wt::Signal<Database::IdType /*trackId*/, bool /*play*/> loadTrack;
Wt::Signal<Database::IdType /*trackId*/, bool /*play*/> trackSelected;
// Signal emitted when play has to be stopped
Wt::Signal<> trackUnload;
// Signal emitted when track is unselected (has to be stopped)
Wt::Signal<> trackUnselected;
private:
Wt::Dbo::ptr<Database::TrackList> getTrackList();
@@ -71,7 +71,7 @@ class PlayQueue : public Wt::WTemplate
void updateRepeatBtn();
void updateRadioBtn();
void load(std::size_t pos, bool play);
void loadTrack(std::size_t pos, bool play);
void stop();
void addRadioTrackFromSimilarity(std::shared_ptr<Similarity::Finder> similarityFinder);
@@ -85,7 +85,7 @@ class PlayQueue : public Wt::WTemplate
Wt::WText* _nbTracks {};
Wt::WText* _repeatBtn {};
Wt::WText* _radioBtn {};
boost::optional<std::size_t> _trackPos; // current track position, if set
std::optional<std::size_t> _trackPos; // current track position, if set
};
} // namespace UserInterface
+3 -3
View File
@@ -53,7 +53,7 @@ class UserModel : public Wt::WFormModel
static const Field AudioTranscodeBitrateLimitField;
static const Field DemoField;
UserModel(boost::optional<Database::IdType> userId)
UserModel(std::optional<Database::IdType> userId)
: Wt::WFormModel(),
_userId(userId)
{
@@ -80,7 +80,7 @@ class UserModel : public Wt::WFormModel
void saveData()
{
boost::optional<Database::User::PasswordHash> passwordHash;
std::optional<Database::User::PasswordHash> passwordHash;
if (!valueText(PasswordField).empty())
passwordHash = getService<::Auth::PasswordService>()->hashPassword(valueText(PasswordField).toUTF8());
@@ -203,7 +203,7 @@ class UserModel : public Wt::WFormModel
}
std::shared_ptr<ValueStringModel<Bitrate>> _bitrateModel;
boost::optional<Database::IdType> _userId;
std::optional<Database::IdType> _userId;
};
const Wt::WFormModel::Field UserModel::LoginField = "login";
+4 -4
View File
@@ -19,7 +19,7 @@
#include "Validators.hpp"
#include <boost/filesystem.hpp>
#include <filesystem>
#include <Wt/WLengthValidator.h>
@@ -53,11 +53,11 @@ DirectoryValidator::validate(const Wt::WString& input) const
if (input.empty())
return Wt::WValidator::validate(input);
boost::filesystem::path p(input.toUTF8());
boost::system::error_code ec;
const std::filesystem::path p {input.toUTF8()};
std::error_code ec;
// TODO check rights
bool res = boost::filesystem::is_directory(p, ec);
bool res = std::filesystem::is_directory(p, ec);
if (ec)
return Wt::WValidator::Result(Wt::ValidationState::Invalid, ec.message()); // TODO translate common errors
else if (res)
+6 -5
View File
@@ -20,7 +20,8 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WStringListModel.h>
namespace UserInterface {
@@ -41,7 +42,7 @@ class ValueStringModel : public Wt::WStringListModel
return Wt::cpp17::any_cast<Wt::WString>(data(index(static_cast<int>(row), 0), Wt::ItemDataRole::Display));
}
boost::optional<std::size_t>
std::optional<std::size_t>
getRowFromString(const Wt::WString& value)
{
for (std::size_t i{}; i < static_cast<std::size_t>(rowCount()); ++i)
@@ -50,10 +51,10 @@ class ValueStringModel : public Wt::WStringListModel
return i;
}
return boost::none;
return std::nullopt;
}
boost::optional<std::size_t>
std::optional<std::size_t>
getRowFromValue(const T& value)
{
for (std::size_t i{}; i < static_cast<std::size_t>(rowCount()); ++i)
@@ -62,7 +63,7 @@ class ValueStringModel : public Wt::WStringListModel
return i;
}
return boost::none;
return std::nullopt;
}
void
+10 -10
View File
@@ -42,16 +42,16 @@ namespace UserInterface {
Artist::Artist(Filters* filters)
: _filters(filters)
{
wApp->internalPathChanged().connect(std::bind([=]
wApp->internalPathChanged().connect([=]
{
refresh();
}));
});
refresh();
filters->updated().connect(std::bind([=] {
filters->updated().connect([=] {
refresh();
}));
});
}
void
@@ -162,13 +162,13 @@ Artist::refresh()
entry->bindWidget("artist", LmsApplication::createArtistAnchor(artists.front()));
}
boost::optional<int> year = release->getReleaseYear();
std::optional<int> year {release->getReleaseYear()};
if (year)
{
entry->setCondition("if-has-year", true);
entry->bindInt("year", *year);
boost::optional<int> originalYear = release->getReleaseYear(true);
std::optional<int> originalYear {release->getReleaseYear(true)};
if (originalYear && *originalYear != *year)
{
entry->setCondition("if-has-orig-year", true);
@@ -177,16 +177,16 @@ Artist::refresh()
}
Wt::WText* playBtn = entry->bindNew<Wt::WText>("play-btn", Wt::WString::tr("Lms.Explore.template.play-btn"), Wt::TextFormat::XHTML);
playBtn->clicked().connect(std::bind([=]
playBtn->clicked().connect([=]
{
releasesPlay.emit({releaseId});
}));
});
Wt::WText* addBtn = entry->bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
addBtn->clicked().connect([=]
{
releasesAdd.emit({releaseId});
}));
});
}
}
+2 -2
View File
@@ -76,8 +76,8 @@ ReleaseInfo::refresh()
if (!release)
return;
boost::optional<std::string> copyright {release->getCopyright()};
boost::optional<std::string> copyrightURL {release->getCopyrightURL()};
std::optional<std::string> copyright {release->getCopyright()};
std::optional<std::string> copyrightURL {release->getCopyrightURL()};
setCondition("if-has-copyright-or-copyright-url", copyright || copyrightURL);
+2 -2
View File
@@ -81,13 +81,13 @@ Release::refresh()
t->bindString("name", Wt::WString::fromUTF8(release->getName()), Wt::TextFormat::Plain);
boost::optional<int> year {release->getReleaseYear()};
std::optional<int> year {release->getReleaseYear()};
if (year)
{
t->setCondition("if-has-year", true);
t->bindInt("year", *year);
boost::optional<int> originalYear {release->getReleaseYear(true)};
std::optional<int> originalYear {release->getReleaseYear(true)};
if (originalYear && *originalYear != *year)
{
t->setCondition("if-has-orig-year", true);
+1 -1
View File
@@ -135,7 +135,7 @@ Releases::addSome()
}
std::vector<Database::IdType>
Releases::getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const
Releases::getReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit, bool& moreResults) const
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
+2 -2
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
@@ -44,7 +44,7 @@ class Releases : public Wt::WTemplate
void refresh();
void addSome();
std::vector<Database::IdType> getReleases(boost::optional<std::size_t> offset, boost::optional<std::size_t> limit, bool& moreResults) const;
std::vector<Database::IdType> getReleases(std::optional<std::size_t> offset, std::optional<std::size_t> limit, bool& moreResults) const;
std::vector<Database::IdType> getReleases() const;
Filters* _filters;
+7 -7
View File
@@ -40,8 +40,8 @@ using namespace Database;
namespace UserInterface {
Tracks::Tracks(Filters* filters)
: Wt::WTemplate(Wt::WString::tr("Lms.Explore.Tracks.template")),
_filters(filters)
: Wt::WTemplate {Wt::WString::tr("Lms.Explore.Tracks.template")},
_filters {filters}
{
addFunction("tr", &Wt::WTemplate::Functions::tr);
@@ -56,18 +56,18 @@ _filters(filters)
});
Wt::WText* addBtn = bindNew<Wt::WText>("add-btn", Wt::WString::tr("Lms.Explore.template.add-btn"), Wt::TextFormat::XHTML);
addBtn->clicked().connect(std::bind([=]
addBtn->clicked().connect([=]
{
tracksAdd.emit(getTracks());
}));
});
_tracksContainer = bindNew<Wt::WContainerWidget>("tracks");
_showMore = bindNew<Wt::WPushButton>("show-more", Wt::WString::tr("Lms.Explore.show-more"));
_showMore->clicked().connect(std::bind([=]
_showMore->clicked().connect([=]
{
addSome();
}));
});
refresh();
@@ -75,7 +75,7 @@ _filters(filters)
}
std::vector<Database::IdType>
Tracks::getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults)
Tracks::getTracks(std::optional<std::size_t> offset, std::optional<std::size_t> size, bool& moreResults)
{
const auto searchKeywords {splitString(_search->text().toUTF8(), " ")};
const auto clusterIds {_filters->getClusterIds()};
+2 -2
View File
@@ -19,7 +19,7 @@
#pragma once
#include <boost/optional.hpp>
#include <optional>
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
@@ -43,7 +43,7 @@ class Tracks : public Wt::WTemplate
void refresh();
void addSome();
std::vector<Database::IdType> getTracks(boost::optional<std::size_t> offset, boost::optional<std::size_t> size, bool& moreResults);
std::vector<Database::IdType> getTracks(std::optional<std::size_t> offset, std::optional<std::size_t> size, bool& moreResults);
std::vector<Database::IdType> getTracks();
Wt::WContainerWidget* _tracksContainer;
+5 -7
View File
@@ -19,12 +19,10 @@
#include "Config.hpp"
#include <sstream>
#include "utils/Logger.hpp"
Config::Config(const boost::filesystem::path& p)
Config::Config(const std::filesystem::path& p)
{
_config.readFile(p.string().c_str());
}
@@ -35,7 +33,7 @@ Config::getString(const std::string& setting, const std::string& def, const std:
try {
std::string res {(const char*)_config.lookup(setting)};
if (!allowedValues.empty() && allowedValues.find(res) == allowedValues.end())
if (!allowedValues.empty() && allowedValues.find(res) == std::cend(allowedValues))
{
LMS_LOG(MAIN, ERROR) << "Invalid setting for '" << setting << "', using default value '" << def << "'";
return def;
@@ -49,12 +47,12 @@ Config::getString(const std::string& setting, const std::string& def, const std:
}
}
boost::filesystem::path
Config::getPath(const std::string& setting, const boost::filesystem::path& path)
std::filesystem::path
Config::getPath(const std::string& setting, const std::filesystem::path& path)
{
try {
const char* res = _config.lookup(setting);
return boost::filesystem::path(std::string(res));
return std::filesystem::path {std::string(res)};
}
catch (std::exception &e)
{
+3 -3
View File
@@ -18,16 +18,16 @@
*/
#pragma once
#include <filesystem>
#include <set>
#include <boost/filesystem.hpp>
#include <libconfig.h++>
// Used to get config values from configuration files
class Config final
{
public:
Config(const boost::filesystem::path& p);
Config(const std::filesystem::path& p);
~Config() = default;
Config(const Config&) = delete;
@@ -37,7 +37,7 @@ class Config final
// Default values are returned in case of setting not found
std::string getString(const std::string& setting, const std::string& def = "", const std::set<std::string>& allowedValues = {});
boost::filesystem::path getPath(const std::string& setting, const boost::filesystem::path& def = boost::filesystem::path());
std::filesystem::path getPath(const std::string& setting, const std::filesystem::path& def = std::filesystem::path());
unsigned long getULong(const std::string& setting, unsigned long def = 0);
long getLong(const std::string& setting, long def = 0);
bool getBool(const std::string& setting, bool def = false);
+7 -7
View File
@@ -28,7 +28,7 @@
#include "utils/Exception.hpp"
#include "utils/Logger.hpp"
boost::filesystem::path searchExecPath(std::string filename)
std::filesystem::path searchExecPath(std::string filename)
{
std::string path;
@@ -42,7 +42,7 @@ boost::filesystem::path searchExecPath(std::string filename)
tokenizer tok(path, sep);
for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
{
boost::filesystem::path p = *it;
std::filesystem::path p = *it;
p /= filename;
if (!::access(p.c_str(), X_OK))
{
@@ -53,7 +53,7 @@ boost::filesystem::path searchExecPath(std::string filename)
return result;
}
void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& crc)
void computeCrc(const std::filesystem::path& p, std::vector<unsigned char>& crc)
{
using crc_type = boost::crc_32_type;
crc_type result;
@@ -87,11 +87,11 @@ void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& cr
}
}
bool ensureDirectory(boost::filesystem::path dir)
bool ensureDirectory(const std::filesystem::path& dir)
{
if (boost::filesystem::exists(dir))
return boost::filesystem::is_directory(dir);
if (std::filesystem::exists(dir))
return std::filesystem::is_directory(dir);
else
return boost::filesystem::create_directory(dir);
return std::filesystem::create_directory(dir);
}
+4 -4
View File
@@ -19,15 +19,15 @@
#pragma once
#include <filesystem>
#include <string>
#include <vector>
#include <boost/filesystem.hpp>
boost::filesystem::path searchExecPath(std::string filename);
std::filesystem::path searchExecPath(std::string filename);
void computeCrc(const boost::filesystem::path& p, std::vector<unsigned char>& checksum);
void computeCrc(const std::filesystem::path& p, std::vector<unsigned char>& checksum);
// Make sure the given path is a directory
// Create it if needed
bool ensureDirectory(boost::filesystem::path dir);
bool ensureDirectory(const std::filesystem::path& dir);
+3 -3
View File
@@ -55,7 +55,7 @@ bool readList(const std::string& str, const std::string& separators, std::list<s
}
template<>
boost::optional<std::string>
std::optional<std::string>
readAs(const std::string& str)
{
return str;
@@ -137,13 +137,13 @@ stringEndsWith(const std::string& str, const std::string& ending)
return boost::algorithm::ends_with(str, ending);
}
boost::optional<std::string>
std::optional<std::string>
stringFromHex(const std::string& str)
{
static const char lut[] {"0123456789ABCDEF"};
if (str.length() % 2 != 0)
return boost::none;
return std::nullopt;
std::string res;
res.reserve(str.length() / 2);
+5 -6
View File
@@ -22,13 +22,12 @@
#include <chrono>
#include <list>
#include <map>
#include <optional>
#include <random>
#include <string>
#include <sstream>
#include <vector>
#include <boost/optional.hpp>
#include <Wt/WDate.h>
bool
@@ -53,14 +52,14 @@ std::string
bufferToString(const std::vector<unsigned char>& data);
template<typename T>
boost::optional<T> readAs(const std::string& str)
std::optional<T> readAs(const std::string& str)
{
T res;
std::istringstream iss ( str );
iss >> res;
if (iss.fail())
return boost::none;
return std::nullopt;
return res;
}
@@ -71,7 +70,7 @@ replaceInString(const std::string& str, const std::string& from, const std::stri
bool
stringEndsWith(const std::string& str, const std::string& ending);
boost::optional<std::string>
std::optional<std::string>
stringFromHex(const std::string& str);
// warning: not efficient
@@ -105,7 +104,7 @@ void uniqueAndSortedByOccurence(In first, In last, Out out)
}
template<class T, class Compare = std::less<>>
constexpr const T& clamp( T v, T lo, T hi, Compare comp = {})
constexpr T clamp(T v, T lo, T hi, Compare comp = {})
{
assert(!comp(hi, lo));
return comp(v, lo) ? lo : comp(hi, v) ? hi : v;