Refactored namespaces
This commit is contained in:
@@ -31,14 +31,14 @@
|
||||
|
||||
#include "image/Exception.hpp"
|
||||
#include "image/IRawImage.hpp"
|
||||
#include "utils/IConfig.hpp"
|
||||
#include "utils/ILogger.hpp"
|
||||
#include "utils/Path.hpp"
|
||||
#include "utils/Random.hpp"
|
||||
#include "utils/String.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
#include "core/IConfig.hpp"
|
||||
#include "core/ILogger.hpp"
|
||||
#include "core/Path.hpp"
|
||||
#include "core/Random.hpp"
|
||||
#include "core/String.hpp"
|
||||
#include "core/Utils.hpp"
|
||||
|
||||
namespace Cover
|
||||
namespace lms::cover
|
||||
{
|
||||
namespace
|
||||
{
|
||||
@@ -47,16 +47,16 @@ namespace Cover
|
||||
bool hasCover{};
|
||||
bool isMultiDisc{};
|
||||
std::filesystem::path trackPath;
|
||||
std::optional<Database::ReleaseId> releaseId;
|
||||
std::optional<db::ReleaseId> releaseId;
|
||||
};
|
||||
|
||||
std::optional<TrackInfo> getTrackInfo(Database::Session& dbSession, Database::TrackId trackId)
|
||||
std::optional<TrackInfo> getTrackInfo(db::Session& dbSession, db::TrackId trackId)
|
||||
{
|
||||
std::optional<TrackInfo> res;
|
||||
|
||||
auto transaction{ dbSession.createReadTransaction() };
|
||||
|
||||
const Database::Track::pointer track{ Database::Track::find(dbSession, trackId) };
|
||||
const db::Track::pointer track{ db::Track::find(dbSession, trackId) };
|
||||
if (!track)
|
||||
return res;
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Cover
|
||||
res->hasCover = track->hasCover();
|
||||
res->trackPath = track->getPath();
|
||||
|
||||
if (const Database::Release::pointer & release{ track->getRelease() })
|
||||
if (const db::Release::pointer & release{ track->getRelease() })
|
||||
{
|
||||
res->releaseId = release->getId();
|
||||
if (release->getTotalDisc() > 1)
|
||||
@@ -79,7 +79,7 @@ namespace Cover
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
Service<IConfig>::get()->visitStrings("cover-preferred-file-names",
|
||||
core::Service<core::IConfig>::get()->visitStrings("cover-preferred-file-names",
|
||||
[&res](std::string_view fileName)
|
||||
{
|
||||
res.emplace_back(fileName);
|
||||
@@ -92,7 +92,7 @@ namespace Cover
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
|
||||
Service<IConfig>::get()->visitStrings("artist-image-file-names",
|
||||
core::Service<core::IConfig>::get()->visitStrings("artist-image-file-names",
|
||||
[&res](std::string_view fileName)
|
||||
{
|
||||
res.emplace_back(fileName);
|
||||
@@ -107,29 +107,29 @@ namespace Cover
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<ICoverService> createCoverService(Database::Db& db, const std::filesystem::path& execPath, const std::filesystem::path& defaultCoverPath)
|
||||
std::unique_ptr<ICoverService> createCoverService(db::Db& db, const std::filesystem::path& execPath, const std::filesystem::path& defaultCoverPath)
|
||||
{
|
||||
return std::make_unique<CoverService>(db, execPath, defaultCoverPath);
|
||||
}
|
||||
|
||||
using namespace Image;
|
||||
using namespace image;
|
||||
|
||||
CoverService::CoverService(Database::Db& db,
|
||||
CoverService::CoverService(db::Db& db,
|
||||
const std::filesystem::path& execPath,
|
||||
const std::filesystem::path& defaultCoverPath)
|
||||
: _db{ db }
|
||||
, _defaultCoverPath{ defaultCoverPath }
|
||||
, _maxCacheSize{ Service<IConfig>::get()->getULong("cover-max-cache-size", 30) * 1000 * 1000 }
|
||||
, _maxFileSize{ Service<IConfig>::get()->getULong("cover-max-file-size", 10) * 1000 * 1000 }
|
||||
, _maxCacheSize{ core::Service<core::IConfig>::get()->getULong("cover-max-cache-size", 30) * 1000 * 1000 }
|
||||
, _maxFileSize{ core::Service<core::IConfig>::get()->getULong("cover-max-file-size", 10) * 1000 * 1000 }
|
||||
, _preferredFileNames{ constructPreferredFileNames() }
|
||||
, _artistFileNames{ constructArtistFileNames() }
|
||||
{
|
||||
setJpegQuality(Service<IConfig>::get()->getULong("cover-jpeg-quality", 75));
|
||||
setJpegQuality(core::Service<core::IConfig>::get()->getULong("cover-jpeg-quality", 75));
|
||||
|
||||
LMS_LOG(COVER, INFO, "Default cover path = '" << _defaultCoverPath.string() << "'");
|
||||
LMS_LOG(COVER, INFO, "Max cache size = " << _maxCacheSize);
|
||||
LMS_LOG(COVER, INFO, "Max file size = " << _maxFileSize);
|
||||
LMS_LOG(COVER, INFO, "Preferred file names: " << StringUtils::joinStrings(_preferredFileNames, ","));
|
||||
LMS_LOG(COVER, INFO, "Preferred file names: " << core::stringUtils::joinStrings(_preferredFileNames, ","));
|
||||
|
||||
#if LMS_SUPPORT_IMAGE_GM
|
||||
GraphicsMagick::init(execPath);
|
||||
@@ -141,17 +141,17 @@ namespace Cover
|
||||
{
|
||||
getDefault(512);
|
||||
}
|
||||
catch (const Image::ImageException& e)
|
||||
catch (const image::Exception& e)
|
||||
{
|
||||
throw LmsException("Cannot read default cover file '" + _defaultCoverPath.string() + "': " + e.what());
|
||||
throw core::LmsException("Cannot read default cover file '" + _defaultCoverPath.string() + "': " + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<IEncodedImage> CoverService::getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) const
|
||||
std::unique_ptr<IEncodedImage> CoverService::getFromAvMediaFile(const av::IAudioFile& input, ImageSize width) const
|
||||
{
|
||||
std::unique_ptr<IEncodedImage> image;
|
||||
|
||||
input.visitAttachedPictures([&](const Av::Picture& picture)
|
||||
input.visitAttachedPictures([&](const av::Picture& picture)
|
||||
{
|
||||
if (image)
|
||||
return;
|
||||
@@ -162,7 +162,7 @@ namespace Cover
|
||||
rawImage->resize(width);
|
||||
image = rawImage->encodeToJPEG(_jpegQuality);
|
||||
}
|
||||
catch (const Image::ImageException& e)
|
||||
catch (const image::Exception& e)
|
||||
{
|
||||
LMS_LOG(COVER, ERROR, "Cannot read embedded cover: " << e.what());
|
||||
}
|
||||
@@ -181,7 +181,7 @@ namespace Cover
|
||||
rawImage->resize(width);
|
||||
image = rawImage->encodeToJPEG(_jpegQuality);
|
||||
}
|
||||
catch (const ImageException& e)
|
||||
catch (const image::Exception& e)
|
||||
{
|
||||
LMS_LOG(COVER, ERROR, "Cannot read cover in file '" << p.string() << "': " << e.what());
|
||||
}
|
||||
@@ -320,9 +320,9 @@ namespace Cover
|
||||
|
||||
try
|
||||
{
|
||||
image = getFromAvMediaFile(*Av::parseAudioFile(p), width);
|
||||
image = getFromAvMediaFile(*av::parseAudioFile(p), width);
|
||||
}
|
||||
catch (Av::Exception& e)
|
||||
catch (av::Exception& e)
|
||||
{
|
||||
LMS_LOG(COVER, ERROR, "Cannot get covers from track " << p.string() << ": " << e.what());
|
||||
}
|
||||
@@ -330,14 +330,14 @@ namespace Cover
|
||||
return image;
|
||||
}
|
||||
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromTrack(Database::TrackId trackId, ImageSize width)
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromTrack(db::TrackId trackId, ImageSize width)
|
||||
{
|
||||
return getFromTrack(_db.getTLSSession(), trackId, width, true /* allow release fallback*/);
|
||||
}
|
||||
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width, bool allowReleaseFallback)
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromTrack(db::Session& dbSession, db::TrackId trackId, ImageSize width, bool allowReleaseFallback)
|
||||
{
|
||||
using namespace Database;
|
||||
using namespace db;
|
||||
|
||||
const CacheEntryDesc cacheEntryDesc{ trackId, width };
|
||||
|
||||
@@ -369,9 +369,9 @@ namespace Cover
|
||||
return cover;
|
||||
}
|
||||
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromRelease(Database::ReleaseId releaseId, ImageSize width)
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromRelease(db::ReleaseId releaseId, ImageSize width)
|
||||
{
|
||||
using namespace Database;
|
||||
using namespace db;
|
||||
const CacheEntryDesc cacheEntryDesc{ releaseId, width };
|
||||
|
||||
std::shared_ptr<IEncodedImage> cover{ loadFromCache(cacheEntryDesc) };
|
||||
@@ -418,9 +418,9 @@ namespace Cover
|
||||
return cover;
|
||||
}
|
||||
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromArtist(Database::ArtistId artistId, ImageSize width)
|
||||
std::shared_ptr<IEncodedImage> CoverService::getFromArtist(db::ArtistId artistId, ImageSize width)
|
||||
{
|
||||
using namespace Database;
|
||||
using namespace db;
|
||||
const CacheEntryDesc cacheEntryDesc{ artistId, width };
|
||||
|
||||
std::shared_ptr<IEncodedImage> artistImage{ loadFromCache(cacheEntryDesc) };
|
||||
@@ -478,7 +478,7 @@ namespace Cover
|
||||
// /artist.jpg
|
||||
if (!releasePaths.empty())
|
||||
{
|
||||
const std::filesystem::path artistPath{ releasePaths.size() == 1 ? releasePaths.begin()->parent_path() : PathUtils::getLongestCommonPath(std::cbegin(releasePaths), std::cend(releasePaths)) };
|
||||
const std::filesystem::path artistPath{ releasePaths.size() == 1 ? releasePaths.begin()->parent_path() : core::pathUtils::getLongestCommonPath(std::cbegin(releasePaths), std::cend(releasePaths)) };
|
||||
artistImage = getFromDirectory(artistPath, width, artistFileNamesWithGenericNames, false);
|
||||
}
|
||||
|
||||
@@ -531,7 +531,7 @@ namespace Cover
|
||||
|
||||
void CoverService::setJpegQuality(unsigned quality)
|
||||
{
|
||||
_jpegQuality = Utils::clamp<unsigned>(quality, 1, 100);
|
||||
_jpegQuality = core::utils::clamp<unsigned>(quality, 1, 100);
|
||||
|
||||
LMS_LOG(COVER, INFO, "JPEG export quality = " << _jpegQuality);
|
||||
}
|
||||
@@ -542,7 +542,7 @@ namespace Cover
|
||||
|
||||
while (_cacheSize + image->getDataSize() > _maxCacheSize && !_cache.empty())
|
||||
{
|
||||
auto itRandom{ Random::pickRandom(_cache) };
|
||||
auto itRandom{ core::random::pickRandom(_cache) };
|
||||
_cacheSize -= itRandom->second->getDataSize();
|
||||
_cache.erase(itRandom);
|
||||
}
|
||||
@@ -566,5 +566,5 @@ namespace Cover
|
||||
return it->second;
|
||||
}
|
||||
|
||||
} // namespace Cover
|
||||
} // namespace lms::cover
|
||||
|
||||
|
||||
@@ -33,21 +33,21 @@
|
||||
#include "image/IEncodedImage.hpp"
|
||||
#include "database/Types.hpp"
|
||||
|
||||
namespace Database
|
||||
namespace lms::db
|
||||
{
|
||||
class Session;
|
||||
}
|
||||
|
||||
namespace Av
|
||||
namespace lms::av
|
||||
{
|
||||
class IAudioFile;
|
||||
}
|
||||
|
||||
namespace Cover
|
||||
namespace lms::cover
|
||||
{
|
||||
struct CacheEntryDesc
|
||||
{
|
||||
std::variant<Database::ArtistId, Database::ReleaseId, Database::TrackId> id;
|
||||
std::variant<db::ArtistId, db::ReleaseId, db::TrackId> id;
|
||||
std::size_t size;
|
||||
|
||||
bool operator==(const CacheEntryDesc& other) const
|
||||
@@ -61,64 +61,64 @@ namespace Cover
|
||||
namespace std
|
||||
{
|
||||
template<>
|
||||
class hash<Cover::CacheEntryDesc>
|
||||
class hash<lms::cover::CacheEntryDesc>
|
||||
{
|
||||
public:
|
||||
size_t operator()(const Cover::CacheEntryDesc& e) const
|
||||
size_t operator()(const lms::cover::CacheEntryDesc& e) const
|
||||
{
|
||||
size_t h{};
|
||||
std::visit([&](auto id)
|
||||
{
|
||||
using IdType = std::decay_t<decltype(id)>;
|
||||
h ^= std::hash<IdType>()(id);
|
||||
h ^= std::hash<IdType>{}(id);
|
||||
}, e.id);
|
||||
h ^= std::hash<std::size_t>()(e.size) << 1;
|
||||
h ^= std::hash<std::size_t>{}(e.size) << 1;
|
||||
return h;
|
||||
}
|
||||
};
|
||||
|
||||
} // ns std
|
||||
|
||||
namespace Cover
|
||||
namespace lms::cover
|
||||
{
|
||||
class CoverService : public ICoverService
|
||||
{
|
||||
public:
|
||||
CoverService(Database::Db& db, const std::filesystem::path& execPath, const std::filesystem::path& defaultCoverPath);
|
||||
CoverService(db::Db& db, const std::filesystem::path& execPath, const std::filesystem::path& defaultCoverPath);
|
||||
|
||||
CoverService(const CoverService&) = delete;
|
||||
CoverService& operator=(const CoverService&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::TrackId trackId, Image::ImageSize width) override;
|
||||
std::shared_ptr<Image::IEncodedImage> getFromRelease(Database::ReleaseId releaseId, Image::ImageSize width) override;
|
||||
std::shared_ptr<Image::IEncodedImage> getFromArtist(Database::ArtistId artistId, Image::ImageSize width) override;
|
||||
std::shared_ptr<Image::IEncodedImage> getDefault(Image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getFromTrack(db::TrackId trackId, image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getFromRelease(db::ReleaseId releaseId, image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getFromArtist(db::ArtistId artistId, image::ImageSize width) override;
|
||||
std::shared_ptr<image::IEncodedImage> getDefault(image::ImageSize width) override;
|
||||
void flushCache() override;
|
||||
void setJpegQuality(unsigned quality) override;
|
||||
|
||||
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, Image::ImageSize width, bool allowReleaseFallback);
|
||||
std::unique_ptr<Image::IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, Image::ImageSize width) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromCoverFile(const std::filesystem::path& p, Image::ImageSize width) const;
|
||||
std::shared_ptr<image::IEncodedImage> getFromTrack(db::Session& dbSession, db::TrackId trackId, image::ImageSize width, bool allowReleaseFallback);
|
||||
std::unique_ptr<image::IEncodedImage> getFromAvMediaFile(const av::IAudioFile& input, image::ImageSize width) const;
|
||||
std::unique_ptr<image::IEncodedImage> getFromCoverFile(const std::filesystem::path& p, image::ImageSize width) const;
|
||||
|
||||
std::unique_ptr<Image::IEncodedImage> getFromTrack(const std::filesystem::path& path, Image::ImageSize width) const;
|
||||
std::unique_ptr<image::IEncodedImage> getFromTrack(const std::filesystem::path& path, image::ImageSize width) const;
|
||||
std::multimap<std::string, std::filesystem::path> getCoverPaths(const std::filesystem::path& directoryPath) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromDirectory(const std::filesystem::path& directory, Image::ImageSize width, const std::vector<std::string>& preferredFileNames, bool allowPickRandom) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, Image::ImageSize width) const;
|
||||
std::unique_ptr<image::IEncodedImage> getFromDirectory(const std::filesystem::path& directory, image::ImageSize width, const std::vector<std::string>& preferredFileNames, bool allowPickRandom) const;
|
||||
std::unique_ptr<image::IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, image::ImageSize width) const;
|
||||
|
||||
bool checkCoverFile(const std::filesystem::path& directoryPath) const;
|
||||
|
||||
Database::Db& _db;
|
||||
db::Db& _db;
|
||||
|
||||
std::shared_mutex _cacheMutex;
|
||||
std::unordered_map<CacheEntryDesc, std::shared_ptr<Image::IEncodedImage>> _cache;
|
||||
std::unordered_map<Image::ImageSize, std::shared_ptr<Image::IEncodedImage>> _defaultCoverCache;
|
||||
std::unordered_map<CacheEntryDesc, std::shared_ptr<image::IEncodedImage>> _cache;
|
||||
std::unordered_map<image::ImageSize, std::shared_ptr<image::IEncodedImage>> _defaultCoverCache;
|
||||
std::atomic<std::size_t> _cacheMisses{};
|
||||
std::atomic<std::size_t> _cacheHits{};
|
||||
std::size_t _cacheSize{};
|
||||
|
||||
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<Image::IEncodedImage> image);
|
||||
std::shared_ptr<Image::IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
|
||||
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<image::IEncodedImage> image);
|
||||
std::shared_ptr<image::IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
|
||||
|
||||
const std::filesystem::path _defaultCoverPath;
|
||||
const std::size_t _maxCacheSize;
|
||||
@@ -129,5 +129,5 @@ namespace Cover
|
||||
unsigned _jpegQuality;
|
||||
};
|
||||
|
||||
} // namespace Cover
|
||||
} // namespace lms::cover
|
||||
|
||||
|
||||
Reference in New Issue
Block a user