1
0
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:
David Sansome 2014-02-07 22:45:55 +11:00
commit eaf182a59a
5 changed files with 28 additions and 17 deletions

View File

@ -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)),

View File

@ -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) {

View File

@ -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);

View File

@ -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;

View File

@ -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_;