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 "?";
}