Minor cleanup
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
namespace lms::core::stringUtils
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
constexpr std::pair<char, std::string_view> jsEscapeChars[]{
|
||||
{ '\\', "\\\\" },
|
||||
@@ -203,7 +203,7 @@ namespace lms::core::stringUtils
|
||||
|
||||
return std::distance(std::cbegin(months), str) + 1;
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
template<>
|
||||
std::optional<std::string> readAs(std::string_view str)
|
||||
@@ -240,32 +240,32 @@ namespace lms::core::stringUtils
|
||||
|
||||
std::vector<std::string_view> splitString(std::string_view str, std::span<const std::string_view> separators)
|
||||
{
|
||||
return details::splitString(str, separators);
|
||||
return detail::splitString(str, separators);
|
||||
}
|
||||
|
||||
std::vector<std::string_view> splitString(std::string_view str, std::span<const std::string> separators)
|
||||
{
|
||||
return details::splitString(str, separators);
|
||||
return detail::splitString(str, separators);
|
||||
}
|
||||
|
||||
std::string joinStrings(std::span<const std::string_view> strings, std::string_view delimiter)
|
||||
{
|
||||
return details::joinStrings(strings, delimiter);
|
||||
return detail::joinStrings(strings, delimiter);
|
||||
}
|
||||
|
||||
std::string joinStrings(std::span<const std::string> strings, std::string_view delimiter)
|
||||
{
|
||||
return details::joinStrings(strings, delimiter);
|
||||
return detail::joinStrings(strings, delimiter);
|
||||
}
|
||||
|
||||
std::string joinStrings(std::span<const std::string> strings, char delimiter)
|
||||
{
|
||||
return details::joinStrings(strings, std::string_view{ &delimiter, 1 });
|
||||
return detail::joinStrings(strings, std::string_view{ &delimiter, 1 });
|
||||
}
|
||||
|
||||
std::string joinStrings(std::span<const std::string_view> strings, char delimiter)
|
||||
{
|
||||
return details::joinStrings(strings, std::string_view{ &delimiter, 1 });
|
||||
return detail::joinStrings(strings, std::string_view{ &delimiter, 1 });
|
||||
}
|
||||
|
||||
std::string escapeAndJoinStrings(std::span<const std::string_view> strings, char delimiter, char escapeChar)
|
||||
@@ -434,32 +434,32 @@ namespace lms::core::stringUtils
|
||||
|
||||
std::string jsEscape(std::string_view str)
|
||||
{
|
||||
return details::escape(str, details::jsEscapeChars);
|
||||
return detail::escape(str, detail::jsEscapeChars);
|
||||
}
|
||||
|
||||
void writeJSEscapedString(std::ostream& os, std::string_view str)
|
||||
{
|
||||
details::writeEscapedString(os, str, details::jsEscapeChars);
|
||||
detail::writeEscapedString(os, str, detail::jsEscapeChars);
|
||||
}
|
||||
|
||||
std::string jsonEscape(std::string_view str)
|
||||
{
|
||||
return details::escape(str, details::jsonEscapeChars);
|
||||
return detail::escape(str, detail::jsonEscapeChars);
|
||||
}
|
||||
|
||||
void writeJsonEscapedString(std::ostream& os, std::string_view str)
|
||||
{
|
||||
details::writeEscapedString(os, str, details::jsonEscapeChars);
|
||||
detail::writeEscapedString(os, str, detail::jsonEscapeChars);
|
||||
}
|
||||
|
||||
std::string xmlEscape(std::string_view str)
|
||||
{
|
||||
return details::escape(str, details::xmlEscapeChars);
|
||||
return detail::escape(str, detail::xmlEscapeChars);
|
||||
}
|
||||
|
||||
void writeXmlEscapedString(std::ostream& os, std::string_view str)
|
||||
{
|
||||
details::writeEscapedString(os, str, details::xmlEscapeChars);
|
||||
detail::writeEscapedString(os, str, detail::xmlEscapeChars);
|
||||
}
|
||||
|
||||
std::string escapeString(std::string_view str, std::string_view charsToEscape, char escapeChar)
|
||||
@@ -611,11 +611,11 @@ namespace lms::core::stringUtils
|
||||
timeStr += ":00";
|
||||
|
||||
// Normalize zone
|
||||
const std::optional<std::chrono::minutes> offset{ details::getRFC822ZoneOffset(zoneStr) };
|
||||
const std::optional<std::chrono::minutes> offset{ detail::getRFC822ZoneOffset(zoneStr) };
|
||||
if (!offset)
|
||||
return {};
|
||||
|
||||
std::optional<unsigned> month{ details::getRFC822Month(monthStr) };
|
||||
std::optional<unsigned> month{ detail::getRFC822Month(monthStr) };
|
||||
if (!month)
|
||||
return {};
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
namespace lms::core
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
template<int... Is>
|
||||
struct Seq
|
||||
@@ -45,11 +45,11 @@ namespace lms::core
|
||||
{
|
||||
auto l = { (f(std::get<Is>(t)), 0)... };
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
template<typename... Ts, typename Func>
|
||||
void forEachTypeInTuple(std::tuple<Ts...> const& t, Func f)
|
||||
{
|
||||
details::forEachTypeInTuple(t, f, details::GenSeq<sizeof...(Ts)>());
|
||||
detail::forEachTypeInTuple(t, f, detail::GenSeq<sizeof...(Ts)>());
|
||||
}
|
||||
} // namespace lms::core
|
||||
@@ -42,7 +42,7 @@ namespace lms::db::utils
|
||||
|
||||
Wt::WDateTime normalizeDateTime(const Wt::WDateTime& dateTime);
|
||||
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
template<typename Query>
|
||||
void recordQueryPlanIfNeeded(const Query& query)
|
||||
@@ -50,7 +50,7 @@ namespace lms::db::utils
|
||||
if (IQueryPlanRecorder * recorder{ core::Service<IQueryPlanRecorder>::get() })
|
||||
static_cast<QueryPlanRecorder*>(recorder)->recordQueryPlanIfNeeded(query.session(), query.asString());
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
template<typename Query>
|
||||
void applyRange(Query& query, std::optional<Range> range)
|
||||
@@ -100,7 +100,7 @@ namespace lms::db::utils
|
||||
template<typename Query, typename UnaryFunc>
|
||||
void forEachQueryResult(const Query& query, UnaryFunc&& func)
|
||||
{
|
||||
details::recordQueryPlanIfNeeded(query);
|
||||
detail::recordQueryPlanIfNeeded(query);
|
||||
|
||||
LMS_SCOPED_TRACE_DETAILED_WITH_ARG("Database", "ForEachQueryResult", "Query", query.asString());
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace lms::db::utils
|
||||
template<typename T, typename Query>
|
||||
std::vector<T> fetchQueryResults(const Query& query)
|
||||
{
|
||||
details::recordQueryPlanIfNeeded(query);
|
||||
detail::recordQueryPlanIfNeeded(query);
|
||||
|
||||
LMS_SCOPED_TRACE_DETAILED_WITH_ARG("Database", "FetchQueryResults", "Query", query.asString());
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace lms::db::utils
|
||||
template<typename Query>
|
||||
std::vector<typename QueryResultType<Query>::type> fetchQueryResults(const Query& query)
|
||||
{
|
||||
details::recordQueryPlanIfNeeded(query);
|
||||
detail::recordQueryPlanIfNeeded(query);
|
||||
|
||||
LMS_SCOPED_TRACE_DETAILED_WITH_ARG("Database", "FetchQueryResults", "Query", query.asString());
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace lms::db::utils
|
||||
template<typename Query>
|
||||
auto fetchQuerySingleResult(const Query& query)
|
||||
{
|
||||
details::recordQueryPlanIfNeeded(query);
|
||||
detail::recordQueryPlanIfNeeded(query);
|
||||
|
||||
LMS_SCOPED_TRACE_DETAILED_WITH_ARG("Database", "FetchQuerySingleResult", "Query", query.asString());
|
||||
return query.resultValue();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace lms::feedback
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
template<typename StarredObjType>
|
||||
void onStarred(db::Session& session, typename StarredObjType::IdType id)
|
||||
@@ -46,7 +46,7 @@ namespace lms::feedback
|
||||
if (auto starredObj{ StarredObjType::find(session, id) })
|
||||
starredObj.remove();
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
InternalBackend::InternalBackend(db::IDb& db)
|
||||
: _db{ db }
|
||||
@@ -55,31 +55,31 @@ namespace lms::feedback
|
||||
|
||||
void InternalBackend::onStarred(db::StarredArtistId artistId)
|
||||
{
|
||||
details::onStarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
detail::onStarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredArtistId artistId)
|
||||
{
|
||||
details::onUnstarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
detail::onUnstarred<db::StarredArtist>(_db.getTLSSession(), artistId);
|
||||
}
|
||||
|
||||
void InternalBackend::onStarred(db::StarredReleaseId releaseId)
|
||||
{
|
||||
details::onStarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
detail::onStarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredReleaseId releaseId)
|
||||
{
|
||||
details::onUnstarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
detail::onUnstarred<db::StarredRelease>(_db.getTLSSession(), releaseId);
|
||||
}
|
||||
|
||||
void InternalBackend::onStarred(db::StarredTrackId trackId)
|
||||
{
|
||||
details::onStarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
detail::onStarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
}
|
||||
|
||||
void InternalBackend::onUnstarred(db::StarredTrackId trackId)
|
||||
{
|
||||
details::onUnstarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
detail::onUnstarred<db::StarredTrack>(_db.getTLSSession(), trackId);
|
||||
}
|
||||
} // namespace lms::feedback
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
namespace lms::feedback::listenBrainz
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
template<typename StarredObjType>
|
||||
void onStarred(db::Session& session, typename StarredObjType::IdType id)
|
||||
@@ -54,7 +54,7 @@ namespace lms::feedback::listenBrainz
|
||||
if (auto starredObj{ StarredObjType::find(session, id) })
|
||||
starredObj.remove();
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
ListenBrainzBackend::ListenBrainzBackend(boost::asio::io_context& ioContext, db::IDb& db)
|
||||
: _ioContext{ ioContext }
|
||||
@@ -73,22 +73,22 @@ namespace lms::feedback::listenBrainz
|
||||
|
||||
void ListenBrainzBackend::onStarred(db::StarredArtistId starredArtistId)
|
||||
{
|
||||
details::onStarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
detail::onStarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
}
|
||||
|
||||
void ListenBrainzBackend::onUnstarred(db::StarredArtistId starredArtistId)
|
||||
{
|
||||
details::onUnstarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
detail::onUnstarred<db::StarredArtist>(_db.getTLSSession(), starredArtistId);
|
||||
}
|
||||
|
||||
void ListenBrainzBackend::onStarred(db::StarredReleaseId starredReleaseId)
|
||||
{
|
||||
details::onStarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
detail::onStarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
}
|
||||
|
||||
void ListenBrainzBackend::onUnstarred(db::StarredReleaseId starredReleaseId)
|
||||
{
|
||||
details::onUnstarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
detail::onUnstarred<db::StarredRelease>(_db.getTLSSession(), starredReleaseId);
|
||||
}
|
||||
|
||||
void ListenBrainzBackend::onStarred(db::StarredTrackId starredTrackId)
|
||||
|
||||
@@ -92,25 +92,25 @@ namespace lms::api::subsonic
|
||||
transcodeNode.addChild("sourceStream", createStreamDetails(sourceStream));
|
||||
}
|
||||
|
||||
const details::TranscodeDecisionResult transcodeDecision{ details::computeTranscodeDecision(clientInfo, audioFileInfo.audioProperties) };
|
||||
const detail::TranscodeDecisionResult transcodeDecision{ detail::computeTranscodeDecision(clientInfo, audioFileInfo.audioProperties) };
|
||||
|
||||
std::visit(core::utils::overloads{
|
||||
[&](const details::DirectPlayResult&) {
|
||||
[&](const detail::DirectPlayResult&) {
|
||||
transcodeNode.setAttribute("canDirectPlay", true);
|
||||
transcodeNode.setAttribute("canTranscode", false);
|
||||
},
|
||||
[&](const details::TranscodeResult& transcodeRes) {
|
||||
[&](const detail::TranscodeResult& transcodeRes) {
|
||||
transcodeNode.setAttribute("canDirectPlay", false);
|
||||
transcodeNode.setAttribute("canTranscode", true);
|
||||
|
||||
for (details::TranscodeReason reason : transcodeRes.reasons)
|
||||
for (detail::TranscodeReason reason : transcodeRes.reasons)
|
||||
transcodeNode.addArrayValue("transcodeReason", transcodeReasonToString(reason).str());
|
||||
|
||||
const core::UUID uuid{ getTranscodeDecisionTracker().add(audioFileId, transcodeRes.targetStreamInfo) };
|
||||
transcodeNode.addChild("transcodeStream", createStreamDetails(transcodeRes.targetStreamInfo));
|
||||
transcodeNode.setAttribute("transcodeParams", uuid.getAsString());
|
||||
},
|
||||
[&](const details::FailureResult& failureRes) {
|
||||
[&](const detail::FailureResult& failureRes) {
|
||||
transcodeNode.setAttribute("canDirectPlay", false);
|
||||
transcodeNode.setAttribute("canTranscode", false);
|
||||
transcodeNode.setAttribute("errorReason", failureRes.reason);
|
||||
@@ -149,7 +149,7 @@ namespace lms::api::subsonic
|
||||
|
||||
params.outputParameters.stripMetadata = false;
|
||||
|
||||
const audio::TranscodeOutputFormat* transcodeOutputFormat{ details::selectTranscodeOutputFormat(entry->targetStreamInfo.container, entry->targetStreamInfo.codec) };
|
||||
const audio::TranscodeOutputFormat* transcodeOutputFormat{ detail::selectTranscodeOutputFormat(entry->targetStreamInfo.container, entry->targetStreamInfo.codec) };
|
||||
if (!transcodeOutputFormat)
|
||||
throw InternalErrorGenericError{ "Unsupported output format" };
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "SubsonicResponse.hpp"
|
||||
#include "payloads/ClientInfo.hpp"
|
||||
|
||||
namespace lms::api::subsonic::details
|
||||
namespace lms::api::subsonic::detail
|
||||
{
|
||||
namespace
|
||||
{
|
||||
@@ -592,4 +592,4 @@ namespace lms::api::subsonic::details
|
||||
|
||||
return FailureResult{ "No compatible direct play or transcoding profile found" };
|
||||
}
|
||||
} // namespace lms::api::subsonic::details
|
||||
} // namespace lms::api::subsonic::detail
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace lms::api::subsonic
|
||||
{
|
||||
struct ClientInfo;
|
||||
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
enum class TranscodeReason
|
||||
{
|
||||
@@ -72,5 +72,5 @@ namespace lms::api::subsonic
|
||||
TranscodeDecisionResult computeTranscodeDecision(const ClientInfo& clientInfo, const audio::AudioProperties& source);
|
||||
|
||||
const audio::TranscodeOutputFormat* selectTranscodeOutputFormat(std::string_view containerName, std::string_view codecName);
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
} // namespace lms::api::subsonic
|
||||
|
||||
@@ -30,14 +30,14 @@
|
||||
|
||||
namespace lms::api::subsonic
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, const details::TranscodeDecisionResult& result)
|
||||
std::ostream& operator<<(std::ostream& os, const detail::TranscodeDecisionResult& result)
|
||||
{
|
||||
std::visit(core::utils::overloads{
|
||||
[&](const details::DirectPlayResult&) { os << "direct play"; },
|
||||
[&](const details::FailureResult& res) { os << "failure: " << res.reason; },
|
||||
[&](const details::TranscodeResult& res) {
|
||||
[&](const detail::DirectPlayResult&) { os << "direct play"; },
|
||||
[&](const detail::FailureResult& res) { os << "failure: " << res.reason; },
|
||||
[&](const detail::TranscodeResult& res) {
|
||||
os << "transcode: reasons = {";
|
||||
|
||||
bool firstReason{ true };
|
||||
@@ -66,7 +66,7 @@ namespace lms::api::subsonic
|
||||
|
||||
return os;
|
||||
} // namespace
|
||||
}; // namespace details
|
||||
}; // namespace detail
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -75,7 +75,7 @@ namespace lms::api::subsonic
|
||||
ClientInfo clientInfo;
|
||||
audio::AudioProperties source;
|
||||
|
||||
details::TranscodeDecisionResult expected;
|
||||
detail::TranscodeDecisionResult expected;
|
||||
};
|
||||
|
||||
void processTests(std::span<const TestCase> testCases)
|
||||
@@ -83,7 +83,7 @@ namespace lms::api::subsonic
|
||||
for (std::size_t testCaseIndex{ 0 }; testCaseIndex < std::size(testCases); ++testCaseIndex)
|
||||
{
|
||||
const auto& testCase{ testCases[testCaseIndex] };
|
||||
const details::TranscodeDecisionResult decision{ details::computeTranscodeDecision(testCase.clientInfo, testCase.source) };
|
||||
const detail::TranscodeDecisionResult decision{ detail::computeTranscodeDecision(testCase.clientInfo, testCase.source) };
|
||||
|
||||
EXPECT_EQ(testCase.expected, decision) << "testCaseIndex: " << testCaseIndex;
|
||||
}
|
||||
@@ -120,7 +120,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::DirectPlayResult{} },
|
||||
.expected = { detail::DirectPlayResult{} },
|
||||
},
|
||||
|
||||
// Needs transcode due to codec limitation
|
||||
@@ -150,7 +150,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// Needs transcode due to global limitation on the direct play bitrate
|
||||
@@ -180,7 +180,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// Needs transcode due to codec limitation, but global limitation is even more restrictive
|
||||
@@ -210,7 +210,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// Needs transcode due to max audio sample rate not handle by codec limitation
|
||||
@@ -240,7 +240,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioSampleRateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioSampleRateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// Needs transcode due to max nb channels not handle by profile
|
||||
@@ -264,7 +264,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioChannelsNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = 2, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioChannelsNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = 2, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// Needs transcode due to max nb channels not handle by codec. TODO take channel reduction into account for bitrate
|
||||
@@ -292,7 +292,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioChannelsNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = 2, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioChannelsNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = 2, .audioBitrate = 192'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// needs transcode because codec not handled
|
||||
@@ -320,7 +320,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 128'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 128'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// needs transcode because codec not handled (lossless source => using max bitrate)
|
||||
@@ -348,7 +348,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 16,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 320000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 320000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// needs transcode because codec not handled (lossless source => using a default good bitrate)
|
||||
@@ -371,7 +371,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 16,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 256000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 256000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// check protocol * and codec * are properly handled
|
||||
@@ -397,7 +397,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::DirectPlayResult{} },
|
||||
.expected = { detail::DirectPlayResult{} },
|
||||
},
|
||||
|
||||
// check container * is properly handled
|
||||
@@ -423,7 +423,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::DirectPlayResult{} },
|
||||
.expected = { detail::DirectPlayResult{} },
|
||||
},
|
||||
|
||||
// want flac but bitrate too high
|
||||
@@ -449,7 +449,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 16,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "ogg", .codec = "opus", .audioChannels = std::nullopt, .audioBitrate = 320'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "ogg", .codec = "opus", .audioChannels = std::nullopt, .audioBitrate = 320'000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// want flac but source sample rate is too high
|
||||
@@ -487,7 +487,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 24,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioSampleRateNotSupported, details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioSampleRateNotSupported, detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// want flac but source sample rate is too high, no max bitrate
|
||||
@@ -526,7 +526,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 24,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioSampleRateNotSupported, details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioSampleRateNotSupported, detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// wants a lossy codec not handled -> transcode to lossy
|
||||
@@ -564,7 +564,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 16,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 128000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 128000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// wants a lossless codec not handled -> transcode to lossless
|
||||
@@ -602,7 +602,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = 24,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported, details::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported, detail::TranscodeReason::ContainerNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "flac", .codec = "flac", .audioChannels = std::nullopt, .audioBitrate = std::nullopt, .audioProfile = "", .audioSamplerate = 48'000, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
|
||||
// no protocol specified
|
||||
@@ -632,7 +632,7 @@ namespace lms::api::subsonic
|
||||
.bitsPerSample = std::nullopt,
|
||||
},
|
||||
|
||||
.expected = { details::TranscodeResult{ .reasons = { details::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
.expected = { detail::TranscodeResult{ .reasons = { detail::TranscodeReason::AudioBitrateNotSupported }, .targetStreamInfo = { .protocol = "http", .container = "mp3", .codec = "mp3", .audioChannels = std::nullopt, .audioBitrate = 96000, .audioProfile = "", .audioSamplerate = std::nullopt, .audioBitdepth = std::nullopt } } },
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "LmsApplication.hpp"
|
||||
|
||||
namespace lms::ui::state::details
|
||||
namespace lms::ui::state::detail
|
||||
{
|
||||
void writeValue(std::string_view item, std::string_view value)
|
||||
{
|
||||
@@ -81,5 +81,4 @@ namespace lms::ui::state::details
|
||||
state.remove();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace lms::ui::state::details
|
||||
} // namespace lms::ui::state::detail
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
|
||||
namespace lms::ui::state
|
||||
{
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
std::optional<std::string> readValue(std::string_view item);
|
||||
void writeValue(std::string_view item, std::string_view value);
|
||||
void eraseValue(std::string_view item);
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
void writeValue(std::string_view item, std::optional<T> value)
|
||||
@@ -40,18 +40,18 @@ namespace lms::ui::state
|
||||
if (value.has_value())
|
||||
{
|
||||
if constexpr (std::is_enum_v<T>)
|
||||
details::writeValue(item, std::to_string(static_cast<std::underlying_type_t<T>>(*value)));
|
||||
detail::writeValue(item, std::to_string(static_cast<std::underlying_type_t<T>>(*value)));
|
||||
else
|
||||
details::writeValue(item, std::to_string(*value));
|
||||
detail::writeValue(item, std::to_string(*value));
|
||||
}
|
||||
else
|
||||
details::eraseValue(item);
|
||||
detail::eraseValue(item);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<T> readValue(std::string_view item)
|
||||
{
|
||||
if (std::optional<std::string> res{ details::readValue(item) })
|
||||
if (std::optional<std::string> res{ detail::readValue(item) })
|
||||
return core::stringUtils::readAs<T>(*res);
|
||||
|
||||
return std::nullopt;
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace lms::ui
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace details
|
||||
namespace detail
|
||||
{
|
||||
std::string getTrackPathName(const db::Track::pointer& track)
|
||||
{
|
||||
@@ -165,7 +165,7 @@ namespace lms::ui
|
||||
|
||||
return zip::createArchiveZipper(files);
|
||||
}
|
||||
} // namespace details
|
||||
} // namespace detail
|
||||
|
||||
DownloadArtistResource::DownloadArtistResource(db::ArtistId artistId)
|
||||
: _artistId{ artistId }
|
||||
@@ -182,7 +182,7 @@ namespace lms::ui
|
||||
auto transaction{ LmsApp->getDbSession().createReadTransaction() };
|
||||
|
||||
const auto trackResults{ db::Track::find(LmsApp->getDbSession(), db::Track::FindParameters{}.setArtist(_artistId).setSortMethod(db::TrackSortMethod::DateDescAndRelease)) };
|
||||
return details::createZipper(trackResults.results);
|
||||
return detail::createZipper(trackResults.results);
|
||||
}
|
||||
|
||||
DownloadReleaseResource::DownloadReleaseResource(db::ReleaseId releaseId)
|
||||
@@ -200,7 +200,7 @@ namespace lms::ui
|
||||
auto transaction{ LmsApp->getDbSession().createReadTransaction() };
|
||||
|
||||
auto tracks{ db::Track::find(LmsApp->getDbSession(), db::Track::FindParameters{}.setRelease(_releaseId).setSortMethod(db::TrackSortMethod::Release)) };
|
||||
return details::createZipper(tracks.results);
|
||||
return detail::createZipper(tracks.results);
|
||||
}
|
||||
|
||||
DownloadTrackResource::DownloadTrackResource(db::TrackId trackId)
|
||||
@@ -210,7 +210,7 @@ namespace lms::ui
|
||||
|
||||
db::Track::pointer track{ db::Track::find(LmsApp->getDbSession(), trackId) };
|
||||
if (track)
|
||||
suggestFileName(details::getTrackPathName(track) + ".zip");
|
||||
suggestFileName(detail::getTrackPathName(track) + ".zip");
|
||||
}
|
||||
|
||||
std::unique_ptr<zip::IZipper> DownloadTrackResource::createZipper()
|
||||
@@ -224,7 +224,7 @@ namespace lms::ui
|
||||
return {};
|
||||
}
|
||||
|
||||
return details::createZipper({ track });
|
||||
return detail::createZipper({ track });
|
||||
}
|
||||
|
||||
DownloadTrackListResource::DownloadTrackListResource(db::TrackListId trackListId)
|
||||
@@ -234,7 +234,7 @@ namespace lms::ui
|
||||
|
||||
const db::TrackList::pointer trackList{ db::TrackList::find(LmsApp->getDbSession(), trackListId) };
|
||||
if (trackList)
|
||||
suggestFileName(details::getTrackListPathName(trackList) + ".zip");
|
||||
suggestFileName(detail::getTrackListPathName(trackList) + ".zip");
|
||||
}
|
||||
|
||||
std::unique_ptr<zip::IZipper> DownloadTrackListResource::createZipper()
|
||||
@@ -244,6 +244,6 @@ namespace lms::ui
|
||||
db::Track::FindParameters params;
|
||||
params.setTrackList(_trackListId);
|
||||
const auto tracks{ db::Track::find(LmsApp->getDbSession(), params) };
|
||||
return details::createZipper(tracks.results);
|
||||
return detail::createZipper(tracks.results);
|
||||
}
|
||||
} // namespace lms::ui
|
||||
|
||||
Reference in New Issue
Block a user