-
-
Notifications
You must be signed in to change notification settings - Fork 200
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CollectionWatcher: Ignore special filesystem paths
Fixes #1615
- Loading branch information
Showing
2 changed files
with
93 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* Strawberry Music Player | ||
* This file was part of Clementine. | ||
* Copyright 2010, David Sansome <[email protected]> | ||
* Copyright 2018-2023, Jonas Kvinge <[email protected]> | ||
* Copyright 2018-2025, Jonas Kvinge <[email protected]> | ||
* | ||
* Strawberry is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
|
@@ -27,6 +27,7 @@ | |
#include <QObject> | ||
#include <QThread> | ||
#include <QIODevice> | ||
#include <QStorageInfo> | ||
#include <QDir> | ||
#include <QDirIterator> | ||
#include <QFile> | ||
|
@@ -51,6 +52,7 @@ | |
#include "core/settings.h" | ||
#include "utilities/imageutils.h" | ||
#include "constants/timeconstants.h" | ||
#include "constants/filesystemconstants.h" | ||
#include "tagreader/tagreaderclient.h" | ||
#include "collectiondirectory.h" | ||
#include "collectionbackend.h" | ||
|
@@ -464,6 +466,24 @@ CollectionSubdirectoryList CollectionWatcher::ScanTransaction::GetAllSubdirs() { | |
|
||
void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const CollectionSubdirectoryList &subdirs) { | ||
|
||
{ | ||
const QFileInfo path_info(dir.path); | ||
if (path_info.isSymbolicLink()) { | ||
const QStorageInfo storage_info(path_info.symLinkTarget()); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
qLog(Warning) << "Ignoring collection directory path" << dir.path << "which is a symbolic link to path" << path_info.symLinkTarget() << "with rejected filesystem type" << storage_info.fileSystemType(); | ||
return; | ||
} | ||
} | ||
else { | ||
const QStorageInfo storage_info(dir.path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
qLog(Warning) << "Ignoring collection directory path" << dir.path << "with rejected filesystem type" << storage_info.fileSystemType(); | ||
return; | ||
} | ||
} | ||
} | ||
|
||
CancelStop(); | ||
|
||
watched_dirs_[dir.id] = dir; | ||
|
@@ -506,17 +526,29 @@ void CollectionWatcher::AddDirectory(const CollectionDirectory &dir, const Colle | |
|
||
void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSubdirectory &subdir, const quint64 files_count, ScanTransaction *t, const bool force_noincremental) { | ||
|
||
QFileInfo path_info(path); | ||
const QFileInfo path_info(path); | ||
|
||
// Do not scan symlinked dirs that are already in collection | ||
if (path_info.isSymLink()) { | ||
QString real_path = path_info.symLinkTarget(); | ||
const QString real_path = path_info.symLinkTarget(); | ||
const QStorageInfo storage_info(real_path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
qLog(Warning) << "Ignoring symbolic link" << path << "which links to" << real_path << "with rejected filesystem type" << storage_info.fileSystemType(); | ||
return; | ||
} | ||
// Do not scan symlinked dirs that are already in collection | ||
for (const CollectionDirectory &dir : std::as_const(watched_dirs_)) { | ||
if (real_path.startsWith(dir.path)) { | ||
return; | ||
} | ||
} | ||
} | ||
else { | ||
const QStorageInfo storage_info(path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
qLog(Warning) << "Ignoring path" << path << "with rejected filesystem type" << storage_info.fileSystemType(); | ||
return; | ||
} | ||
} | ||
|
||
bool songs_missing_fingerprint = false; | ||
bool songs_missing_loudness_characteristics = false; | ||
|
@@ -556,32 +588,40 @@ void CollectionWatcher::ScanSubdirectory(const QString &path, const CollectionSu | |
|
||
if (stop_or_abort_requested()) return; | ||
|
||
QString child(it.next()); | ||
QFileInfo child_info(child); | ||
const QString child_filepath = it.next(); | ||
const QFileInfo child_fileinfo(child_filepath); | ||
|
||
if (child_fileinfo.isSymLink()) { | ||
QStorageInfo storage_info(child_fileinfo.symLinkTarget()); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
qLog(Warning) << "Ignoring symbolic link" << child_filepath << "which links to" << child_fileinfo.symLinkTarget() << "with rejected filesystem type" << storage_info.fileSystemType(); | ||
continue; | ||
} | ||
} | ||
|
||
if (child_info.isDir()) { | ||
if (!t->HasSeenSubdir(child)) { | ||
if (child_fileinfo.isDir()) { | ||
if (!t->HasSeenSubdir(child_filepath)) { | ||
// We haven't seen this subdirectory before - add it to a list, and later we'll tell the backend about it and scan it. | ||
CollectionSubdirectory new_subdir; | ||
new_subdir.directory_id = -1; | ||
new_subdir.path = child; | ||
new_subdir.mtime = child_info.lastModified().toSecsSinceEpoch(); | ||
new_subdir.path = child_filepath; | ||
new_subdir.mtime = child_fileinfo.lastModified().toSecsSinceEpoch(); | ||
my_new_subdirs << new_subdir; | ||
} | ||
t->AddToProgress(1); | ||
} | ||
else { | ||
QString ext_part(ExtensionPart(child)); | ||
QString dir_part(DirectoryPart(child)); | ||
if (Song::kRejectedExtensions.contains(child_info.suffix(), Qt::CaseInsensitive) || child_info.baseName() == "qt_temp"_L1) { | ||
QString ext_part(ExtensionPart(child_filepath)); | ||
QString dir_part(DirectoryPart(child_filepath)); | ||
if (Song::kRejectedExtensions.contains(child_fileinfo.suffix(), Qt::CaseInsensitive) || child_fileinfo.baseName() == "qt_temp"_L1) { | ||
t->AddToProgress(1); | ||
} | ||
else if (sValidImages.contains(ext_part)) { | ||
album_art[dir_part] << child; | ||
album_art[dir_part] << child_filepath; | ||
t->AddToProgress(1); | ||
} | ||
else if (tagreader_client_->IsMediaFileBlocking(child)) { | ||
files_on_disk << child; | ||
else if (tagreader_client_->IsMediaFileBlocking(child_filepath)) { | ||
files_on_disk << child_filepath; | ||
} | ||
else { | ||
t->AddToProgress(1); | ||
|
@@ -1153,7 +1193,7 @@ void CollectionWatcher::RescanPathsNow() { | |
|
||
QMap<QString, quint64> subdir_files_count; | ||
for (const QString &path : paths) { | ||
quint64 files_count = FilesCountForPath(&transaction, path); | ||
const quint64 files_count = FilesCountForPath(&transaction, path); | ||
subdir_files_count[path] = files_count; | ||
transaction.AddToProgressMax(files_count); | ||
} | ||
|
@@ -1316,28 +1356,55 @@ void CollectionWatcher::PerformScan(const bool incremental, const bool ignore_mt | |
|
||
quint64 CollectionWatcher::FilesCountForPath(ScanTransaction *t, const QString &path) { | ||
|
||
const QFileInfo path_info(path); | ||
if (path_info.isSymLink()) { | ||
const QString real_path = path_info.symLinkTarget(); | ||
const QStorageInfo storage_info(real_path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
return 0; | ||
} | ||
for (const CollectionDirectory &dir : std::as_const(watched_dirs_)) { | ||
if (real_path.startsWith(dir.path)) { | ||
return 0; | ||
} | ||
} | ||
} | ||
else { | ||
const QStorageInfo storage_info(path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
return 0; | ||
} | ||
} | ||
|
||
quint64 i = 0; | ||
QDirIterator it(path, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot); | ||
while (it.hasNext()) { | ||
|
||
if (stop_or_abort_requested()) break; | ||
|
||
QString child = it.next(); | ||
QFileInfo path_info(child); | ||
const QString child_filepath = it.next(); | ||
const QFileInfo child_fileinfo(child_filepath); | ||
|
||
if (child_fileinfo.isDir()) { | ||
if (child_fileinfo.isSymLink()) { | ||
|
||
const QString real_path = child_fileinfo.symLinkTarget(); | ||
|
||
QStorageInfo storage_info(real_path); | ||
if (kRejectedFileSystems.contains(storage_info.fileSystemType())) { | ||
continue; | ||
} | ||
|
||
if (path_info.isDir()) { | ||
if (path_info.isSymLink()) { | ||
QString real_path = path_info.symLinkTarget(); | ||
for (const CollectionDirectory &dir : std::as_const(watched_dirs_)) { | ||
if (real_path.startsWith(dir.path)) { | ||
continue; | ||
} | ||
} | ||
} | ||
|
||
if (!t->HasSeenSubdir(child) && !path_info.isHidden()) { | ||
if (!t->HasSeenSubdir(child_filepath) && !child_fileinfo.isHidden()) { | ||
// We haven't seen this subdirectory before, so we need to include the file count for this directory too. | ||
i += FilesCountForPath(t, child); | ||
i += FilesCountForPath(t, child_filepath); | ||
} | ||
|
||
} | ||
|
@@ -1385,7 +1452,7 @@ void CollectionWatcher::RescanSongs(const SongList &songs) { | |
if (stop_or_abort_requested()) break; | ||
if (subdir.path != song_path) continue; | ||
qLog(Debug) << "Rescan for directory ID" << song.directory_id() << "directory" << subdir.path; | ||
quint64 files_count = FilesCountForPath(&transaction, subdir.path); | ||
const quint64 files_count = FilesCountForPath(&transaction, subdir.path); | ||
ScanSubdirectory(song_path, subdir, files_count, &transaction); | ||
scanned_paths << subdir.path; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* Strawberry Music Player | ||
* This file was part of Clementine. | ||
* Copyright 2010, David Sansome <[email protected]> | ||
* Copyright 2018-2023, Jonas Kvinge <[email protected]> | ||
* Copyright 2018-2025, Jonas Kvinge <[email protected]> | ||
* | ||
* Strawberry is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
|