Subsonic: use file added info for 'created' fields, ref #601
This commit is contained in:
@@ -708,7 +708,14 @@ namespace lms::db
|
|||||||
{
|
{
|
||||||
assert(session());
|
assert(session());
|
||||||
|
|
||||||
return utils::fetchQuerySingleResult(session()->query<Wt::WDateTime>("SELECT COALESCE(MAX(file_last_write), '1970-01-01T00:00:00') FROM track t").where("t.release_id = ?").bind(getId()));
|
return utils::fetchQuerySingleResult(session()->query<Wt::WDateTime>("SELECT MAX(file_last_write) FROM track t").where("t.release_id = ?").bind(getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
core::PartialDateTime Release::getAddedTime() const
|
||||||
|
{
|
||||||
|
assert(session());
|
||||||
|
|
||||||
|
return utils::fetchQuerySingleResult(session()->query<core::PartialDateTime>("SELECT MAX(file_added) FROM track t").where("t.release_id = ?").bind(getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::vector<Cluster::pointer>> Release::getClusterGroups(const std::vector<ClusterTypeId>& clusterTypeIds, std::size_t size) const
|
std::vector<std::vector<Cluster::pointer>> Release::getClusterGroups(const std::vector<ClusterTypeId>& clusterTypeIds, std::size_t size) const
|
||||||
|
|||||||
@@ -244,6 +244,7 @@ namespace lms::db
|
|||||||
std::size_t getDiscCount() const; // may not be total disc (if incomplete for example)
|
std::size_t getDiscCount() const; // may not be total disc (if incomplete for example)
|
||||||
std::vector<DiscInfo> getDiscs() const;
|
std::vector<DiscInfo> getDiscs() const;
|
||||||
std::chrono::milliseconds getDuration() const;
|
std::chrono::milliseconds getDuration() const;
|
||||||
|
core::PartialDateTime getAddedTime() const;
|
||||||
Wt::WDateTime getLastWritten() const;
|
Wt::WDateTime getLastWritten() const;
|
||||||
std::string_view getArtistDisplayName() const { return _artistDisplayName; }
|
std::string_view getArtistDisplayName() const { return _artistDisplayName; }
|
||||||
bool isCompilation() const { return _isCompilation; }
|
bool isCompilation() const { return _isCompilation; }
|
||||||
|
|||||||
@@ -1201,4 +1201,66 @@ namespace lms::db::tests
|
|||||||
EXPECT_EQ(releases.results[3], releaseC.getId());
|
EXPECT_EQ(releases.results[3], releaseC.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DatabaseFixture, Release_LastWritten)
|
||||||
|
{
|
||||||
|
ScopedRelease release{ session, "relA" };
|
||||||
|
|
||||||
|
ScopedTrack track1{ session };
|
||||||
|
ScopedTrack track2{ session };
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
|
Wt::WDateTime lastWritten{ release.get()->getLastWritten() };
|
||||||
|
EXPECT_FALSE(lastWritten.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createWriteTransaction() };
|
||||||
|
track1.get().modify()->setLastWriteTime(Wt::WDateTime{ Wt::WDate{ 2021, 1, 2 } });
|
||||||
|
track2.get().modify()->setLastWriteTime(Wt::WDateTime{ Wt::WDate{ 2021, 1, 2 }, Wt::WTime{ 15, 36, 24 } });
|
||||||
|
track1.get().modify()->setRelease(release.get());
|
||||||
|
track2.get().modify()->setRelease(release.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
|
Wt::WDateTime lastWritten{ release.get()->getLastWritten() };
|
||||||
|
ASSERT_TRUE(lastWritten.isValid());
|
||||||
|
EXPECT_EQ(lastWritten, track2.get()->getLastWriteTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DatabaseFixture, Release_AddedTime)
|
||||||
|
{
|
||||||
|
ScopedRelease release{ session, "relA" };
|
||||||
|
|
||||||
|
ScopedTrack track1{ session };
|
||||||
|
ScopedTrack track2{ session };
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
|
core::PartialDateTime addedTime{ release.get()->getAddedTime() };
|
||||||
|
EXPECT_FALSE(addedTime.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createWriteTransaction() };
|
||||||
|
track1.get().modify()->setAddedTime(core::PartialDateTime{ 2021, 1, 2 });
|
||||||
|
track2.get().modify()->setAddedTime(core::PartialDateTime{ 2021, 1, 2, 15, 36, 24 });
|
||||||
|
track1.get().modify()->setRelease(release.get());
|
||||||
|
track2.get().modify()->setRelease(release.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
|
||||||
|
core::PartialDateTime addedTime{ release.get()->getAddedTime() };
|
||||||
|
ASSERT_TRUE(addedTime.isValid());
|
||||||
|
EXPECT_EQ(addedTime, track2.get()->getAddedTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace lms::db::tests
|
} // namespace lms::db::tests
|
||||||
@@ -85,7 +85,7 @@ namespace lms::api::subsonic
|
|||||||
albumNode.setAttribute("isDir", true);
|
albumNode.setAttribute("isDir", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
albumNode.setAttribute("created", core::stringUtils::toISO8601String(release->getLastWritten()));
|
albumNode.setAttribute("created", release->getAddedTime().toISO8601String());
|
||||||
if (const auto image{ release->getImage() })
|
if (const auto image{ release->getImage() })
|
||||||
{
|
{
|
||||||
const CoverArtId coverArtId{ image->getId(), image->getLastWriteTime().toTime_t() };
|
const CoverArtId coverArtId{ image->getId(), image->getLastWriteTime().toTime_t() };
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace lms::api::subsonic
|
|||||||
trackResponse.setAttribute("duration", std::chrono::duration_cast<std::chrono::seconds>(track->getDuration()).count());
|
trackResponse.setAttribute("duration", std::chrono::duration_cast<std::chrono::seconds>(track->getDuration()).count());
|
||||||
trackResponse.setAttribute("bitRate", (track->getBitrate() / 1000));
|
trackResponse.setAttribute("bitRate", (track->getBitrate() / 1000));
|
||||||
trackResponse.setAttribute("type", "music");
|
trackResponse.setAttribute("type", "music");
|
||||||
trackResponse.setAttribute("created", core::stringUtils::toISO8601String(track->getLastWritten()));
|
trackResponse.setAttribute("created", track->getAddedTime().toISO8601String());
|
||||||
trackResponse.setAttribute("contentType", av::getMimeType(track->getAbsoluteFilePath().extension()));
|
trackResponse.setAttribute("contentType", av::getMimeType(track->getAbsoluteFilePath().extension()));
|
||||||
if (const auto rating{ core::Service<feedback::IFeedbackService>::get()->getRating(context.user->getId(), track->getId()) })
|
if (const auto rating{ core::Service<feedback::IFeedbackService>::get()->getRating(context.user->getId(), track->getId()) })
|
||||||
trackResponse.setAttribute("userRating", *rating);
|
trackResponse.setAttribute("userRating", *rating);
|
||||||
|
|||||||
Reference in New Issue
Block a user