diff --git a/approot/messages.xml b/approot/messages.xml index 20677bc8..925ac67c 100644 --- a/approot/messages.xml +++ b/approot/messages.xml @@ -61,6 +61,8 @@ Not available Scanned {1} files in {2} on {3} ({4} errors, {5} duplicates) No audio track +Not a regular file +File type not supported Duplicated file hash Duplicated MBID Status diff --git a/approot/messages_fr.xml b/approot/messages_fr.xml index 934cd400..5f5951b2 100644 --- a/approot/messages_fr.xml +++ b/approot/messages_fr.xml @@ -61,6 +61,8 @@ Non disponible {1} fichiers scannés en {2} le {3} ({4} erreurs, {5} duplicatas) Pas de piste audio +Fichier non régulier +Type de fichier non supporté Hash dupliqué MBID dupliqué Statut diff --git a/src/libs/database/impl/ScanSettings.cpp b/src/libs/database/impl/ScanSettings.cpp index 673e2a24..3d9a1a86 100644 --- a/src/libs/database/impl/ScanSettings.cpp +++ b/src/libs/database/impl/ScanSettings.cpp @@ -21,6 +21,7 @@ #include +#include "utils/Path.hpp" #include "utils/Logger.hpp" #include "utils/String.hpp" @@ -62,11 +63,11 @@ ScanSettings::get(Session& session) return session.getDboSession().find(); } -std::set +std::unordered_set ScanSettings::getAudioFileExtensions() const { auto extensions = StringUtils::splitString(_audioFileExtensions, " "); - return std::set(std::cbegin(extensions), std::cend(extensions)); + return std::unordered_set(std::cbegin(extensions), std::cend(extensions)); } void diff --git a/src/libs/database/include/database/ScanSettings.hpp b/src/libs/database/include/database/ScanSettings.hpp index 7151df23..0a2ee450 100644 --- a/src/libs/database/include/database/ScanSettings.hpp +++ b/src/libs/database/include/database/ScanSettings.hpp @@ -19,11 +19,13 @@ #pragma once -#include +#include #include #include +#include "utils/Path.hpp" + namespace Database { class ClusterType; @@ -59,7 +61,7 @@ class ScanSettings : public Wt::Dbo::Dbo Wt::WTime getUpdateStartTime() const { return _startTime; } UpdatePeriod getUpdatePeriod() const { return _updatePeriod; } std::vector> getClusterTypes() const; - std::set getAudioFileExtensions() const; + std::unordered_set getAudioFileExtensions() const; RecommendationEngineType getRecommendationEngineType() const { return _recommendationEngineType; } // Setters diff --git a/src/libs/scanner/impl/MediaScanner.cpp b/src/libs/scanner/impl/MediaScanner.cpp index 586f2995..b213f9f8 100644 --- a/src/libs/scanner/impl/MediaScanner.cpp +++ b/src/libs/scanner/impl/MediaScanner.cpp @@ -63,7 +63,7 @@ getNextFirstOfMonth(Wt::WDate current) } bool -isFileSupported(const std::filesystem::path& file, const std::set& extensions) +isFileSupported(const std::filesystem::path& file, const std::unordered_set& extensions) { return (extensions.find(file.extension()) != extensions.end()); } @@ -768,10 +768,26 @@ MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bo LMS_LOG(DBUPDATER, ERROR) << "Cannot process entry '" << path.string() << "': " << ec.message(); stats.errors.emplace_back(ScanError {path, ScanErrorType::CannotReadFile, ec.message()}); } + else if (std::filesystem::is_directory(path)) + { + ; + } else if (std::filesystem::is_regular_file(path)) { if (isFileSupported(path, _fileExtensions)) + { scanAudioFile(path, forceScan, stats ); + } + else + { + LMS_LOG(DBUPDATER, ERROR) << "Skipped '" << path.string() << "': file not supported"; + stats.errors.emplace_back(ScanError {path, ScanErrorType::NotSupported}); + } + } + else + { + LMS_LOG(DBUPDATER, ERROR) << "Skipped '" << path.string() << "': not a regular file"; + stats.errors.emplace_back(ScanError {path, ScanErrorType::NotRegular}); } itPath.increment(ec); @@ -782,7 +798,7 @@ MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bo // Check if a file exists and is still in a media directory static bool -checkFile(const std::filesystem::path& p, const std::filesystem::path& mediaDirectory, const std::set& extensions) +checkFile(const std::filesystem::path& p, const std::filesystem::path& mediaDirectory, const std::unordered_set& extensions) { try { diff --git a/src/libs/scanner/impl/MediaScanner.hpp b/src/libs/scanner/impl/MediaScanner.hpp index 645538a0..a04ceb39 100644 --- a/src/libs/scanner/impl/MediaScanner.hpp +++ b/src/libs/scanner/impl/MediaScanner.hpp @@ -108,7 +108,7 @@ class MediaScanner : public IMediaScanner std::size_t _scanVersion {}; Wt::WTime _startTime; Database::ScanSettings::UpdatePeriod _updatePeriod {Database::ScanSettings::UpdatePeriod::Never}; - std::set _fileExtensions; + std::unordered_set _fileExtensions; std::filesystem::path _mediaDirectory; Database::ScanSettings::RecommendationEngineType _recommendationEngineType; diff --git a/src/libs/scanner/include/scanner/MediaScannerStats.hpp b/src/libs/scanner/include/scanner/MediaScannerStats.hpp index 99c898b6..7356306e 100644 --- a/src/libs/scanner/include/scanner/MediaScannerStats.hpp +++ b/src/libs/scanner/include/scanner/MediaScannerStats.hpp @@ -32,6 +32,8 @@ namespace Scanner { CannotParseFile, // cannot parse file NoAudioTrack, // no audio track found BadDuration, // bad duration + NotSupported, // not supported + NotRegular, }; enum class DuplicateReason diff --git a/src/libs/utils/include/utils/Path.hpp b/src/libs/utils/include/utils/Path.hpp index f7e82893..caf3a148 100644 --- a/src/libs/utils/include/utils/Path.hpp +++ b/src/libs/utils/include/utils/Path.hpp @@ -34,3 +34,10 @@ bool ensureDirectory(const std::filesystem::path& dir); // Get the last write time since Epoch Wt::WDateTime getLastWriteTime(const std::filesystem::path& dir); +namespace std { + template <> + struct hash { + inline std::size_t operator()(const std::filesystem::path &path) const { return hash_value(path); } + }; +} + diff --git a/src/lms/ui/admin/DatabaseStatus.cpp b/src/lms/ui/admin/DatabaseStatus.cpp index 34133e01..017ef1a8 100644 --- a/src/lms/ui/admin/DatabaseStatus.cpp +++ b/src/lms/ui/admin/DatabaseStatus.cpp @@ -94,6 +94,8 @@ class ReportResource : public Wt::WResource case Scanner::ScanErrorType::CannotParseFile: return Wt::WString::tr("Lms.Admin.Database.Status.cannot-parse-file"); case Scanner::ScanErrorType::NoAudioTrack: return Wt::WString::tr("Lms.Admin.Database.Status.no-audio-track"); case Scanner::ScanErrorType::BadDuration: return Wt::WString::tr("Lms.Admin.Database.Status.bad-duration"); + case Scanner::ScanErrorType::NotSupported: return Wt::WString::tr("Lms.Admin.Database.Status.not-supported"); + case Scanner::ScanErrorType::NotRegular: return Wt::WString::tr("Lms.Admin.Database.Status.not-regular"); } return "?"; }