Attempt to properly scan all the files during scan

This commit is contained in:
emeric
2020-02-20 13:32:48 +01:00
parent 428ab70d27
commit 284231ff92
7 changed files with 59 additions and 68 deletions
-2
View File
@@ -61,8 +61,6 @@
<message id="Lms.Admin.Database.Status.last-scan-not-available">Not available</message> <message id="Lms.Admin.Database.Status.last-scan-not-available">Not available</message>
<message id="Lms.Admin.Database.Status.last-scan-status">Scanned {1} files in {2} on {3} ({4} errors, {5} duplicates)</message> <message id="Lms.Admin.Database.Status.last-scan-status">Scanned {1} files in {2} on {3} ({4} errors, {5} duplicates)</message>
<message id="Lms.Admin.Database.Status.no-audio-track">No audio track</message> <message id="Lms.Admin.Database.Status.no-audio-track">No audio track</message>
<message id="Lms.Admin.Database.Status.not-regular">Not a regular file</message>
<message id="Lms.Admin.Database.Status.not-supported">File type not supported</message>
<message id="Lms.Admin.Database.Status.same-hash">Duplicated file hash</message> <message id="Lms.Admin.Database.Status.same-hash">Duplicated file hash</message>
<message id="Lms.Admin.Database.Status.same-mbid">Duplicated MBID</message> <message id="Lms.Admin.Database.Status.same-mbid">Duplicated MBID</message>
<message id="Lms.Admin.Database.Status.status">Status</message> <message id="Lms.Admin.Database.Status.status">Status</message>
-2
View File
@@ -61,8 +61,6 @@
<message id="Lms.Admin.Database.Status.last-scan-not-available">Non disponible</message> <message id="Lms.Admin.Database.Status.last-scan-not-available">Non disponible</message>
<message id="Lms.Admin.Database.Status.last-scan-status">{1} fichiers scannés en {2} le {3} ({4} erreurs, {5} duplicatas)</message> <message id="Lms.Admin.Database.Status.last-scan-status">{1} fichiers scannés en {2} le {3} ({4} erreurs, {5} duplicatas)</message>
<message id="Lms.Admin.Database.Status.no-audio-track">Pas de piste audio</message> <message id="Lms.Admin.Database.Status.no-audio-track">Pas de piste audio</message>
<message id="Lms.Admin.Database.Status.not-regular">Fichier non régulier</message>
<message id="Lms.Admin.Database.Status.not-supported">Type de fichier non supporté</message>
<message id="Lms.Admin.Database.Status.same-hash">Hash dupliqué</message> <message id="Lms.Admin.Database.Status.same-hash">Hash dupliqué</message>
<message id="Lms.Admin.Database.Status.same-mbid">MBID dupliqué</message> <message id="Lms.Admin.Database.Status.same-mbid">MBID dupliqué</message>
<message id="Lms.Admin.Database.Status.status">Statut</message> <message id="Lms.Admin.Database.Status.status">Statut</message>
+16 -57
View File
@@ -350,33 +350,21 @@ MediaScanner::scheduleNextScan()
void void
MediaScanner::countAllFiles(ScanStats& stats) MediaScanner::countAllFiles(ScanStats& stats)
{ {
std::error_code ec;
stats.filesToScan = 0; stats.filesToScan = 0;
std::filesystem::recursive_directory_iterator itPath {_mediaDirectory, std::filesystem::directory_options::follow_directory_symlink, ec}; exploreFilesRecursive(_mediaDirectory, [&](std::error_code ec, const std::filesystem::path& path)
if (ec)
{ {
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << _mediaDirectory.string() << "': " << ec.message(); if (ec)
return; return;
}
std::filesystem::recursive_directory_iterator itEnd; if (isFileSupported(path, _fileExtensions))
while (_running && itPath != itEnd)
{
const std::filesystem::path& path {*itPath};
if (!ec)
{ {
if (std::filesystem::is_regular_file(path) && isFileSupported(path, _fileExtensions)) stats.filesToScan++;
stats.filesToScan ++;
if (stats.filesToScan % 250 == 0) if (stats.filesToScan % 250 == 0)
notifyInProgressIfNeeded(stats); notifyInProgressIfNeeded(stats);
} }
});
itPath.increment(ec);
}
} }
void void
@@ -592,8 +580,6 @@ MediaScanner::notifyInProgressIfNeeded(const ScanStats& stats)
void void
MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, ScanStats& stats) MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, ScanStats& stats)
{ {
notifyInProgressIfNeeded(stats);
Wt::WDateTime lastWriteTime; Wt::WDateTime lastWriteTime;
try try
{ {
@@ -748,50 +734,23 @@ MediaScanner::scanAudioFile(const std::filesystem::path& file, bool forceScan, S
void void
MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bool forceScan, ScanStats& stats) MediaScanner::scanMediaDirectory(const std::filesystem::path& mediaDirectory, bool forceScan, ScanStats& stats)
{ {
std::error_code ec; exploreFilesRecursive(mediaDirectory, [&](std::error_code ec, const std::filesystem::path& path)
std::filesystem::recursive_directory_iterator itPath {_mediaDirectory, std::filesystem::directory_options::follow_directory_symlink, ec};
if (ec)
{ {
LMS_LOG(DBUPDATER, ERROR) << "Cannot iterate over '" << mediaDirectory.string() << "': " << ec.message();
stats.errors.emplace_back(ScanError {mediaDirectory, ScanErrorType::CannotReadFile, ec.message()});
return;
}
std::filesystem::recursive_directory_iterator itEnd;
while (_running && itPath != itEnd)
{
const std::filesystem::path& path {*itPath};
if (ec) if (ec)
{ {
LMS_LOG(DBUPDATER, ERROR) << "Cannot process entry '" << path.string() << "': " << ec.message(); LMS_LOG(DBUPDATER, ERROR) << "Cannot process entry '" << path.string() << "': " << ec.message();
stats.errors.emplace_back(ScanError {path, ScanErrorType::CannotReadFile, ec.message()}); stats.errors.emplace_back(ScanError {path, ScanErrorType::CannotReadFile, ec.message()});
}
else if (std::filesystem::is_directory(path)) return;
{
;
}
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); if (isFileSupported(path, _fileExtensions))
} {
scanAudioFile(path, forceScan, stats );
notifyInProgressIfNeeded(stats);
}
});
notifyInProgress(stats); notifyInProgress(stats);
} }
@@ -32,8 +32,6 @@ namespace Scanner {
CannotParseFile, // cannot parse file CannotParseFile, // cannot parse file
NoAudioTrack, // no audio track found NoAudioTrack, // no audio track found
BadDuration, // bad duration BadDuration, // bad duration
NotSupported, // not supported
NotRegular,
}; };
enum class DuplicateReason enum class DuplicateReason
+36
View File
@@ -87,3 +87,39 @@ getLastWriteTime(const std::filesystem::path& file)
return Wt::WDateTime::fromTime_t(sb.st_mtime); return Wt::WDateTime::fromTime_t(sb.st_mtime);
} }
void
exploreFilesRecursive(const std::filesystem::path& directory, std::function<void(std::error_code, const std::filesystem::path&)> cb)
{
std::error_code ec;
std::filesystem::directory_iterator itPath {directory, std::filesystem::directory_options::follow_directory_symlink, ec};
if (ec)
{
cb(ec, directory);
return;
}
std::filesystem::directory_iterator itEnd;
while (itPath != itEnd)
{
if (ec)
{
cb(ec, *itPath);
}
else
{
if (std::filesystem::is_regular_file(*itPath, ec))
cb(ec, *itPath);
else if (std::filesystem::is_directory(*itPath, ec))
{
if (!ec)
exploreFilesRecursive(*itPath, cb);
else
cb(ec, *itPath);
}
}
itPath.increment(ec);
}
}
+7 -3
View File
@@ -20,6 +20,7 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
#include <functional>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -34,10 +35,13 @@ bool ensureDirectory(const std::filesystem::path& dir);
// Get the last write time since Epoch // Get the last write time since Epoch
Wt::WDateTime getLastWriteTime(const std::filesystem::path& dir); Wt::WDateTime getLastWriteTime(const std::filesystem::path& dir);
namespace std { void exploreFilesRecursive(const std::filesystem::path& directory, std::function<void(std::error_code, const std::filesystem::path&)> cb);
namespace std
{
template <> template <>
struct hash<std::filesystem::path> { struct hash<std::filesystem::path>
{
inline std::size_t operator()(const std::filesystem::path &path) const { return hash_value(path); } inline std::size_t operator()(const std::filesystem::path &path) const { return hash_value(path); }
}; };
} }
-2
View File
@@ -94,8 +94,6 @@ class ReportResource : public Wt::WResource
case Scanner::ScanErrorType::CannotParseFile: return Wt::WString::tr("Lms.Admin.Database.Status.cannot-parse-file"); 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::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::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 "?"; return "?";
} }