Merge pull request #15793 from glassez/save-path

Redesign "Incomplete folder" feature
This commit is contained in:
Vladimir Golovnev
2022-01-02 22:25:00 +03:00
committed by GitHub
52 changed files with 1498 additions and 599 deletions

View File

@@ -252,7 +252,8 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
, m_infoHash(m_nativeHandle.info_hash())
#endif
, m_name(params.name)
, m_savePath(Utils::Fs::toNativePath(params.savePath))
, m_savePath(params.savePath)
, m_downloadPath(params.downloadPath)
, m_category(params.category)
, m_tags(params.tags)
, m_ratioLimit(params.ratioLimit)
@@ -261,13 +262,10 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
, m_contentLayout(params.contentLayout)
, m_hasSeedStatus(params.hasSeedStatus)
, m_hasFirstLastPiecePriority(params.firstLastPiecePriority)
, m_useAutoTMM(params.savePath.isEmpty())
, m_useAutoTMM(params.useAutoTMM)
, m_isStopped(params.stopped)
, m_ltAddTorrentParams(params.ltAddTorrentParams)
{
if (m_useAutoTMM)
m_savePath = Utils::Fs::toNativePath(m_session->categorySavePath(m_category));
if (m_ltAddTorrentParams.ti)
{
// Initialize it only if torrent is added with metadata.
@@ -293,7 +291,7 @@ TorrentImpl::TorrentImpl(Session *session, lt::session *nativeSession
if (hasMetadata())
applyFirstLastPiecePriority(m_hasFirstLastPiecePriority);
// TODO: Remove the following upgrade code in v.4.4
// TODO: Remove the following upgrade code in v4.4
// == BEGIN UPGRADE CODE ==
const QString spath = actualStorageLocation();
for (int i = 0; i < filesCount(); ++i)
@@ -396,15 +394,52 @@ QString TorrentImpl::currentTracker() const
return QString::fromStdString(m_nativeStatus.current_tracker);
}
QString TorrentImpl::savePath(bool actual) const
QString TorrentImpl::savePath() const
{
if (actual)
return Utils::Fs::toUniformPath(actualStorageLocation());
else
return Utils::Fs::toUniformPath(m_savePath);
return isAutoTMMEnabled() ? m_session->categorySavePath(category()) : m_savePath;
}
QString TorrentImpl::rootPath(bool actual) const
void TorrentImpl::setSavePath(const QString &path)
{
Q_ASSERT(!isAutoTMMEnabled());
const QString resolvedPath = (QDir::isAbsolutePath(path) ? path : Utils::Fs::resolvePath(path, m_session->savePath()));
if (resolvedPath == savePath())
return;
m_savePath = resolvedPath;
m_session->handleTorrentNeedSaveResumeData(this);
const bool isFinished = isSeed() || m_hasSeedStatus;
if (isFinished)
moveStorage(savePath(), MoveStorageMode::KeepExistingFiles);
}
QString TorrentImpl::downloadPath() const
{
return isAutoTMMEnabled() ? m_session->categoryDownloadPath(category()) : m_downloadPath;
}
void TorrentImpl::setDownloadPath(const QString &path)
{
Q_ASSERT(!isAutoTMMEnabled());
const QString resolvedPath = ((path.isEmpty() || QDir::isAbsolutePath(path))
? path : Utils::Fs::resolvePath(path, m_session->downloadPath()));
if (resolvedPath == m_downloadPath)
return;
m_downloadPath = resolvedPath;
m_session->handleTorrentNeedSaveResumeData(this);
const bool isFinished = isSeed() || m_hasSeedStatus;
if (!isFinished)
moveStorage((m_downloadPath.isEmpty() ? savePath() : m_downloadPath), MoveStorageMode::KeepExistingFiles);
}
QString TorrentImpl::rootPath() const
{
if (!hasMetadata())
return {};
@@ -413,19 +448,19 @@ QString TorrentImpl::rootPath(bool actual) const
if (relativeRootPath.isEmpty())
return {};
return QDir(savePath(actual)).absoluteFilePath(relativeRootPath);
return QDir(actualStorageLocation()).absoluteFilePath(relativeRootPath);
}
QString TorrentImpl::contentPath(const bool actual) const
QString TorrentImpl::contentPath() const
{
if (!hasMetadata())
return {};
if (filesCount() == 1)
return QDir(savePath(actual)).absoluteFilePath(filePath(0));
return QDir(actualStorageLocation()).absoluteFilePath(filePath(0));
const QString rootPath = this->rootPath(actual);
return (rootPath.isEmpty() ? savePath(actual) : rootPath);
const QString rootPath = this->rootPath();
return (rootPath.isEmpty() ? actualStorageLocation() : rootPath);
}
bool TorrentImpl::isAutoTMMEnabled() const
@@ -435,19 +470,25 @@ bool TorrentImpl::isAutoTMMEnabled() const
void TorrentImpl::setAutoTMMEnabled(bool enabled)
{
if (m_useAutoTMM == enabled) return;
if (m_useAutoTMM == enabled)
return;
m_useAutoTMM = enabled;
if (!m_useAutoTMM)
{
m_savePath = m_session->categorySavePath(category());
m_downloadPath = m_session->categoryDownloadPath(category());
}
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentSavingModeChanged(this);
if (m_useAutoTMM)
move_impl(m_session->categorySavePath(m_category), MoveStorageMode::Overwrite);
adjustStorageLocation();
}
QString TorrentImpl::actualStorageLocation() const
{
return QString::fromStdString(m_nativeStatus.save_path);
return Utils::Fs::toUniformPath(QString::fromStdString(m_nativeStatus.save_path));
}
void TorrentImpl::setAutoManaged(const bool enable)
@@ -774,7 +815,7 @@ QStringList TorrentImpl::absoluteFilePaths() const
{
if (!hasMetadata()) return {};
const QDir saveDir {savePath(true)};
const QDir saveDir {actualStorageLocation()};
QStringList res;
res.reserve(filesCount());
for (int i = 0; i < filesCount(); ++i)
@@ -1351,7 +1392,7 @@ bool TorrentImpl::setCategory(const QString &category)
if (m_useAutoTMM)
{
if (!m_session->isDisableAutoTMMWhenCategoryChanged())
move_impl(m_session->categorySavePath(m_category), MoveStorageMode::Overwrite);
adjustStorageLocation();
else
setAutoTMMEnabled(false);
}
@@ -1360,41 +1401,6 @@ bool TorrentImpl::setCategory(const QString &category)
return true;
}
void TorrentImpl::move(QString path)
{
if (m_useAutoTMM)
{
m_useAutoTMM = false;
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentSavingModeChanged(this);
}
path = Utils::Fs::toUniformPath(path.trimmed());
if (path.isEmpty())
path = m_session->defaultSavePath();
if (!path.endsWith('/'))
path += '/';
move_impl(path, MoveStorageMode::KeepExistingFiles);
}
void TorrentImpl::move_impl(QString path, const MoveStorageMode mode)
{
if (path == savePath()) return;
path = Utils::Fs::toNativePath(path);
if (!useTempPath())
{
moveStorage(path, mode);
}
else
{
m_savePath = path;
m_session->handleTorrentNeedSaveResumeData(this);
m_session->handleTorrentSavePathChanged(this);
}
}
void TorrentImpl::forceReannounce(const int index)
{
m_nativeHandle.force_reannounce(0, index);
@@ -1611,7 +1617,7 @@ void TorrentImpl::resume(const TorrentOperatingMode mode)
void TorrentImpl::moveStorage(const QString &newPath, const MoveStorageMode mode)
{
if (m_session->addMoveTorrentStorageJob(this, newPath, mode))
if (m_session->addMoveTorrentStorageJob(this, Utils::Fs::toNativePath(newPath), mode))
{
m_storageIsMoving = true;
updateStatus();
@@ -1629,18 +1635,18 @@ void TorrentImpl::handleStateUpdate(const lt::torrent_status &nativeStatus)
updateStatus(nativeStatus);
}
void TorrentImpl::handleDownloadPathChanged()
{
adjustStorageLocation();
}
void TorrentImpl::handleMoveStorageJobFinished(const bool hasOutstandingJob)
{
m_session->handleTorrentNeedSaveResumeData(this);
m_storageIsMoving = hasOutstandingJob;
updateStatus();
const QString newPath = QString::fromStdString(m_nativeStatus.save_path);
if (!useTempPath() && (newPath != m_savePath))
{
m_savePath = newPath;
m_session->handleTorrentSavePathChanged(this);
}
m_session->handleTorrentSavePathChanged(this);
if (!m_storageIsMoving)
{
@@ -1717,7 +1723,7 @@ void TorrentImpl::handleTorrentCheckedAlert(const lt::torrent_checked_alert *p)
else if (progress() == 1.0)
m_hasSeedStatus = true;
adjustActualSavePath();
adjustStorageLocation();
manageIncompleteFiles();
}
@@ -1735,7 +1741,7 @@ void TorrentImpl::handleTorrentFinishedAlert(const lt::torrent_finished_alert *p
updateStatus();
m_hasSeedStatus = true;
adjustActualSavePath();
adjustStorageLocation();
manageIncompleteFiles();
m_session->handleTorrentNeedSaveResumeData(this);
@@ -1778,7 +1784,7 @@ void TorrentImpl::handleSaveResumeDataAlert(const lt::save_resume_data_alert *p)
QStringList filePaths = metadata.filePaths();
applyContentLayout(filePaths, m_contentLayout);
m_session->findIncompleteFiles(metadata, m_savePath, filePaths);
m_session->findIncompleteFiles(metadata, savePath(), downloadPath(), filePaths);
}
else
{
@@ -1812,7 +1818,6 @@ void TorrentImpl::prepareResumeData(const lt::add_torrent_params &params)
LoadTorrentParams resumeData;
resumeData.name = m_name;
resumeData.category = m_category;
resumeData.savePath = m_useAutoTMM ? "" : m_savePath;
resumeData.tags = m_tags;
resumeData.contentLayout = m_contentLayout;
resumeData.ratioLimit = m_ratioLimit;
@@ -1822,6 +1827,12 @@ void TorrentImpl::prepareResumeData(const lt::add_torrent_params &params)
resumeData.stopped = m_isStopped;
resumeData.operatingMode = m_operatingMode;
resumeData.ltAddTorrentParams = m_ltAddTorrentParams;
resumeData.useAutoTMM = m_useAutoTMM;
if (!resumeData.useAutoTMM)
{
resumeData.savePath = m_savePath;
resumeData.downloadPath = m_downloadPath;
}
m_session->handleTorrentResumeDataReady(this, resumeData);
}
@@ -1956,15 +1967,10 @@ void TorrentImpl::handlePerformanceAlert(const lt::performance_alert *p) const
, Log::INFO);
}
void TorrentImpl::handleTempPathChanged()
{
adjustActualSavePath();
}
void TorrentImpl::handleCategorySavePathChanged()
void TorrentImpl::handleCategoryOptionsChanged()
{
if (m_useAutoTMM)
move_impl(m_session->categorySavePath(m_category), MoveStorageMode::Overwrite);
adjustStorageLocation();
}
void TorrentImpl::handleAppendExtensionToggled()
@@ -2069,39 +2075,13 @@ void TorrentImpl::manageIncompleteFiles()
}
}
void TorrentImpl::adjustActualSavePath()
void TorrentImpl::adjustStorageLocation()
{
if (!isMoveInProgress())
adjustActualSavePath_impl();
else
m_moveFinishedTriggers.append([this]() { adjustActualSavePath_impl(); });
}
const QString downloadPath = this->downloadPath();
const bool isFinished = isSeed() || m_hasSeedStatus;
const QDir targetDir {((isFinished || downloadPath.isEmpty()) ? savePath() : downloadPath)};
void TorrentImpl::adjustActualSavePath_impl()
{
const bool needUseTempDir = useTempPath();
const QDir tempDir {m_session->torrentTempPath(m_torrentInfo)};
const QDir currentDir {actualStorageLocation()};
const QDir targetDir {needUseTempDir ? tempDir : QDir {savePath()}};
if (targetDir == currentDir) return;
if (!needUseTempDir)
{
if ((currentDir == tempDir) && (currentDir != QDir {m_session->tempPath()}))
{
// torrent without root folder still has it in its temporary save path
// so its temp path isn't equal to temp path root
const QString currentDirPath = currentDir.absolutePath();
m_moveFinishedTriggers.append([currentDirPath]
{
qDebug() << "Removing torrent temp folder:" << currentDirPath;
Utils::Fs::smartRemoveEmptyFolderTree(currentDirPath);
});
}
}
moveStorage(Utils::Fs::toNativePath(targetDir.absolutePath()), MoveStorageMode::Overwrite);
moveStorage(targetDir.absolutePath(), MoveStorageMode::Overwrite);
}
lt::torrent_handle TorrentImpl::nativeHandle() const
@@ -2114,11 +2094,6 @@ bool TorrentImpl::isMoveInProgress() const
return m_storageIsMoving;
}
bool TorrentImpl::useTempPath() const
{
return m_session->isTempPathEnabled() && !(isSeed() || m_hasSeedStatus);
}
void TorrentImpl::updateStatus()
{
updateStatus(m_nativeHandle.status());