Attempt to properly scan all the files during scan
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 "?";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user