Removed session parameters from cover service
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "av/IAudioFile.hpp"
|
#include "av/IAudioFile.hpp"
|
||||||
|
|
||||||
|
#include "database/Db.hpp"
|
||||||
#include "database/Release.hpp"
|
#include "database/Release.hpp"
|
||||||
#include "database/Session.hpp"
|
#include "database/Session.hpp"
|
||||||
#include "database/Track.hpp"
|
#include "database/Track.hpp"
|
||||||
@@ -33,6 +34,7 @@ using RawImage = CoverArt::STB::RawImage;
|
|||||||
using RawImage = CoverArt::GraphicsMagick::RawImage;
|
using RawImage = CoverArt::GraphicsMagick::RawImage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "utils/IConfig.hpp"
|
||||||
#include "utils/Logger.hpp"
|
#include "utils/Logger.hpp"
|
||||||
#include "utils/Random.hpp"
|
#include "utils/Random.hpp"
|
||||||
#include "utils/Utils.hpp"
|
#include "utils/Utils.hpp"
|
||||||
@@ -85,27 +87,25 @@ isFileSupported(const std::filesystem::path& file, const std::vector<std::filesy
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<IGrabber>
|
std::unique_ptr<IGrabber>
|
||||||
createGrabber(const std::filesystem::path& execPath,
|
createGrabber(Database::Db& db, const std::filesystem::path& execPath, const std::filesystem::path& defaultCoverPath)
|
||||||
const std::filesystem::path& defaultCoverPath,
|
|
||||||
std::size_t maxCacheSize, std::size_t maxFileSize, unsigned jpegQuality)
|
|
||||||
{
|
{
|
||||||
return std::make_unique<Grabber>(execPath, defaultCoverPath, maxCacheSize, maxFileSize, jpegQuality);
|
return std::make_unique<Grabber>(db, execPath, defaultCoverPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
Grabber::Grabber(const std::filesystem::path& execPath,
|
Grabber::Grabber(Database::Db& db,
|
||||||
const std::filesystem::path& defaultCoverPath,
|
const std::filesystem::path& execPath,
|
||||||
std::size_t maxCacheSize,
|
const std::filesystem::path& defaultCoverPath)
|
||||||
std::size_t maxFileSize,
|
: _db {db}
|
||||||
unsigned jpegQuality)
|
, _defaultCoverPath {defaultCoverPath}
|
||||||
: _defaultCoverPath {defaultCoverPath}
|
, _maxCacheSize {Service<IConfig>::get()->getULong("cover-max-cache-size", 30) * 1000 * 1000}
|
||||||
, _maxCacheSize {maxCacheSize}
|
, _maxFileSize {Service<IConfig>::get()->getULong("cover-max-file-size", 10) * 1000 * 1000}
|
||||||
, _maxFileSize {maxFileSize}
|
|
||||||
, _jpegQuality {Utils::clamp<unsigned>(jpegQuality, 1, 100)}
|
|
||||||
{
|
{
|
||||||
|
setJpegQuality(Service<IConfig>::get()->getULong("cover-jpeg-quality", 75));
|
||||||
|
|
||||||
LMS_LOG(COVER, INFO) << "Default cover path = '" << _defaultCoverPath.string() << "'";
|
LMS_LOG(COVER, INFO) << "Default cover path = '" << _defaultCoverPath.string() << "'";
|
||||||
LMS_LOG(COVER, INFO) << "Max cache size = " << _maxCacheSize;
|
LMS_LOG(COVER, INFO) << "Max cache size = " << _maxCacheSize;
|
||||||
LMS_LOG(COVER, INFO) << "Max file size = " << _maxFileSize;
|
LMS_LOG(COVER, INFO) << "Max file size = " << _maxFileSize;
|
||||||
LMS_LOG(COVER, INFO) << "JPEG export quality = " << _jpegQuality;
|
|
||||||
|
|
||||||
#if LMS_SUPPORT_IMAGE_GM
|
#if LMS_SUPPORT_IMAGE_GM
|
||||||
GraphicsMagick::init(execPath);
|
GraphicsMagick::init(execPath);
|
||||||
@@ -313,9 +313,9 @@ Grabber::getFromTrack(const std::filesystem::path& p, ImageSize width) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IEncodedImage>
|
std::shared_ptr<IEncodedImage>
|
||||||
Grabber::getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width)
|
Grabber::getFromTrack(Database::TrackId trackId, ImageSize width)
|
||||||
{
|
{
|
||||||
return getFromTrack(dbSession, trackId, width, true /* allow release fallback*/);
|
return getFromTrack(_db.getTLSSession(), trackId, width, true /* allow release fallback*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IEncodedImage>
|
std::shared_ptr<IEncodedImage>
|
||||||
@@ -338,7 +338,7 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::TrackId trackId, I
|
|||||||
cover = getFromSameNamedFile(trackInfo->trackPath, width);
|
cover = getFromSameNamedFile(trackInfo->trackPath, width);
|
||||||
|
|
||||||
if (!cover && trackInfo->releaseId && allowReleaseFallback)
|
if (!cover && trackInfo->releaseId && allowReleaseFallback)
|
||||||
cover = getFromRelease(dbSession, *trackInfo->releaseId, width);
|
cover = getFromRelease(*trackInfo->releaseId, width);
|
||||||
|
|
||||||
if (!cover && trackInfo->isMultiDisc)
|
if (!cover && trackInfo->isMultiDisc)
|
||||||
{
|
{
|
||||||
@@ -357,7 +357,7 @@ Grabber::getFromTrack(Database::Session& dbSession, Database::TrackId trackId, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<IEncodedImage>
|
std::shared_ptr<IEncodedImage>
|
||||||
Grabber::getFromRelease(Database::Session& session, Database::ReleaseId releaseId, ImageSize width)
|
Grabber::getFromRelease(Database::ReleaseId releaseId, ImageSize width)
|
||||||
{
|
{
|
||||||
const CacheEntryDesc cacheEntryDesc {releaseId, width};
|
const CacheEntryDesc cacheEntryDesc {releaseId, width};
|
||||||
|
|
||||||
@@ -371,6 +371,8 @@ Grabber::getFromRelease(Database::Session& session, Database::ReleaseId releaseI
|
|||||||
std::filesystem::path releaseDirectory;
|
std::filesystem::path releaseDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Database::Session& session {_db.getTLSSession()};
|
||||||
|
|
||||||
auto getReleaseInfo {[&]
|
auto getReleaseInfo {[&]
|
||||||
{
|
{
|
||||||
std::optional<ReleaseInfo> res;
|
std::optional<ReleaseInfo> res;
|
||||||
@@ -418,6 +420,14 @@ Grabber::flushCache()
|
|||||||
_cache.clear();
|
_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Grabber::setJpegQuality(unsigned quality)
|
||||||
|
{
|
||||||
|
_jpegQuality = Utils::clamp<unsigned>(quality, 1, 100);
|
||||||
|
|
||||||
|
LMS_LOG(COVER, INFO) << "JPEG export quality = " << _jpegQuality;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Grabber::saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<IEncodedImage> image)
|
Grabber::saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<IEncodedImage> image)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -86,11 +86,9 @@ namespace CoverArt
|
|||||||
class Grabber : public IGrabber
|
class Grabber : public IGrabber
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Grabber(const std::filesystem::path& execPath,
|
Grabber(Database::Db& db,
|
||||||
const std::filesystem::path& defaultCoverPath,
|
const std::filesystem::path& execPath,
|
||||||
std::size_t maxCacheEntries,
|
const std::filesystem::path& defaultCoverPath);
|
||||||
std::size_t maxFileSize,
|
|
||||||
unsigned jpegQuality);
|
|
||||||
|
|
||||||
Grabber(const Grabber&) = delete;
|
Grabber(const Grabber&) = delete;
|
||||||
Grabber& operator=(const Grabber&) = delete;
|
Grabber& operator=(const Grabber&) = delete;
|
||||||
@@ -98,9 +96,10 @@ namespace CoverArt
|
|||||||
Grabber& operator=(Grabber&&) = delete;
|
Grabber& operator=(Grabber&&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width) override;
|
std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) override;
|
||||||
std::shared_ptr<IEncodedImage> getFromRelease(Database::Session& dbSession, Database::ReleaseId releaseId, ImageSize width) override;
|
std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) override;
|
||||||
void flushCache() override;
|
void flushCache() override;
|
||||||
|
void setJpegQuality(unsigned quality) override;
|
||||||
|
|
||||||
std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width, bool allowReleaseFallback);
|
std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width, bool allowReleaseFallback);
|
||||||
std::unique_ptr<IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) const;
|
std::unique_ptr<IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) const;
|
||||||
@@ -114,6 +113,8 @@ namespace CoverArt
|
|||||||
|
|
||||||
bool checkCoverFile(const std::filesystem::path& directoryPath) const;
|
bool checkCoverFile(const std::filesystem::path& directoryPath) const;
|
||||||
|
|
||||||
|
Database::Db& _db;
|
||||||
|
|
||||||
std::shared_mutex _cacheMutex;
|
std::shared_mutex _cacheMutex;
|
||||||
std::unordered_map<CacheEntryDesc, std::shared_ptr<IEncodedImage>> _cache;
|
std::unordered_map<CacheEntryDesc, std::shared_ptr<IEncodedImage>> _cache;
|
||||||
std::unordered_map<ImageSize, std::shared_ptr<IEncodedImage>> _defaultCoverCache;
|
std::unordered_map<ImageSize, std::shared_ptr<IEncodedImage>> _defaultCoverCache;
|
||||||
@@ -129,7 +130,7 @@ namespace CoverArt
|
|||||||
static inline const std::vector<std::filesystem::path> _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize
|
static inline const std::vector<std::filesystem::path> _fileExtensions {".jpg", ".jpeg", ".png", ".bmp"}; // TODO parametrize
|
||||||
const std::size_t _maxFileSize;
|
const std::size_t _maxFileSize;
|
||||||
static inline const std::vector<std::string> _preferredFileNames {"cover", "front"}; // TODO parametrize
|
static inline const std::vector<std::string> _preferredFileNames {"cover", "front"}; // TODO parametrize
|
||||||
const unsigned _jpegQuality;
|
unsigned _jpegQuality;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CoverArt
|
} // namespace CoverArt
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
namespace Database
|
namespace Database
|
||||||
{
|
{
|
||||||
class Session;
|
class Db;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CoverArt
|
namespace CoverArt
|
||||||
@@ -37,17 +37,17 @@ namespace CoverArt
|
|||||||
public:
|
public:
|
||||||
virtual ~IGrabber() = default;
|
virtual ~IGrabber() = default;
|
||||||
|
|
||||||
virtual std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width) = 0;
|
virtual std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) = 0;
|
||||||
virtual std::shared_ptr<IEncodedImage> getFromRelease(Database::Session& dbSession, Database::ReleaseId releaseId, ImageSize width) = 0;
|
virtual std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) = 0;
|
||||||
|
|
||||||
virtual void flushCache() = 0;
|
virtual void flushCache() = 0;
|
||||||
|
|
||||||
|
virtual void setJpegQuality(unsigned quality) = 0; // from 1 to 100
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IGrabber> createGrabber(const std::filesystem::path& execPath,
|
std::unique_ptr<IGrabber> createGrabber(Database::Db& db,
|
||||||
const std::filesystem::path& defaultCoverPath,
|
const std::filesystem::path& execPath,
|
||||||
std::size_t maxCacheEntries,
|
const std::filesystem::path& defaultCoverPath);
|
||||||
std::size_t maxFileSize,
|
|
||||||
unsigned jpegQuality);
|
|
||||||
|
|
||||||
} // namespace CoverArt
|
} // namespace CoverArt
|
||||||
|
|
||||||
|
|||||||
@@ -1795,9 +1795,9 @@ handleGetCoverArt(RequestContext& context, const Wt::Http::Request& /*request*/,
|
|||||||
|
|
||||||
std::shared_ptr<CoverArt::IEncodedImage> cover;
|
std::shared_ptr<CoverArt::IEncodedImage> cover;
|
||||||
if (trackId)
|
if (trackId)
|
||||||
cover = Service<CoverArt::IGrabber>::get()->getFromTrack(context.dbSession, *trackId, size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromTrack(*trackId, size);
|
||||||
else if (releaseId)
|
else if (releaseId)
|
||||||
cover = Service<CoverArt::IGrabber>::get()->getFromRelease(context.dbSession, *releaseId, size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromRelease(*releaseId, size);
|
||||||
|
|
||||||
response.out().write(reinterpret_cast<const char*>(cover->getData()), cover->getDataSize());
|
response.out().write(reinterpret_cast<const char*>(cover->getData()), cover->getDataSize());
|
||||||
response.setMimeType(std::string {cover->getMimeType()});
|
response.setMimeType(std::string {cover->getMimeType()});
|
||||||
|
|||||||
+2
-6
@@ -250,13 +250,9 @@ int main(int argc, char* argv[])
|
|||||||
else
|
else
|
||||||
throw LmsException {"Bad value '" + authenticationBackend + "' for 'authentication-backend'"};
|
throw LmsException {"Bad value '" + authenticationBackend + "' for 'authentication-backend'"};
|
||||||
|
|
||||||
Service<CoverArt::IGrabber> coverArtService {CoverArt::createGrabber(argv[0],
|
Service<CoverArt::IGrabber> coverArtService {CoverArt::createGrabber(database, argv[0], server.appRoot() + "/images/unknown-cover.jpg")};
|
||||||
server.appRoot() + "/images/unknown-cover.jpg",
|
|
||||||
config->getULong("cover-max-cache-size", 30) * 1000 * 1000,
|
|
||||||
config->getULong("cover-max-file-size", 10) * 1000 * 1000,
|
|
||||||
config->getULong("cover-jpeg-quality", 75))};
|
|
||||||
Service<Recommendation::IEngine> recommendationEngineService {Recommendation::createEngine(database)};
|
Service<Recommendation::IEngine> recommendationEngineService {Recommendation::createEngine(database)};
|
||||||
Service<Scanner::IScanner> scannerService {Scanner::createScanner(/*ioContext,*/ database, *recommendationEngineService)};
|
Service<Scanner::IScanner> scannerService {Scanner::createScanner(database, *recommendationEngineService)};
|
||||||
|
|
||||||
scannerService->getEvents().scanComplete.connect([&]
|
scannerService->getEvents().scanComplete.connect([&]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cover = Service<CoverArt::IGrabber>::get()->getFromTrack(LmsApp->getDbSession(), *trackId, *size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromTrack(*trackId, *size);
|
||||||
}
|
}
|
||||||
else if (releaseIdStr)
|
else if (releaseIdStr)
|
||||||
{
|
{
|
||||||
@@ -106,7 +106,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
|||||||
if (!releaseId)
|
if (!releaseId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cover = Service<CoverArt::IGrabber>::get()->getFromRelease(LmsApp->getDbSession(), *releaseId, *size);
|
cover = Service<CoverArt::IGrabber>::get()->getFromRelease(*releaseId, *size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ dumpTrackCovers(Database::Session& session, CoverArt::ImageSize width)
|
|||||||
for (const Database::TrackId trackId : trackIds)
|
for (const Database::TrackId trackId : trackIds)
|
||||||
{
|
{
|
||||||
std::cout << "Getting cover for track id " << trackId.toString() << std::endl;
|
std::cout << "Getting cover for track id " << trackId.toString() << std::endl;
|
||||||
Service<CoverArt::IGrabber>::get()->getFromTrack(session, trackId, width);
|
Service<CoverArt::IGrabber>::get()->getFromTrack(trackId, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,15 +82,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
Service<IConfig> config {createConfig(vm["conf"].as<std::string>())};
|
Service<IConfig> config {createConfig(vm["conf"].as<std::string>())};
|
||||||
|
|
||||||
Service<CoverArt::IGrabber> coverArtService {CoverArt::createGrabber(argv[0],
|
|
||||||
vm["default-cover"].as<std::string>(),
|
|
||||||
config->getULong("cover-max-cache-size", 30) * 1000 * 1000,
|
|
||||||
config->getULong("cover-max-file-size", 10) * 1000 * 1000,
|
|
||||||
config->getULong("cover-jpeg-quality", vm["quality"].as<unsigned>())
|
|
||||||
)};
|
|
||||||
|
|
||||||
Database::Db db {config->getPath("working-dir") / "lms.db"};
|
Database::Db db {config->getPath("working-dir") / "lms.db"};
|
||||||
|
Service<CoverArt::IGrabber> coverArtService {CoverArt::createGrabber(db, argv[0], vm["default-cover"].as<std::string>())};
|
||||||
|
|
||||||
|
coverArtService->setJpegQuality(config->getULong("cover-jpeg-quality", vm["quality"].as<unsigned>()));
|
||||||
|
|
||||||
Database::Session session {db};
|
Database::Session session {db};
|
||||||
|
|
||||||
if (vm.count("tracks"))
|
if (vm.count("tracks"))
|
||||||
|
|||||||
Reference in New Issue
Block a user