Exposed release date at release level (instead of just year)
This commit is contained in:
@@ -149,11 +149,11 @@ ClusterType::findUsed(Session& session, Range range)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ClusterType::pointer
|
ClusterType::pointer
|
||||||
ClusterType::find(Session& session, const std::string& name)
|
ClusterType::find(Session& session, std::string_view name)
|
||||||
{
|
{
|
||||||
session.checkSharedLocked();
|
session.checkSharedLocked();
|
||||||
|
|
||||||
return session.getDboSession().find<ClusterType>().where("name = ?").bind(name).resultValue();
|
return session.getDboSession().find<ClusterType>().where("name = ?").bind(std::string {name}).resultValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
ClusterType::pointer
|
ClusterType::pointer
|
||||||
|
|||||||
@@ -287,8 +287,20 @@ Release::getDiscCount() const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<int>
|
Wt::WDate
|
||||||
Release::getReleaseYear(bool original) const
|
Release::getReleaseDate() const
|
||||||
|
{
|
||||||
|
return getReleaseDate(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wt::WDate
|
||||||
|
Release::getOriginalReleaseDate() const
|
||||||
|
{
|
||||||
|
return getReleaseDate(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wt::WDate
|
||||||
|
Release::getReleaseDate(bool original) const
|
||||||
{
|
{
|
||||||
assert(session());
|
assert(session());
|
||||||
|
|
||||||
@@ -301,16 +313,11 @@ Release::getReleaseYear(bool original) const
|
|||||||
.bind(getId())
|
.bind(getId())
|
||||||
.resultList()};
|
.resultList()};
|
||||||
|
|
||||||
// various dates => no date
|
// various dates => invalid date
|
||||||
if (dates.empty() || dates.size() > 1)
|
if (dates.empty() || dates.size() > 1)
|
||||||
return std::nullopt;
|
return {};
|
||||||
|
|
||||||
auto date {dates.front().year()};
|
return dates.front();
|
||||||
|
|
||||||
if (date > 0)
|
|
||||||
return date;
|
|
||||||
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string>
|
std::optional<std::string>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class ClusterType final : public Object<ClusterType, ClusterTypeId>
|
|||||||
// Getters
|
// Getters
|
||||||
static std::size_t getCount(Session& session);
|
static std::size_t getCount(Session& session);
|
||||||
static RangeResults<ClusterTypeId> find(Session& session, Range range);
|
static RangeResults<ClusterTypeId> find(Session& session, Range range);
|
||||||
static pointer find(Session& session, const std::string& name);
|
static pointer find(Session& session, std::string_view name);
|
||||||
static pointer find(Session& session, ClusterTypeId id);
|
static pointer find(Session& session, ClusterTypeId id);
|
||||||
static RangeResults<ClusterTypeId> findOrphans(Session& session, Range range);
|
static RangeResults<ClusterTypeId> findOrphans(Session& session, Range range);
|
||||||
static RangeResults<ClusterTypeId> findUsed(Session& session, Range range);
|
static RangeResults<ClusterTypeId> findUsed(Session& session, Range range);
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ class Release final : public Object<Release, ReleaseId>
|
|||||||
std::vector<std::vector<ObjectPtr<Cluster>>> getClusterGroups(const std::vector<ObjectPtr<ClusterType>>& clusterTypes, std::size_t size) const;
|
std::vector<std::vector<ObjectPtr<Cluster>>> getClusterGroups(const std::vector<ObjectPtr<ClusterType>>& clusterTypes, std::size_t size) const;
|
||||||
|
|
||||||
// Utility functions (if all tracks have the same values, which is legit to not be the case)
|
// Utility functions (if all tracks have the same values, which is legit to not be the case)
|
||||||
std::optional<int> getReleaseYear(bool originalDate = false) const;
|
Wt::WDate getReleaseDate() const;
|
||||||
|
Wt::WDate getOriginalReleaseDate() const;
|
||||||
std::optional<std::string> getCopyright() const;
|
std::optional<std::string> getCopyright() const;
|
||||||
std::optional<std::string> getCopyrightURL() const;
|
std::optional<std::string> getCopyrightURL() const;
|
||||||
|
|
||||||
@@ -145,6 +146,8 @@ class Release final : public Object<Release, ReleaseId>
|
|||||||
Release(const std::string& name, const std::optional<UUID>& MBID = {});
|
Release(const std::string& name, const std::optional<UUID>& MBID = {});
|
||||||
static pointer create(Session& session, const std::string& name, const std::optional<UUID>& MBID = {});
|
static pointer create(Session& session, const std::string& name, const std::optional<UUID>& MBID = {});
|
||||||
|
|
||||||
|
Wt::WDate getReleaseDate(bool original) const;
|
||||||
|
|
||||||
static constexpr std::size_t _maxNameLength {128};
|
static constexpr std::size_t _maxNameLength {128};
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
|||||||
@@ -350,8 +350,8 @@ TEST_F(DatabaseFixture, MultiTracksSingleReleaseDate)
|
|||||||
track1A.get().modify()->setOriginalDate(release1OriginalDate);
|
track1A.get().modify()->setOriginalDate(release1OriginalDate);
|
||||||
track1B.get().modify()->setOriginalDate(release1OriginalDate);
|
track1B.get().modify()->setOriginalDate(release1OriginalDate);
|
||||||
|
|
||||||
EXPECT_EQ(release1.get()->getReleaseYear(), release1Date.year());
|
EXPECT_EQ(release1.get()->getReleaseDate(), release1Date);
|
||||||
EXPECT_EQ(release1.get()->getReleaseYear(true), release1OriginalDate.year());
|
EXPECT_EQ(release1.get()->getOriginalReleaseDate(), release1OriginalDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,14 +57,11 @@
|
|||||||
|
|
||||||
using namespace Database;
|
using namespace Database;
|
||||||
|
|
||||||
static const std::string genreClusterName {"GENRE"};
|
static const std::string_view genreClusterName {"GENRE"};
|
||||||
static const std::string reportedStarredDate {"2000-01-01T00:00:00"};
|
static const std::string_view reportedStarredDate {"2000-01-01T00:00:00"};
|
||||||
static const std::string reportedDummyDate {"2000-01-01T00:00:00"};
|
static const std::string_view reportedDummyDate {"2000-01-01T00:00:00"};
|
||||||
static const unsigned long long reportedDummyDateULong {946684800000ULL}; // 2000-01-01T00:00:00 UTC
|
static const unsigned long long reportedDummyDateULong {946684800000ULL}; // 2000-01-01T00:00:00 UTC
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace API::Subsonic
|
namespace API::Subsonic
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -375,9 +372,8 @@ releaseToResponseNode(const Release::pointer& release, Session& dbSession, const
|
|||||||
albumNode.setAttribute("created", dateTimeToCreatedString(release->getLastWritten()));
|
albumNode.setAttribute("created", dateTimeToCreatedString(release->getLastWritten()));
|
||||||
albumNode.setAttribute("id", idToString(release->getId()));
|
albumNode.setAttribute("id", idToString(release->getId()));
|
||||||
albumNode.setAttribute("coverArt", idToString(release->getId()));
|
albumNode.setAttribute("coverArt", idToString(release->getId()));
|
||||||
auto releaseYear {release->getReleaseYear()};
|
if (const Wt::WDate releaseDate {release->getReleaseDate()}; releaseDate.isValid())
|
||||||
if (releaseYear)
|
albumNode.setAttribute("year", releaseDate.year());
|
||||||
albumNode.setAttribute("year", *releaseYear);
|
|
||||||
|
|
||||||
auto artists {release->getReleaseArtists()};
|
auto artists {release->getReleaseArtists()};
|
||||||
if (artists.empty())
|
if (artists.empty())
|
||||||
@@ -405,10 +401,10 @@ releaseToResponseNode(const Release::pointer& release, Session& dbSession, const
|
|||||||
if (id3)
|
if (id3)
|
||||||
{
|
{
|
||||||
// Report the first GENRE for this track
|
// Report the first GENRE for this track
|
||||||
ClusterType::pointer clusterType {ClusterType::find(dbSession, genreClusterName)};
|
ClusterType::pointer clusterType{ClusterType::find(dbSession, genreClusterName)};
|
||||||
if (clusterType)
|
if (clusterType)
|
||||||
{
|
{
|
||||||
auto clusters {release->getClusterGroups({clusterType}, 1)};
|
auto clusters{release->getClusterGroups({clusterType}, 1)};
|
||||||
if (!clusters.empty() && !clusters.front().empty())
|
if (!clusters.empty() && !clusters.front().empty())
|
||||||
albumNode.setAttribute("genre", clusters.front().front()->getName());
|
albumNode.setAttribute("genre", clusters.front().front()->getName());
|
||||||
}
|
}
|
||||||
@@ -1905,7 +1901,7 @@ struct RequestEntryPointInfo
|
|||||||
CheckImplementedFunc checkFunc {};
|
CheckImplementedFunc checkFunc {};
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<std::string, RequestEntryPointInfo> requestEntryPoints
|
static const std::unordered_map<std::string_view, RequestEntryPointInfo> requestEntryPoints
|
||||||
{
|
{
|
||||||
// System
|
// System
|
||||||
{"/ping", {handlePingRequest}},
|
{"/ping", {handlePingRequest}},
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace UserInterface::ReleaseListHelpers
|
|||||||
|
|
||||||
if (showYear)
|
if (showYear)
|
||||||
{
|
{
|
||||||
Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseYear(), release->getReleaseYear(true))};
|
Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseDate(), release->getOriginalReleaseDate())};
|
||||||
if (!year.empty())
|
if (!year.empty())
|
||||||
{
|
{
|
||||||
entry->setCondition("if-has-year", true);
|
entry->setCondition("if-has-year", true);
|
||||||
@@ -135,18 +135,18 @@ namespace UserInterface::ReleaseHelpers
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wt::WString buildReleaseYearString(std::optional<int> year, std::optional<int> originalYear)
|
Wt::WString buildReleaseYearString(const Wt::WDate& releaseDate, const Wt::WDate& originalReleaseDate)
|
||||||
{
|
{
|
||||||
Wt::WString res;
|
Wt::WString res;
|
||||||
|
|
||||||
// Year can be here, but originalYear can't be here without year (enforced by scanner)
|
// Year can be here, but originalYear can't be here without year (enforced by scanner)
|
||||||
if (!year)
|
if (!releaseDate.isValid())
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
if (originalYear && *originalYear != *year)
|
if (originalReleaseDate.isValid() && originalReleaseDate != releaseDate)
|
||||||
res = std::to_string(*originalYear) + " (" + std::to_string(*year) + ")";
|
res = std::to_string(originalReleaseDate.year()) + " (" + std::to_string(releaseDate.year()) + ")";
|
||||||
else
|
else
|
||||||
res = std::to_string(*year);
|
res = std::to_string(releaseDate.year());
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <Wt/WString.h>
|
#include <Wt/WString.h>
|
||||||
#include <Wt/WTemplate.h>
|
#include <Wt/WTemplate.h>
|
||||||
|
#include <Wt/WDate.h>
|
||||||
#include "services/database/Object.hpp"
|
#include "services/database/Object.hpp"
|
||||||
#include "services/database/Types.hpp"
|
#include "services/database/Types.hpp"
|
||||||
#include "utils/EnumSet.hpp"
|
#include "utils/EnumSet.hpp"
|
||||||
@@ -43,5 +44,5 @@ namespace UserInterface::ReleaseListHelpers
|
|||||||
namespace UserInterface::ReleaseHelpers
|
namespace UserInterface::ReleaseHelpers
|
||||||
{
|
{
|
||||||
Wt::WString buildReleaseTypeString(Database::ReleaseTypePrimary primaryType, EnumSet<Database::ReleaseTypeSecondary> secondaryTypes);
|
Wt::WString buildReleaseTypeString(Database::ReleaseTypePrimary primaryType, EnumSet<Database::ReleaseTypeSecondary> secondaryTypes);
|
||||||
Wt::WString buildReleaseYearString(std::optional<int> year, std::optional<int> originalYear);
|
Wt::WString buildReleaseYearString(const Wt::WDate& releaseDate, const Wt::WDate& originalReleaseDate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ Release::refreshView()
|
|||||||
|
|
||||||
bindString("name", Wt::WString::fromUTF8(release->getName()), Wt::TextFormat::Plain);
|
bindString("name", Wt::WString::fromUTF8(release->getName()), Wt::TextFormat::Plain);
|
||||||
|
|
||||||
Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseYear(), release->getReleaseYear(true))};
|
Wt::WString year {ReleaseHelpers::buildReleaseYearString(release->getReleaseDate(), release->getOriginalReleaseDate())};
|
||||||
if (!year.empty())
|
if (!year.empty())
|
||||||
{
|
{
|
||||||
setCondition("if-has-year", true);
|
setCondition("if-has-year", true);
|
||||||
|
|||||||
@@ -109,8 +109,8 @@ getReleasePathName(Database::Release::pointer release)
|
|||||||
{
|
{
|
||||||
std::string releaseName;
|
std::string releaseName;
|
||||||
|
|
||||||
if (auto releaseYear {release->getReleaseYear()})
|
if (const Wt::WDate releaseDate {release->getReleaseDate()}; releaseDate.isValid())
|
||||||
releaseName += std::to_string(*releaseYear) + " - ";
|
releaseName += std::to_string(releaseDate.year()) + " - ";
|
||||||
releaseName += StringUtils::replaceInString(release->getName(), "/", "_");
|
releaseName += StringUtils::replaceInString(release->getName(), "/", "_");
|
||||||
|
|
||||||
return releaseName;
|
return releaseName;
|
||||||
|
|||||||
Reference in New Issue
Block a user