Implement class for handling filesystem paths

PR #15915.
This commit is contained in:
Vladimir Golovnev
2022-02-08 06:03:48 +03:00
committed by GitHub
parent facfa26eed
commit dd1bd8ad10
131 changed files with 2252 additions and 1868 deletions

View File

@@ -47,6 +47,7 @@
#include "base/global.h"
#include "base/net/portforwarder.h"
#include "base/net/proxyconfigurationmanager.h"
#include "base/path.h"
#include "base/preferences.h"
#include "base/rss/rss_autodownloader.h"
#include "base/rss/rss_session.h"
@@ -112,28 +113,28 @@ void AppController::preferencesAction()
data["torrent_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategoryChanged();
data["save_path_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenDefaultSavePathChanged();
data["category_changed_tmm_enabled"] = !session->isDisableAutoTMMWhenCategorySavePathChanged();
data["save_path"] = Utils::Fs::toNativePath(session->savePath());
data["save_path"] = session->savePath().toString();
data["temp_path_enabled"] = session->isDownloadPathEnabled();
data["temp_path"] = Utils::Fs::toNativePath(session->downloadPath());
data["temp_path"] = session->downloadPath().toString();
data["use_category_paths_in_manual_mode"] = session->useCategoryPathsInManualMode();
data["export_dir"] = Utils::Fs::toNativePath(session->torrentExportDirectory());
data["export_dir_fin"] = Utils::Fs::toNativePath(session->finishedTorrentExportDirectory());
data["export_dir"] = session->torrentExportDirectory().toString();
data["export_dir_fin"] = session->finishedTorrentExportDirectory().toString();
// TODO: The following code is deprecated. Delete it once replaced by updated API method.
// === BEGIN DEPRECATED CODE === //
TorrentFilesWatcher *fsWatcher = TorrentFilesWatcher::instance();
const QHash<QString, TorrentFilesWatcher::WatchedFolderOptions> watchedFolders = fsWatcher->folders();
const QHash<Path, TorrentFilesWatcher::WatchedFolderOptions> watchedFolders = fsWatcher->folders();
QJsonObject nativeDirs;
for (auto i = watchedFolders.cbegin(); i != watchedFolders.cend(); ++i)
{
const QString watchedFolder = i.key();
const Path watchedFolder = i.key();
const BitTorrent::AddTorrentParams params = i.value().addTorrentParams;
if (params.savePath.isEmpty())
nativeDirs.insert(Utils::Fs::toNativePath(watchedFolder), 1);
nativeDirs.insert(watchedFolder.toString(), 1);
else if (params.savePath == watchedFolder)
nativeDirs.insert(Utils::Fs::toNativePath(watchedFolder), 0);
nativeDirs.insert(watchedFolder.toString(), 0);
else
nativeDirs.insert(Utils::Fs::toNativePath(watchedFolder), Utils::Fs::toNativePath(params.savePath));
nativeDirs.insert(watchedFolder.toString(), params.savePath.toString());
}
data["scan_dirs"] = nativeDirs;
// === END DEPRECATED CODE === //
@@ -149,7 +150,7 @@ void AppController::preferencesAction()
data["mail_notification_password"] = pref->getMailNotificationSMTPPassword();
// Run an external program on torrent completion
data["autorun_enabled"] = pref->isAutoRunEnabled();
data["autorun_program"] = Utils::Fs::toNativePath(pref->getAutoRunProgram());
data["autorun_program"] = pref->getAutoRunProgram();
// Connection
// Listening Port
@@ -177,7 +178,7 @@ void AppController::preferencesAction()
// IP Filtering
data["ip_filter_enabled"] = session->isIPFilteringEnabled();
data["ip_filter_path"] = Utils::Fs::toNativePath(session->IPFilterFile());
data["ip_filter_path"] = session->IPFilterFile().toString();
data["ip_filter_trackers"] = session->isTrackerFilteringEnabled();
data["banned_IPs"] = session->bannedIPs().join('\n');
@@ -236,8 +237,8 @@ void AppController::preferencesAction()
data["web_ui_port"] = pref->getWebUiPort();
data["web_ui_upnp"] = pref->useUPnPForWebUIPort();
data["use_https"] = pref->isWebUiHttpsEnabled();
data["web_ui_https_cert_path"] = pref->getWebUIHttpsCertificatePath();
data["web_ui_https_key_path"] = pref->getWebUIHttpsKeyPath();
data["web_ui_https_cert_path"] = pref->getWebUIHttpsCertificatePath().toString();
data["web_ui_https_key_path"] = pref->getWebUIHttpsKeyPath().toString();
// Authentication
data["web_ui_username"] = pref->getWebUiUsername();
data["bypass_local_auth"] = !pref->isWebUiLocalAuthEnabled();
@@ -251,7 +252,7 @@ void AppController::preferencesAction()
data["web_ui_session_timeout"] = pref->getWebUISessionTimeout();
// Use alternative Web UI
data["alternative_webui_enabled"] = pref->isAltWebUiEnabled();
data["alternative_webui_path"] = pref->getWebUiRootFolder();
data["alternative_webui_path"] = pref->getWebUiRootFolder().toString();
// Security
data["web_ui_clickjacking_protection_enabled"] = pref->isWebUiClickjackingProtectionEnabled();
data["web_ui_csrf_protection_enabled"] = pref->isWebUiCSRFProtectionEnabled();
@@ -400,31 +401,31 @@ void AppController::setPreferencesAction()
if (hasKey("category_changed_tmm_enabled"))
session->setDisableAutoTMMWhenCategorySavePathChanged(!it.value().toBool());
if (hasKey("save_path"))
session->setSavePath(it.value().toString());
session->setSavePath(Path(it.value().toString()));
if (hasKey("temp_path_enabled"))
session->setDownloadPathEnabled(it.value().toBool());
if (hasKey("temp_path"))
session->setDownloadPath(it.value().toString());
session->setDownloadPath(Path(it.value().toString()));
if (hasKey("use_category_paths_in_manual_mode"))
session->setUseCategoryPathsInManualMode(it.value().toBool());
if (hasKey("export_dir"))
session->setTorrentExportDirectory(it.value().toString());
session->setTorrentExportDirectory(Path(it.value().toString()));
if (hasKey("export_dir_fin"))
session->setFinishedTorrentExportDirectory(it.value().toString());
session->setFinishedTorrentExportDirectory(Path(it.value().toString()));
// TODO: The following code is deprecated. Delete it once replaced by updated API method.
// === BEGIN DEPRECATED CODE === //
if (hasKey("scan_dirs"))
{
QStringList scanDirs;
PathList scanDirs;
TorrentFilesWatcher *fsWatcher = TorrentFilesWatcher::instance();
const QStringList oldScanDirs = fsWatcher->folders().keys();
const PathList oldScanDirs = fsWatcher->folders().keys();
const QVariantHash nativeDirs = it.value().toHash();
for (auto i = nativeDirs.cbegin(); i != nativeDirs.cend(); ++i)
{
try
{
const QString watchedFolder = TorrentFilesWatcher::makeCleanPath(i.key());
const Path watchedFolder {i.key()};
TorrentFilesWatcher::WatchedFolderOptions options = fsWatcher->folders().value(watchedFolder);
BitTorrent::AddTorrentParams &params = options.addTorrentParams;
@@ -440,7 +441,7 @@ void AppController::setPreferencesAction()
}
else
{
const QString customSavePath = i.value().toString();
const Path customSavePath {i.value().toString()};
params.savePath = customSavePath;
params.useAutoTMM = false;
}
@@ -454,7 +455,7 @@ void AppController::setPreferencesAction()
}
// Update deleted folders
for (const QString &path : oldScanDirs)
for (const Path &path : oldScanDirs)
{
if (!scanDirs.contains(path))
fsWatcher->removeWatchedFolder(path);
@@ -531,7 +532,7 @@ void AppController::setPreferencesAction()
if (hasKey("ip_filter_enabled"))
session->setIPFilteringEnabled(it.value().toBool());
if (hasKey("ip_filter_path"))
session->setIPFilterFile(it.value().toString());
session->setIPFilterFile(Path(it.value().toString()));
if (hasKey("ip_filter_trackers"))
session->setTrackerFilteringEnabled(it.value().toBool());
if (hasKey("banned_IPs"))
@@ -650,9 +651,9 @@ void AppController::setPreferencesAction()
if (hasKey("use_https"))
pref->setWebUiHttpsEnabled(it.value().toBool());
if (hasKey("web_ui_https_cert_path"))
pref->setWebUIHttpsCertificatePath(it.value().toString());
pref->setWebUIHttpsCertificatePath(Path(it.value().toString()));
if (hasKey("web_ui_https_key_path"))
pref->setWebUIHttpsKeyPath(it.value().toString());
pref->setWebUIHttpsKeyPath(Path(it.value().toString()));
// Authentication
if (hasKey("web_ui_username"))
pref->setWebUiUsername(it.value().toString());
@@ -677,7 +678,7 @@ void AppController::setPreferencesAction()
if (hasKey("alternative_webui_enabled"))
pref->setAltWebUiEnabled(it.value().toBool());
if (hasKey("alternative_webui_path"))
pref->setWebUiRootFolder(it.value().toString());
pref->setWebUiRootFolder(Path(it.value().toString()));
// Security
if (hasKey("web_ui_clickjacking_protection_enabled"))
pref->setWebUiClickjackingProtectionEnabled(it.value().toBool());
@@ -869,7 +870,7 @@ void AppController::setPreferencesAction()
void AppController::defaultSavePathAction()
{
setResult(BitTorrent::Session::instance()->savePath());
setResult(BitTorrent::Session::instance()->savePath().toString());
}
void AppController::networkInterfaceListAction()

View File

@@ -34,6 +34,7 @@
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/torrent.h"
#include "base/bittorrent/trackerentry.h"
#include "base/path.h"
#include "base/tagset.h"
#include "base/utils/fs.h"
@@ -130,9 +131,9 @@ QVariantMap serialize(const BitTorrent::Torrent &torrent)
{KEY_TORRENT_TAGS, torrent.tags().join(QLatin1String(", "))},
{KEY_TORRENT_SUPER_SEEDING, torrent.superSeeding()},
{KEY_TORRENT_FORCE_START, torrent.isForced()},
{KEY_TORRENT_SAVE_PATH, Utils::Fs::toNativePath(torrent.savePath())},
{KEY_TORRENT_DOWNLOAD_PATH, Utils::Fs::toNativePath(torrent.downloadPath())},
{KEY_TORRENT_CONTENT_PATH, Utils::Fs::toNativePath(torrent.contentPath())},
{KEY_TORRENT_SAVE_PATH, torrent.savePath().toString()},
{KEY_TORRENT_DOWNLOAD_PATH, torrent.downloadPath().toString()},
{KEY_TORRENT_CONTENT_PATH, torrent.contentPath().toString()},
{KEY_TORRENT_ADDED_ON, torrent.addedTime().toSecsSinceEpoch()},
{KEY_TORRENT_COMPLETION_ON, torrent.completedTime().toSecsSinceEpoch()},
{KEY_TORRENT_TRACKER, torrent.currentTracker()},

View File

@@ -579,7 +579,14 @@ void SyncController::torrentPeersAction()
};
if (torrent->hasMetadata())
peer.insert(KEY_PEER_FILES, torrent->info().filesForPiece(pi.downloadingPieceIndex()).join('\n'));
{
const PathList filePaths = torrent->info().filesForPiece(pi.downloadingPieceIndex());
QStringList filesForPiece;
filesForPiece.reserve(filePaths.size());
for (const Path &filePath : filePaths)
filesForPiece.append(filePath.toString());
peer.insert(KEY_PEER_FILES, filesForPiece.join(QLatin1Char('\n')));
}
if (resolvePeerCountries)
{

View File

@@ -31,7 +31,6 @@
#include <functional>
#include <QBitArray>
#include <QDir>
#include <QJsonArray>
#include <QJsonObject>
#include <QList>
@@ -431,8 +430,8 @@ void TorrentsController::propertiesAction()
dataDict[KEY_PROP_COMPLETION_DATE] = -1;
dataDict[KEY_PROP_CREATION_DATE] = -1;
}
dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath());
dataDict[KEY_PROP_DOWNLOAD_PATH] = Utils::Fs::toNativePath(torrent->downloadPath());
dataDict[KEY_PROP_SAVE_PATH] = torrent->savePath().toString();
dataDict[KEY_PROP_DOWNLOAD_PATH] = torrent->downloadPath().toString();
dataDict[KEY_PROP_COMMENT] = torrent->comment();
setResult(dataDict);
@@ -565,7 +564,7 @@ void TorrentsController::filesAction()
{KEY_FILE_PRIORITY, static_cast<int>(priorities[index])},
{KEY_FILE_SIZE, torrent->fileSize(index)},
{KEY_FILE_AVAILABILITY, fileAvailability[index]},
{KEY_FILE_NAME, Utils::Fs::toUniformPath(torrent->filePath(index))}
{KEY_FILE_NAME, torrent->filePath(index).toString()}
};
const BitTorrent::TorrentInfo::PieceRange idx = info.filePieces(index);
@@ -682,8 +681,8 @@ void TorrentsController::addAction()
addTorrentParams.firstLastPiecePriority = firstLastPiece;
addTorrentParams.addPaused = addPaused;
addTorrentParams.contentLayout = contentLayout;
addTorrentParams.savePath = savepath;
addTorrentParams.downloadPath = downloadPath;
addTorrentParams.savePath = Path(savepath);
addTorrentParams.downloadPath = Path(downloadPath);
addTorrentParams.useDownloadPath = useDownloadPath;
addTorrentParams.category = category;
addTorrentParams.tags.insert(tags.cbegin(), tags.cend());
@@ -1081,25 +1080,25 @@ void TorrentsController::setLocationAction()
requireParams({"hashes", "location"});
const QStringList hashes {params()["hashes"].split('|')};
const QString newLocation {params()["location"].trimmed()};
const Path newLocation {params()["location"].trimmed()};
if (newLocation.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
// try to create the location if it does not exist
if (!QDir(newLocation).mkpath("."))
if (!Utils::Fs::mkpath(newLocation))
throw APIError(APIErrorType::Conflict, tr("Cannot make save path"));
// check permissions
if (!QFileInfo(newLocation).isWritable())
if (!Utils::Fs::isWritable(newLocation))
throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
applyToTorrents(hashes, [newLocation](BitTorrent::Torrent *const torrent)
{
LogMsg(tr("WebUI Set location: moving \"%1\", from \"%2\" to \"%3\"")
.arg(torrent->name(), Utils::Fs::toNativePath(torrent->savePath()), Utils::Fs::toNativePath(newLocation)));
.arg(torrent->name(), torrent->savePath().toString(), newLocation.toString()));
torrent->setAutoTMMEnabled(false);
torrent->setSavePath(Utils::Fs::expandPathAbs(newLocation));
torrent->setSavePath(newLocation);
});
}
@@ -1108,17 +1107,17 @@ void TorrentsController::setSavePathAction()
requireParams({"id", "path"});
const QStringList ids {params()["id"].split('|')};
const QString newPath {params()["path"]};
const Path newPath {params()["path"]};
if (newPath.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Save path cannot be empty"));
// try to create the directory if it does not exist
if (!QDir(newPath).mkpath("."))
if (!Utils::Fs::mkpath(newPath))
throw APIError(APIErrorType::Conflict, tr("Cannot create target directory"));
// check permissions
if (!QFileInfo(newPath).isWritable())
if (!Utils::Fs::isWritable(newPath))
throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
applyToTorrents(ids, [&newPath](BitTorrent::Torrent *const torrent)
@@ -1133,16 +1132,16 @@ void TorrentsController::setDownloadPathAction()
requireParams({"id", "path"});
const QStringList ids {params()["id"].split('|')};
const QString newPath {params()["path"]};
const Path newPath {params()["path"]};
if (!newPath.isEmpty())
{
// try to create the directory if it does not exist
if (!QDir(newPath).mkpath("."))
if (!Utils::Fs::mkpath(newPath))
throw APIError(APIErrorType::Conflict, tr("Cannot create target directory"));
// check permissions
if (!QFileInfo(newPath).isWritable())
if (!Utils::Fs::isWritable(newPath))
throw APIError(APIErrorType::AccessDenied, tr("Cannot write to directory"));
}
@@ -1225,13 +1224,13 @@ void TorrentsController::createCategoryAction()
if (!BitTorrent::Session::isValidCategoryName(category))
throw APIError(APIErrorType::Conflict, tr("Incorrect category name"));
const QString savePath = params()["savePath"];
const Path savePath {params()["savePath"]};
const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]);
BitTorrent::CategoryOptions categoryOptions;
categoryOptions.savePath = savePath;
if (useDownloadPath.has_value())
{
const QString downloadPath = params()["downloadPath"];
const Path downloadPath {params()["downloadPath"]};
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
}
@@ -1247,13 +1246,13 @@ void TorrentsController::editCategoryAction()
if (category.isEmpty())
throw APIError(APIErrorType::BadParams, tr("Category cannot be empty"));
const QString savePath = params()["savePath"];
const Path savePath {params()["savePath"]};
const auto useDownloadPath = parseBool(params()["downloadPathEnabled"]);
BitTorrent::CategoryOptions categoryOptions;
categoryOptions.savePath = savePath;
if (useDownloadPath.has_value())
{
const QString downloadPath = params()["downloadPath"];
const Path downloadPath {params()["downloadPath"]};
categoryOptions.downloadPath = {useDownloadPath.value(), downloadPath};
}
@@ -1367,8 +1366,8 @@ void TorrentsController::renameFileAction()
if (!torrent)
throw APIError(APIErrorType::NotFound);
const QString oldPath = params()["oldPath"];
const QString newPath = params()["newPath"];
const Path oldPath {params()["oldPath"]};
const Path newPath {params()["newPath"]};
try
{
@@ -1389,8 +1388,8 @@ void TorrentsController::renameFolderAction()
if (!torrent)
throw APIError(APIErrorType::NotFound);
const QString oldPath = params()["oldPath"];
const QString newPath = params()["newPath"];
const Path oldPath {params()["oldPath"]};
const Path newPath {params()["newPath"]};
try
{