Distinguish initial scan to import last time write as added time, ref #601
This commit is contained in:
@@ -22,6 +22,10 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <Wt/WDate.h>
|
||||||
|
#include <Wt/WDateTime.h>
|
||||||
|
#include <Wt/WTime.h>
|
||||||
|
|
||||||
namespace lms::core
|
namespace lms::core
|
||||||
{
|
{
|
||||||
PartialDateTime::PartialDateTime(int year)
|
PartialDateTime::PartialDateTime(int year)
|
||||||
@@ -84,6 +88,18 @@ namespace lms::core
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PartialDateTime PartialDateTime::fromWtDateTime(const Wt::WDateTime& dateTime)
|
||||||
|
{
|
||||||
|
return core::PartialDateTime{
|
||||||
|
dateTime.date().year(),
|
||||||
|
static_cast<unsigned>(dateTime.date().month()),
|
||||||
|
static_cast<unsigned>(dateTime.date().day()),
|
||||||
|
static_cast<unsigned>(dateTime.time().hour()),
|
||||||
|
static_cast<unsigned>(dateTime.time().minute()),
|
||||||
|
static_cast<unsigned>(dateTime.time().second())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
std::string PartialDateTime::toISO8601String() const
|
std::string PartialDateTime::toISO8601String() const
|
||||||
{
|
{
|
||||||
if (_precision == Precision::Invalid)
|
if (_precision == Precision::Invalid)
|
||||||
|
|||||||
@@ -23,6 +23,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace Wt
|
||||||
|
{
|
||||||
|
class WDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
namespace lms::core
|
namespace lms::core
|
||||||
{
|
{
|
||||||
class PartialDateTime
|
class PartialDateTime
|
||||||
@@ -35,6 +40,7 @@ namespace lms::core
|
|||||||
PartialDateTime(int year, unsigned month, unsigned day, unsigned hour, unsigned min, unsigned sec);
|
PartialDateTime(int year, unsigned month, unsigned day, unsigned hour, unsigned min, unsigned sec);
|
||||||
|
|
||||||
static PartialDateTime fromString(std::string_view str);
|
static PartialDateTime fromString(std::string_view str);
|
||||||
|
static PartialDateTime fromWtDateTime(const Wt::WDateTime& dateTime);
|
||||||
std::string toISO8601String() const;
|
std::string toISO8601String() const;
|
||||||
|
|
||||||
bool isValid() const { return _precision != Precision::Invalid; }
|
bool isValid() const { return _precision != Precision::Invalid; }
|
||||||
|
|||||||
@@ -78,6 +78,13 @@ namespace lms::db
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaLibrary::isEmpty() const
|
||||||
|
{
|
||||||
|
assert(session());
|
||||||
|
auto query{ session()->query<bool>("SELECT EXISTS (SELECT 1 FROM track WHERE media_library_id = ? LIMIT 1) AS is_media_library_empty").bind(getId()) };
|
||||||
|
return !utils::fetchQuerySingleResult(query);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaLibrary::setPath(const std::filesystem::path& p)
|
void MediaLibrary::setPath(const std::filesystem::path& p)
|
||||||
{
|
{
|
||||||
assert(p.is_absolute());
|
assert(p.is_absolute());
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace lms::db
|
|||||||
// getters
|
// getters
|
||||||
std::string_view getName() const { return _name; }
|
std::string_view getName() const { return _name; }
|
||||||
const std::filesystem::path& getPath() const { return _path; }
|
const std::filesystem::path& getPath() const { return _path; }
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
// setters
|
// setters
|
||||||
void setName(std::string_view name) { _name = name; }
|
void setName(std::string_view name) { _name = name; }
|
||||||
|
|||||||
@@ -151,19 +151,31 @@ namespace lms::db::tests
|
|||||||
ScopedMediaLibrary library{ session, "MyLibrary", "/root" };
|
ScopedMediaLibrary library{ session, "MyLibrary", "/root" };
|
||||||
ScopedMediaLibrary otherLibrary{ session, "OtherLibrary", "/otherRoot" };
|
ScopedMediaLibrary otherLibrary{ session, "OtherLibrary", "/otherRoot" };
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
EXPECT_TRUE(library->isEmpty());
|
||||||
|
EXPECT_TRUE(otherLibrary->isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createWriteTransaction() };
|
||||||
track.get().modify()->setMediaLibrary(library.get());
|
track.get().modify()->setMediaLibrary(library.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
|
EXPECT_FALSE(library->isEmpty());
|
||||||
|
EXPECT_TRUE(otherLibrary->isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto transaction{ session.createReadTransaction() };
|
||||||
const auto tracks{ Track::findIds(session, Track::FindParameters{}.setMediaLibrary(library->getId())) };
|
const auto tracks{ Track::findIds(session, Track::FindParameters{}.setMediaLibrary(library->getId())) };
|
||||||
ASSERT_EQ(tracks.results.size(), 1);
|
ASSERT_EQ(tracks.results.size(), 1);
|
||||||
EXPECT_EQ(tracks.results.front(), track.getId());
|
EXPECT_EQ(tracks.results.front(), track.getId());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto transaction{ session.createWriteTransaction() };
|
auto transaction{ session.createReadTransaction() };
|
||||||
const auto tracks{ Track::findIds(session, Track::FindParameters{}.setMediaLibrary(otherLibrary->getId())) };
|
const auto tracks{ Track::findIds(session, Track::FindParameters{}.setMediaLibrary(otherLibrary->getId())) };
|
||||||
EXPECT_EQ(tracks.results.size(), 0);
|
EXPECT_EQ(tracks.results.size(), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace lms::scanner
|
|||||||
{
|
{
|
||||||
db::MediaLibraryId id;
|
db::MediaLibraryId id;
|
||||||
std::filesystem::path rootDirectory;
|
std::filesystem::path rootDirectory;
|
||||||
|
bool firstScan{};
|
||||||
|
|
||||||
auto operator<=>(const MediaLibraryInfo& other) const = default;
|
auto operator<=>(const MediaLibraryInfo& other) const = default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -395,7 +395,12 @@ namespace lms::scanner
|
|||||||
newSettings.updatePeriod = scanSettings->getUpdatePeriod();
|
newSettings.updatePeriod = scanSettings->getUpdatePeriod();
|
||||||
|
|
||||||
MediaLibrary::find(_db.getTLSSession(), [&](const MediaLibrary::pointer& mediaLibrary) {
|
MediaLibrary::find(_db.getTLSSession(), [&](const MediaLibrary::pointer& mediaLibrary) {
|
||||||
newSettings.mediaLibraries.push_back(MediaLibraryInfo{ .id = mediaLibrary->getId(), .rootDirectory = mediaLibrary->getPath().lexically_normal() });
|
MediaLibraryInfo info;
|
||||||
|
info.firstScan = mediaLibrary->isEmpty();
|
||||||
|
info.id = mediaLibrary->getId();
|
||||||
|
info.rootDirectory = mediaLibrary->getPath().lexically_normal();
|
||||||
|
|
||||||
|
newSettings.mediaLibraries.push_back(info);
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -479,19 +479,14 @@ namespace lms::scanner
|
|||||||
if (!track)
|
if (!track)
|
||||||
{
|
{
|
||||||
track = dbSession.create<db::Track>();
|
track = dbSession.create<db::Track>();
|
||||||
track.modify()->setAbsoluteFilePath(_file);
|
|
||||||
|
|
||||||
const core::PartialDateTime addedTime{
|
|
||||||
fileInfo->lastWriteTime.date().year(),
|
|
||||||
static_cast<unsigned>(fileInfo->lastWriteTime.date().month()),
|
|
||||||
static_cast<unsigned>(fileInfo->lastWriteTime.date().day()),
|
|
||||||
static_cast<unsigned>(fileInfo->lastWriteTime.time().hour()),
|
|
||||||
static_cast<unsigned>(fileInfo->lastWriteTime.time().minute()),
|
|
||||||
static_cast<unsigned>(fileInfo->lastWriteTime.time().second())
|
|
||||||
};
|
|
||||||
|
|
||||||
track.modify()->setAddedTime(addedTime); // may be erased by encodingTime
|
|
||||||
added = true;
|
added = true;
|
||||||
|
|
||||||
|
track.modify()->setAbsoluteFilePath(_file);
|
||||||
|
if (!_parsedTrack->encodingTime.isValid())
|
||||||
|
{
|
||||||
|
const core::PartialDateTime addedTime{ core::PartialDateTime::fromWtDateTime(_mediaLibrary.firstScan ? fileInfo->lastWriteTime : Wt::WDateTime::currentDateTime()) };
|
||||||
|
track.modify()->setAddedTime(addedTime); // may be erased by encodingTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track related data
|
// Track related data
|
||||||
|
|||||||
Reference in New Issue
Block a user