Added an option to skip duplicated recording MBID. Fixes #180
This commit is contained in:
@@ -186,12 +186,12 @@ Track::findPaths(Session& session, Range range)
|
||||
}
|
||||
|
||||
RangeResults<TrackId>
|
||||
Track::findMBIDDuplicates(Session& session, Range range)
|
||||
Track::findRecordingMBIDDuplicates(Session& session, Range range)
|
||||
{
|
||||
session.checkSharedLocked();
|
||||
|
||||
auto query {session.getDboSession().query<TrackId>( "SELECT track.id FROM track WHERE mbid in (SELECT mbid FROM track WHERE mbid <> '' GROUP BY mbid HAVING COUNT (*) > 1)")
|
||||
.orderBy("track.release_id,track.disc_number,track.track_number,track.mbid")};
|
||||
auto query {session.getDboSession().query<TrackId>( "SELECT track.id FROM track WHERE recording_mbid in (SELECT recording_mbid FROM track WHERE recording_mbid <> '' GROUP BY recording_mbid HAVING COUNT (*) > 1)")
|
||||
.orderBy("track.release_id,track.disc_number,track.track_number,track.recording_mbid")};
|
||||
|
||||
return execQuery(query, range);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ class Track : public Object<Track, TrackId>
|
||||
static RangeResults<TrackId> find(Session& session, const FindParameters& parameters);
|
||||
static RangeResults<TrackId> findByNameAndReleaseName(Session& session, std::string_view trackName, std::string_view releaseName);
|
||||
static RangeResults<PathResult> findPaths(Session& session, Range range);
|
||||
static RangeResults<TrackId> findMBIDDuplicates(Session& session, Range range);
|
||||
static RangeResults<TrackId> findRecordingMBIDDuplicates(Session& session, Range range);
|
||||
static RangeResults<TrackId> findWithRecordingMBIDAndMissingFeatures(Session& session, Range range);
|
||||
|
||||
// Create utility
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "metadata/TagLibParser.hpp"
|
||||
#include "services/recommendation/IRecommendationService.hpp"
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/IConfig.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Path.hpp"
|
||||
#include "utils/UUID.hpp"
|
||||
@@ -256,8 +257,11 @@ createScannerService(Db& db, Recommendation::IRecommendationService& recommendat
|
||||
|
||||
ScannerService::ScannerService(Db& db, Recommendation::IRecommendationService& recommendationService)
|
||||
: _recommendationService {recommendationService}
|
||||
, _skipDuplicateRecordingMBID {Service<IConfig>::get()->getBool("scanner-skip-duplicate-recording-mbid", false)}
|
||||
, _dbSession {db}
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "skipDuplicateRecordingMBID = " << _skipDuplicateRecordingMBID;
|
||||
|
||||
// For now, always use TagLib
|
||||
_metadataParser = std::make_unique<MetaData::TagLibParser>();
|
||||
|
||||
@@ -719,6 +723,25 @@ ScannerService::scanAudioFile(const std::filesystem::path& file, bool forceScan,
|
||||
|
||||
Track::pointer track {Track::findByPath(_dbSession, file) };
|
||||
|
||||
// Skip duplicate recording MBID
|
||||
if (trackInfo->recordingMBID && _skipDuplicateRecordingMBID)
|
||||
{
|
||||
for (Track::pointer otherTrack : Track::findByRecordingMBID(_dbSession, *trackInfo->recordingMBID))
|
||||
{
|
||||
if (track && track->getId() == otherTrack->getId())
|
||||
continue;
|
||||
|
||||
LMS_LOG(DBUPDATER, DEBUG) << "Skipped '" << file.string() << "' (similar recording MBID in '" << otherTrack->getPath().string() << "')";
|
||||
// This recording MBID already exists, just remove what we just scanned
|
||||
if (track)
|
||||
{
|
||||
track.remove();
|
||||
stats.deletions++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We estimate this is an audio file if:
|
||||
// - we found a least one audio stream
|
||||
// - the duration is not null
|
||||
@@ -1026,14 +1049,14 @@ ScannerService::checkDuplicatedAudioFiles(ScanStats& stats)
|
||||
|
||||
auto transaction {_dbSession.createSharedTransaction()};
|
||||
|
||||
const RangeResults<TrackId> tracks = Track::findMBIDDuplicates(_dbSession, Range {});
|
||||
const RangeResults<TrackId> tracks = Track::findRecordingMBIDDuplicates(_dbSession, Range {});
|
||||
for (const TrackId trackId : tracks.results)
|
||||
{
|
||||
const Track::pointer track {Track::find(_dbSession, trackId)};
|
||||
if (auto trackMBID {track->getTrackMBID()})
|
||||
if (auto recordingMBID {track->getRecordingMBID()})
|
||||
{
|
||||
LMS_LOG(DBUPDATER, INFO) << "Found duplicated Track MBID [" << trackMBID->getAsString() << "], file: " << track->getPath().string() << " - " << track->getName();
|
||||
stats.duplicates.emplace_back(ScanDuplicate {track->getId(), DuplicateReason::SameMBID});
|
||||
LMS_LOG(DBUPDATER, INFO) << "Found duplicated recording MBID [" << recordingMBID->getAsString() << "], file: " << track->getPath().string() << " - " << track->getName();
|
||||
stats.duplicates.emplace_back(ScanDuplicate {track->getId(), DuplicateReason::SameRecordingMBID});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,7 @@ namespace Scanner
|
||||
std::atomic<bool> _abortScan {};
|
||||
Wt::WIOService _ioService;
|
||||
boost::asio::system_timer _scheduleTimer {_ioService};
|
||||
const bool _skipDuplicateRecordingMBID {};
|
||||
Events _events;
|
||||
std::chrono::system_clock::time_point _lastScanInProgressEmit {};
|
||||
Database::Session _dbSession;
|
||||
|
||||
@@ -30,16 +30,16 @@ namespace Scanner
|
||||
{
|
||||
enum class ScanErrorType
|
||||
{
|
||||
CannotReadFile, // cannot read file
|
||||
CannotParseFile, // cannot parse file
|
||||
NoAudioTrack, // no audio track found
|
||||
BadDuration, // bad duration
|
||||
CannotReadFile, // cannot read file
|
||||
CannotParseFile, // cannot parse file
|
||||
NoAudioTrack, // no audio track found
|
||||
BadDuration, // bad duration
|
||||
};
|
||||
|
||||
enum class DuplicateReason
|
||||
{
|
||||
SameHash,
|
||||
SameMBID,
|
||||
SameRecordingMBID,
|
||||
};
|
||||
|
||||
struct ScanError
|
||||
|
||||
@@ -96,7 +96,7 @@ class ReportResource : public Wt::WResource
|
||||
|
||||
response.out() << track->getPath().string();
|
||||
if (auto mbid {track->getTrackMBID()})
|
||||
response.out() << " (Track MBID " << mbid->getAsString() << ")";
|
||||
response.out() << " (Recording MBID " << mbid->getAsString() << ")";
|
||||
|
||||
response.out() << " - " << duplicateReasonToWString(duplicate.reason).toUTF8() << '\n';
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class ReportResource : public Wt::WResource
|
||||
switch (reason)
|
||||
{
|
||||
case Scanner::DuplicateReason::SameHash: return Wt::WString::tr("Lms.Admin.ScannerController.same-hash");
|
||||
case Scanner::DuplicateReason::SameMBID: return Wt::WString::tr("Lms.Admin.ScannerController.same-mbid");
|
||||
case Scanner::DuplicateReason::SameRecordingMBID: return Wt::WString::tr("Lms.Admin.ScannerController.same-mbid");
|
||||
}
|
||||
return "?";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user