mirror of
https://github.com/clementine-player/Clementine
synced 2025-02-05 13:47:54 +01:00
Merge pull request #4161 from BrummbQ/master
don't rescan unchanged files if library has been unavailable. Fixes #3032
This commit is contained in:
commit
eaf182a59a
@ -126,6 +126,8 @@ void Library::Init() {
|
||||
backend_, SLOT(UpdateMTimesOnly(SongList)));
|
||||
connect(watcher_, SIGNAL(SongsDeleted(SongList)),
|
||||
backend_, SLOT(MarkSongsUnavailable(SongList)));
|
||||
connect(watcher_, SIGNAL(SongsReadded(SongList,bool)),
|
||||
backend_, SLOT(MarkSongsUnavailable(SongList,bool)));
|
||||
connect(watcher_, SIGNAL(SubdirsDiscovered(SubdirectoryList)),
|
||||
backend_, SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
|
||||
connect(watcher_, SIGNAL(SubdirsMTimeUpdated(SubdirectoryList)),
|
||||
|
@ -445,12 +445,12 @@ void LibraryBackend::DeleteSongs(const SongList &songs) {
|
||||
UpdateTotalSongCountAsync();
|
||||
}
|
||||
|
||||
void LibraryBackend::MarkSongsUnavailable(const SongList &songs) {
|
||||
void LibraryBackend::MarkSongsUnavailable(const SongList& songs, bool unavailable) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
QSqlQuery remove(QString("UPDATE %1 SET unavailable = 1 WHERE ROWID = :id")
|
||||
.arg(songs_table_), db);
|
||||
QSqlQuery remove(QString("UPDATE %1 SET unavailable = %2 WHERE ROWID = :id")
|
||||
.arg(songs_table_).arg(int(unavailable)), db);
|
||||
|
||||
ScopedTransaction transaction(&db);
|
||||
foreach (const Song& song, songs) {
|
||||
|
@ -174,7 +174,7 @@ class LibraryBackend : public LibraryBackendInterface {
|
||||
void AddOrUpdateSongs(const SongList& songs);
|
||||
void UpdateMTimesOnly(const SongList& songs);
|
||||
void DeleteSongs(const SongList& songs);
|
||||
void MarkSongsUnavailable(const SongList& songs);
|
||||
void MarkSongsUnavailable(const SongList& songs, bool unavailable = true);
|
||||
void AddOrUpdateSubdirs(const SubdirectoryList& subdirs);
|
||||
void UpdateCompilations();
|
||||
void UpdateManualAlbumArt(const QString& artist, const QString& album, const QString& art);
|
||||
|
@ -108,6 +108,9 @@ LibraryWatcher::ScanTransaction::~ScanTransaction() {
|
||||
if (!deleted_songs.isEmpty())
|
||||
emit watcher_->SongsDeleted(deleted_songs);
|
||||
|
||||
if (!readded_songs.isEmpty())
|
||||
emit watcher_->SongsReadded(readded_songs);
|
||||
|
||||
if (!new_subdirs.isEmpty())
|
||||
emit watcher_->SubdirsDiscovered(new_subdirs);
|
||||
|
||||
@ -323,8 +326,7 @@ void LibraryWatcher::ScanSubdirectory(
|
||||
|
||||
// watch out for cue songs which have their mtime equal to qMax(media_file_mtime, cue_sheet_mtime)
|
||||
bool changed = (matching_song.mtime() != qMax(file_info.lastModified().toTime_t(), song_cue_mtime))
|
||||
|| cue_deleted || cue_added
|
||||
|| matching_song.is_unavailable();
|
||||
|| cue_deleted || cue_added;
|
||||
|
||||
// Also want to look to see whether the album art has changed
|
||||
QString image = ImageForSong(file, album_art);
|
||||
@ -347,6 +349,11 @@ void LibraryWatcher::ScanSubdirectory(
|
||||
UpdateNonCueAssociatedSong(file, matching_song, image, cue_deleted, t);
|
||||
}
|
||||
}
|
||||
|
||||
// nothing has changed - mark the song available without re-scanning
|
||||
if (matching_song.is_unavailable())
|
||||
t->readded_songs << matching_song;
|
||||
|
||||
} else {
|
||||
// The song is on disk but not in the DB
|
||||
SongList song_list = ScanNewFile(file, path, matching_cue, &cues_processed);
|
||||
@ -516,11 +523,11 @@ void LibraryWatcher::PreserveUserSetData(const QString& file, const QString& ima
|
||||
|
||||
out->MergeUserSetData(matching_song);
|
||||
|
||||
// The song was deleted from the database (e.g. due to an unmounted
|
||||
// The song was deleted from the database (e.g. due to an unmounted
|
||||
// filesystem), but has been restored.
|
||||
if (matching_song.is_unavailable()) {
|
||||
qLog(Debug) << file << " unavailable song restored";
|
||||
|
||||
|
||||
t->new_songs << *out;
|
||||
} else if (!matching_song.IsMetadataEqual(*out)) {
|
||||
qLog(Debug) << file << "metadata changed";
|
||||
@ -623,14 +630,14 @@ void LibraryWatcher::RescanPathsNow() {
|
||||
}
|
||||
|
||||
QString LibraryWatcher::PickBestImage(const QStringList& images) {
|
||||
|
||||
|
||||
// This is used when there is more than one image in a directory.
|
||||
// Pick the biggest image that matches the most important filter
|
||||
|
||||
|
||||
QStringList filtered;
|
||||
|
||||
|
||||
foreach(const QString& filter_text, best_image_filters_) {
|
||||
// the images in the images list are represented by a full path,
|
||||
// the images in the images list are represented by a full path,
|
||||
// so we need to isolate just the filename
|
||||
foreach(const QString& image, images) {
|
||||
QFileInfo file_info(image);
|
||||
@ -639,13 +646,13 @@ QString LibraryWatcher::PickBestImage(const QStringList& images) {
|
||||
filtered << image;
|
||||
}
|
||||
|
||||
/* We assume the filters are give in the order best to worst, so
|
||||
/* We assume the filters are give in the order best to worst, so
|
||||
if we've got a result, we go with it. Otherwise we might
|
||||
start capturing more generic rules */
|
||||
if (!filtered.isEmpty())
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (filtered.isEmpty()){
|
||||
// the filter was too restrictive, just use the original list
|
||||
filtered = images;
|
||||
|
@ -57,6 +57,7 @@ class LibraryWatcher : public QObject {
|
||||
void NewOrUpdatedSongs(const SongList& songs);
|
||||
void SongsMTimeUpdated(const SongList& songs);
|
||||
void SongsDeleted(const SongList& songs);
|
||||
void SongsReadded(const SongList& songs, bool unavailable = false);
|
||||
void SubdirsDiscovered(const SubdirectoryList& subdirs);
|
||||
void SubdirsMTimeUpdated(const SubdirectoryList& subdirs);
|
||||
void CompilationsNeedUpdating();
|
||||
@ -99,6 +100,7 @@ class LibraryWatcher : public QObject {
|
||||
bool ignores_mtime() const { return ignores_mtime_; }
|
||||
|
||||
SongList deleted_songs;
|
||||
SongList readded_songs;
|
||||
SongList new_songs;
|
||||
SongList touched_songs;
|
||||
SubdirectoryList new_subdirs;
|
||||
@ -160,7 +162,7 @@ class LibraryWatcher : public QObject {
|
||||
void UpdateNonCueAssociatedSong(const QString& file, const Song& matching_song,
|
||||
const QString& image, bool cue_deleted,
|
||||
ScanTransaction* t) ;
|
||||
// Updates a new song with some metadata taken from it's equivalent old
|
||||
// Updates a new song with some metadata taken from it's equivalent old
|
||||
// song (for example rating and score).
|
||||
void PreserveUserSetData(const QString& file, const QString& image,
|
||||
const Song& matching_song, Song* out, ScanTransaction* t);
|
||||
@ -178,12 +180,12 @@ class LibraryWatcher : public QObject {
|
||||
FileSystemWatcherInterface* fs_watcher_;
|
||||
QHash<QString, Directory> subdir_mapping_;
|
||||
|
||||
/* A list of words use to try to identify the (likely) best image
|
||||
/* A list of words use to try to identify the (likely) best image
|
||||
* found in an directory to use as cover artwork.
|
||||
* e.g. using ["front", "cover"] would identify front.jpg and
|
||||
* exclude back.jpg.
|
||||
*/
|
||||
QStringList best_image_filters_;
|
||||
QStringList best_image_filters_;
|
||||
|
||||
bool stop_requested_;
|
||||
bool scan_on_startup_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user