diff --git a/approot/admin-database.xml b/approot/admin-database.xml index df1f883e..dcd81c0f 100644 --- a/approot/admin-database.xml +++ b/approot/admin-database.xml @@ -34,17 +34,15 @@ ${tr:Lms.Admin.Database.scan-options} - ${} - - - ${tr:Lms.Admin.Database.recommendation-engine-type} + + + ${tr:Lms.Admin.Database.similarity-engine-type} - ${recommendation-engine-type class="form-control"} + ${similarity-engine-type class="form-control"} - ${recommendation-engine-type-info} + ${similarity-engine-type-info} - ${} ${tr:Lms.clusters} diff --git a/approot/messages.xml b/approot/messages.xml index 4793931f..f00f7596 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -53,13 +53,13 @@ Never Media root directory Directories containing a .lmsignore file are skipped -Recommendation engine -Tags based -Audio analysis based Scan complete: {1} total files, {2} additions, {3} updates, {4} deletions, {5} duplicates, {6} errors Scan launched! Scan options New settings saved! +Similarity engine +Tags based +None Update period Update start time Weekly diff --git a/approot/messages_fr.xml b/approot/messages_fr.xml index d7ace5e6..c67ab668 100644 --- a/approot/messages_fr.xml +++ b/approot/messages_fr.xml @@ -53,13 +53,13 @@ Jamais Dossier racine des fichiers de musique Les dossiers contenant un fichier .lmsignore sont ignorés -Moteur de recommandation -Basé sur les tags -Basé sur l'analyse audio Scan terminé : {1} fichiers, {2} ajouts, {3} mises à jour, {4} suppressions, {5} duplicatas, {6} erreurs Scan lancé ! Options Nouveaux paramètres sauvegardés ! +Moteur de similarité +Basé sur les tags +Aucun Périodicité des mises à jour Heure de départ de la mise à jour Toutes les semaines diff --git a/approot/messages_it.xml b/approot/messages_it.xml index 67ebf67e..518fc9b6 100644 --- a/approot/messages_it.xml +++ b/approot/messages_it.xml @@ -53,13 +53,13 @@ Mai Cartella dei file multimediali -Modalità di raccomandazione brani consigliati -Basata sui tag -Basata sull'analisi acustica Scansione completata: {1} file totali, {2} aggiunti, {3} aggiornati, {4} eliminati, {5} duplicati, {6} errati Scansione avviata! Impostazioni scansione Impostazioni salvate! + + + Frequenza di aggiornamento Orario di aggiornamento Settimanale diff --git a/approot/messages_zh.xml b/approot/messages_zh.xml index 317f85ea..9442202c 100644 --- a/approot/messages_zh.xml +++ b/approot/messages_zh.xml @@ -53,13 +53,13 @@ 从不 媒体根目录 包含 .lmsignore 文件的目录将会被跳过 -推荐引擎 -基于标签 -基于音频分析 扫描完成:总文件 {1},添加文件 {2},更新文件 {3},删除文件 {4},重复文件 {5},错误文件 {6} 扫描已完成! 扫描选项 新设置已保存! + + + 更新周期 更新开始时间 每周 diff --git a/src/libs/services/database/include/services/database/ScanSettings.hpp b/src/libs/services/database/include/services/database/ScanSettings.hpp index bb9c924a..cf2aa26b 100644 --- a/src/libs/services/database/include/services/database/ScanSettings.hpp +++ b/src/libs/services/database/include/services/database/ScanSettings.hpp @@ -32,72 +32,74 @@ LMS_DECLARE_IDTYPE(ScanSettingsId) namespace Database { -class ClusterType; -class Session; + class ClusterType; + class Session; -class ScanSettings final : public Object -{ - public: - // Do not modify values (just add) - enum class UpdatePeriod - { - Never = 0, - Daily, - Weekly, - Monthly, - Hourly, - }; + class ScanSettings final : public Object + { + public: + // Do not modify values (just add) + enum class UpdatePeriod + { + Never = 0, + Daily, + Weekly, + Monthly, + Hourly, + }; - // Do not modify values (just add) - enum class RecommendationEngineType - { - Clusters = 0, - Features, - }; + // Do not modify values (just add) + enum class SimilarityEngineType + { + Clusters = 0, + Features, + None, + }; - static void init(Session& session); + static void init(Session& session); - static pointer get(Session& session); + static pointer get(Session& session); - // Getters - std::size_t getScanVersion() const { return _scanVersion; } - std::filesystem::path getMediaDirectory() const { return _mediaDirectory; } - Wt::WTime getUpdateStartTime() const { return _startTime; } - UpdatePeriod getUpdatePeriod() const { return _updatePeriod; } - std::vector> getClusterTypes() const; - std::vector getAudioFileExtensions() const; - RecommendationEngineType getRecommendationEngineType() const { return _recommendationEngineType; } + // Getters + std::size_t getScanVersion() const { return _scanVersion; } + std::filesystem::path getMediaDirectory() const { return _mediaDirectory; } + Wt::WTime getUpdateStartTime() const { return _startTime; } + UpdatePeriod getUpdatePeriod() const { return _updatePeriod; } + std::vector> getClusterTypes() const; + std::vector getAudioFileExtensions() const; + SimilarityEngineType getSimilarityEngineType() const { return _similarityEngineType; } - // Setters - void addAudioFileExtension(const std::filesystem::path& ext); - void setMediaDirectory(const std::filesystem::path& p); - void setUpdateStartTime(Wt::WTime t) { _startTime = t; } - void setUpdatePeriod(UpdatePeriod p) { _updatePeriod = p; } - void setClusterTypes(Session& session, const std::set& clusterTypeNames); - void setRecommendationEngineType(RecommendationEngineType type) { _recommendationEngineType = type; } - void incScanVersion(); + // Setters + void addAudioFileExtension(const std::filesystem::path& ext); + void setMediaDirectory(const std::filesystem::path& p); + void setUpdateStartTime(Wt::WTime t) { _startTime = t; } + void setUpdatePeriod(UpdatePeriod p) { _updatePeriod = p; } + void setClusterTypes(Session& session, const std::set& clusterTypeNames); + void setSimilarityEngineType(SimilarityEngineType type) { _similarityEngineType = type; } + void incScanVersion(); - template - void persist(Action& a) - { - Wt::Dbo::field(a, _scanVersion, "scan_version"); - Wt::Dbo::field(a, _mediaDirectory, "media_directory"); - Wt::Dbo::field(a, _startTime, "start_time"); - Wt::Dbo::field(a, _updatePeriod, "update_period"); - Wt::Dbo::field(a, _audioFileExtensions, "audio_file_extensions"); - Wt::Dbo::field(a, _recommendationEngineType,"similarity_engine_type"); - Wt::Dbo::hasMany(a, _clusterTypes, Wt::Dbo::ManyToOne, "scan_settings"); - } + template + void persist(Action& a) + { + Wt::Dbo::field(a, _scanVersion, "scan_version"); + Wt::Dbo::field(a, _mediaDirectory, "media_directory"); + Wt::Dbo::field(a, _startTime, "start_time"); + Wt::Dbo::field(a, _updatePeriod, "update_period"); + Wt::Dbo::field(a, _audioFileExtensions, "audio_file_extensions"); + Wt::Dbo::field(a, _similarityEngineType, "similarity_engine_type"); + Wt::Dbo::hasMany(a, _clusterTypes, Wt::Dbo::ManyToOne, "scan_settings"); + } - private: - int _scanVersion {}; - std::string _mediaDirectory; - Wt::WTime _startTime = Wt::WTime {0,0,0}; - UpdatePeriod _updatePeriod {UpdatePeriod::Never}; - RecommendationEngineType _recommendationEngineType {RecommendationEngineType::Clusters}; - std::string _audioFileExtensions {".alac .mp3 .ogg .oga .aac .m4a .m4b .flac .wav .wma .aif .aiff .ape .mpc .shn .opus .wv"}; - Wt::Dbo::collection> _clusterTypes; -}; + private: + int _scanVersion{}; + std::string _mediaDirectory; + Wt::WTime _startTime = Wt::WTime{ 0,0,0 }; + UpdatePeriod _updatePeriod{ UpdatePeriod::Never }; + SimilarityEngineType _similarityEngineType{ SimilarityEngineType::Clusters }; + std::string _audioFileExtensions{ ".alac .mp3 .ogg .oga .aac .m4a .m4b .flac .wav .wma .aif .aiff .ape .mpc .shn .opus .wv" }; + + Wt::Dbo::collection> _clusterTypes; + }; } // namespace Database diff --git a/src/libs/services/recommendation/impl/RecommendationService.cpp b/src/libs/services/recommendation/impl/RecommendationService.cpp index 2958450b..4ec0ac75 100644 --- a/src/libs/services/recommendation/impl/RecommendationService.cpp +++ b/src/libs/services/recommendation/impl/RecommendationService.cpp @@ -159,12 +159,12 @@ namespace Recommendation } static - Database::ScanSettings::RecommendationEngineType - getRecommendationEngineType(Database::Session& session) + Database::ScanSettings::SimilarityEngineType + getSimilarityEngineType(Database::Session& session) { auto transaction {session.createSharedTransaction()}; - return Database::ScanSettings::get(session)->getRecommendationEngineType(); + return Database::ScanSettings::get(session)->getSimilarityEngineType(); } void @@ -184,20 +184,24 @@ namespace Recommendation _engines.clear(); } - switch (getRecommendationEngineType(_db.getTLSSession())) + switch (getSimilarityEngineType(_db.getTLSSession())) { - case ScanSettings::RecommendationEngineType::Clusters: + case ScanSettings::SimilarityEngineType::Clusters: _enginePriorities = {EngineType::Clusters}; enginesToLoad.try_emplace(EngineType::Clusters, createClustersEngine(_db)); break; - case ScanSettings::RecommendationEngineType::Features: + case ScanSettings::SimilarityEngineType::Features: _enginePriorities = {EngineType::Features, EngineType::Clusters}; // not same order since clusters is faster to load enginesToLoad.try_emplace(EngineType::Clusters, createClustersEngine(_db)); enginesToLoad.try_emplace(EngineType::Features, createFeaturesEngine(_db)); break; + + case ScanSettings::SimilarityEngineType::None: + _enginePriorities.clear(); + break; } assert(_pendingEngines.empty()); diff --git a/src/libs/services/scanner/impl/ScannerService.cpp b/src/libs/services/scanner/impl/ScannerService.cpp index 4c4c1b95..3fa41ed2 100644 --- a/src/libs/services/scanner/impl/ScannerService.cpp +++ b/src/libs/services/scanner/impl/ScannerService.cpp @@ -381,7 +381,7 @@ ScannerService::readSettings() std::transform(std::cbegin(fileExtensions), std::end(fileExtensions), std::back_inserter(newSettings.supportedExtensions), [](const std::filesystem::path& extension) { return std::filesystem::path{ StringUtils::stringToLower(extension.string()) }; }); } - newSettings.recommendationServiceType = scanSettings->getRecommendationEngineType(); + newSettings.similarityServiceType = scanSettings->getSimilarityEngineType(); newSettings.mediaDirectory = scanSettings->getMediaDirectory(); const auto clusterTypes = scanSettings->getClusterTypes(); diff --git a/src/libs/services/scanner/impl/ScannerSettings.hpp b/src/libs/services/scanner/impl/ScannerSettings.hpp index 6f7af993..a102dea3 100644 --- a/src/libs/services/scanner/impl/ScannerSettings.hpp +++ b/src/libs/services/scanner/impl/ScannerSettings.hpp @@ -34,7 +34,7 @@ namespace Scanner Wt::WTime startTime; Database::ScanSettings::UpdatePeriod updatePeriod {Database::ScanSettings::UpdatePeriod::Never}; std::vector supportedExtensions; - Database::ScanSettings::RecommendationEngineType recommendationServiceType; + Database::ScanSettings::SimilarityEngineType similarityServiceType; std::filesystem::path mediaDirectory; bool skipDuplicateMBID {}; std::set clusterTypeNames; @@ -45,7 +45,7 @@ namespace Scanner && startTime == rhs.startTime && updatePeriod == rhs.updatePeriod && supportedExtensions == rhs.supportedExtensions - && recommendationServiceType == rhs.recommendationServiceType + && similarityServiceType == rhs.similarityServiceType && mediaDirectory == rhs.mediaDirectory && skipDuplicateMBID == rhs.skipDuplicateMBID && clusterTypeNames == rhs.clusterTypeNames; diff --git a/src/lms/ui/admin/DatabaseSettingsView.cpp b/src/lms/ui/admin/DatabaseSettingsView.cpp index 108664da..38d9877e 100644 --- a/src/lms/ui/admin/DatabaseSettingsView.cpp +++ b/src/lms/ui/admin/DatabaseSettingsView.cpp @@ -51,7 +51,7 @@ class DatabaseSettingsModel : public Wt::WFormModel static inline constexpr Field MediaDirectoryField {"media-directory"}; static inline constexpr Field UpdatePeriodField {"update-period"}; static inline constexpr Field UpdateStartTimeField {"update-start-time"}; - static inline constexpr Field RecommendationEngineTypeField {"recommendation-engine-type"}; + static inline constexpr Field SimilarityEngineTypeField {"similarity-engine-type"}; static inline constexpr Field ClustersField {"clusters"}; using UpdatePeriodModel = ValueStringModel; @@ -63,7 +63,7 @@ class DatabaseSettingsModel : public Wt::WFormModel addField(MediaDirectoryField); addField(UpdatePeriodField); addField(UpdateStartTimeField); - addField(RecommendationEngineTypeField); + addField(SimilarityEngineTypeField); addField(ClustersField); auto dirValidator {createDirectoryValidator()}; @@ -72,7 +72,7 @@ class DatabaseSettingsModel : public Wt::WFormModel setValidator(UpdatePeriodField, createMandatoryValidator()); setValidator(UpdateStartTimeField, createMandatoryValidator()); - setValidator(RecommendationEngineTypeField, createMandatoryValidator()); + setValidator(SimilarityEngineTypeField, createMandatoryValidator()); // populate the model with initial data loadData(); @@ -80,7 +80,7 @@ class DatabaseSettingsModel : public Wt::WFormModel std::shared_ptr updatePeriodModel() { return _updatePeriodModel; } std::shared_ptr updateStartTimeModel() { return _updateStartTimeModel; } - std::shared_ptr recommendationEngineTypeModel() { return _recommendationEngineTypeModel; } + std::shared_ptr similarityEngineTypeModel() { return _similarityEngineTypeModel; } void loadData() { @@ -104,9 +104,9 @@ class DatabaseSettingsModel : public Wt::WFormModel setReadOnly(DatabaseSettingsModel::UpdateStartTimeField, true); } - auto recommendationEngineTypeRow {_recommendationEngineTypeModel->getRowFromValue(scanSettings->getRecommendationEngineType())}; - if (recommendationEngineTypeRow) - setValue(RecommendationEngineTypeField, _recommendationEngineTypeModel->getString(*recommendationEngineTypeRow)); + auto similarityEngineTypeRow {_similarityEngineTypeModel->getRowFromValue(scanSettings->getSimilarityEngineType())}; + if (similarityEngineTypeRow) + setValue(SimilarityEngineTypeField, _similarityEngineTypeModel->getString(*similarityEngineTypeRow)); auto clusterTypes {scanSettings->getClusterTypes()}; if (!clusterTypes.empty()) @@ -133,21 +133,14 @@ class DatabaseSettingsModel : public Wt::WFormModel if (startTimeRow) scanSettings.modify()->setUpdateStartTime(_updateStartTimeModel->getValue(*startTimeRow)); - auto recommendationEngineTypeRow {_recommendationEngineTypeModel->getRowFromString(valueText(RecommendationEngineTypeField))}; - if (recommendationEngineTypeRow) - scanSettings.modify()->setRecommendationEngineType(_recommendationEngineTypeModel->getValue(*recommendationEngineTypeRow)); + auto similarityEngineTypeRow {_similarityEngineTypeModel->getRowFromString(valueText(SimilarityEngineTypeField))}; + if (similarityEngineTypeRow) + scanSettings.modify()->setSimilarityEngineType(_similarityEngineTypeModel->getValue(*similarityEngineTypeRow)); auto clusterTypes {StringUtils::splitStringCopy(valueText(ClustersField).toUTF8(), " ")}; scanSettings.modify()->setClusterTypes(LmsApp->getDbSession(), std::set(clusterTypes.begin(), clusterTypes.end())); } - static ScanSettings::RecommendationEngineType getCurrentRecommendationEngine() - { - auto transaction {LmsApp->getDbSession().createSharedTransaction()}; - const ScanSettings::pointer scanSettings {ScanSettings::get(LmsApp->getDbSession())}; - return scanSettings->getRecommendationEngineType(); - } - private: void initializeModels() { @@ -165,14 +158,14 @@ class DatabaseSettingsModel : public Wt::WFormModel _updateStartTimeModel->add(time.toString(), time); } - _recommendationEngineTypeModel = std::make_shared>(); - _recommendationEngineTypeModel->add(Wt::WString::tr("Lms.Admin.Database.recommendation-engine-type.clusters"), ScanSettings::RecommendationEngineType::Clusters); - _recommendationEngineTypeModel->add(Wt::WString::tr("Lms.Admin.Database.recommendation-engine-type.features"), ScanSettings::RecommendationEngineType::Features); + _similarityEngineTypeModel = std::make_shared>(); + _similarityEngineTypeModel->add(Wt::WString::tr("Lms.Admin.Database.similarity-engine-type.clusters"), ScanSettings::SimilarityEngineType::Clusters); + _similarityEngineTypeModel->add(Wt::WString::tr("Lms.Admin.Database.similarity-engine-type.none"), ScanSettings::SimilarityEngineType::None); } std::shared_ptr _updatePeriodModel; std::shared_ptr> _updateStartTimeModel; - std::shared_ptr> _recommendationEngineTypeModel; + std::shared_ptr> _similarityEngineTypeModel; }; DatabaseSettingsView::DatabaseSettingsView() @@ -216,13 +209,10 @@ DatabaseSettingsView::refreshView() updateStartTime->setModel(model->updateStartTimeModel()); t->setFormWidget(DatabaseSettingsModel::UpdateStartTimeField, std::move(updateStartTime)); - // recommendation engine type - // Hide the settings if the engine is set to clusters, as we don't want users to switch to acoustic features (currently broken) - // Otherwise, give the user a way to switch back to clusters - t->setCondition("if-has-recommendation-engine", model->getCurrentRecommendationEngine() == ScanSettings::RecommendationEngineType::Features); - auto recommendationEngineType {std::make_unique()}; - recommendationEngineType->setModel(model->recommendationEngineTypeModel()); - t->setFormWidget(DatabaseSettingsModel::RecommendationEngineTypeField, std::move(recommendationEngineType)); + // Similarity engine type + auto similarityEngineType {std::make_unique()}; + similarityEngineType->setModel(model->similarityEngineTypeModel()); + t->setFormWidget(DatabaseSettingsModel::SimilarityEngineTypeField, std::move(similarityEngineType)); // Clusters t->setFormWidget(DatabaseSettingsModel::ClustersField, std::make_unique());
.lmsignore