mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-23 17:56:50 +03:00
Fix TorrentHandle path methods. Closes #3847.
This commit is contained in:
parent
d0ebe08bf5
commit
501ab07024
8 changed files with 89 additions and 52 deletions
|
@ -142,13 +142,13 @@ void Application::torrentFinished(BitTorrent::TorrentHandle *const torrent)
|
||||||
// AutoRun program
|
// AutoRun program
|
||||||
if (pref->isAutoRunEnabled()) {
|
if (pref->isAutoRunEnabled()) {
|
||||||
QString program = pref->getAutoRunProgram();
|
QString program = pref->getAutoRunProgram();
|
||||||
int file_count = torrent->filesCount();
|
int fileCount = torrent->filesCount();
|
||||||
|
|
||||||
program.replace("%N", torrent->name());
|
program.replace("%N", torrent->name());
|
||||||
program.replace("%F", (file_count > 1) ? "" : torrent->fileName(0));
|
program.replace("%F", (fileCount > 1) ? "" : torrent->fileName(0));
|
||||||
program.replace("%L", torrent->label());
|
program.replace("%L", torrent->label());
|
||||||
program.replace("%D", Utils::Fs::toNativePath(torrent->rootPath()));
|
program.replace("%D", Utils::Fs::toNativePath(torrent->savePath()));
|
||||||
program.replace("%K", (file_count > 1) ? "multi" : "single");
|
program.replace("%K", (fileCount > 1) ? "multi" : "single");
|
||||||
program.replace("%C", QString::number(torrent->filesCount()));
|
program.replace("%C", QString::number(torrent->filesCount()));
|
||||||
program.replace("%Z", QString::number(torrent->totalSize()));
|
program.replace("%Z", QString::number(torrent->totalSize()));
|
||||||
program.replace("%T", torrent->currentTracker());
|
program.replace("%T", torrent->currentTracker());
|
||||||
|
|
|
@ -813,11 +813,7 @@ bool Session::deleteTorrent(const QString &hash, bool deleteLocalFiles)
|
||||||
|
|
||||||
// Remove it from session
|
// Remove it from session
|
||||||
if (deleteLocalFiles) {
|
if (deleteLocalFiles) {
|
||||||
QString tmp = torrent->filePath(0);
|
m_savePathsToRemove[torrent->hash()] = torrent->rootPath(true);
|
||||||
tmp.truncate(tmp.indexOf("/")); // get the torrent root directory name
|
|
||||||
if (!tmp.isEmpty())
|
|
||||||
m_savePathsToRemove[torrent->hash()] = torrent->actualSavePath() + tmp;
|
|
||||||
|
|
||||||
m_nativeSession->remove_torrent(torrent->nativeHandle(), libt::session::delete_files);
|
m_nativeSession->remove_torrent(torrent->nativeHandle(), libt::session::delete_files);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1722,7 +1718,7 @@ void Session::handleTorrentFinished(TorrentHandle *const torrent)
|
||||||
const QString torrentRelpath = torrent->filePath(i);
|
const QString torrentRelpath = torrent->filePath(i);
|
||||||
if (torrentRelpath.endsWith(".torrent", Qt::CaseInsensitive)) {
|
if (torrentRelpath.endsWith(".torrent", Qt::CaseInsensitive)) {
|
||||||
qDebug("Found possible recursive torrent download.");
|
qDebug("Found possible recursive torrent download.");
|
||||||
const QString torrentFullpath = torrent->actualSavePath() + "/" + torrentRelpath;
|
const QString torrentFullpath = torrent->savePath(true) + "/" + torrentRelpath;
|
||||||
qDebug("Full subtorrent path is %s", qPrintable(torrentFullpath));
|
qDebug("Full subtorrent path is %s", qPrintable(torrentFullpath));
|
||||||
TorrentInfo torrentInfo = TorrentInfo::loadFromFile(torrentFullpath);
|
TorrentInfo torrentInfo = TorrentInfo::loadFromFile(torrentFullpath);
|
||||||
if (torrentInfo.isValid()) {
|
if (torrentInfo.isValid()) {
|
||||||
|
|
|
@ -297,21 +297,30 @@ QString TorrentHandle::currentTracker() const
|
||||||
return Utils::String::fromStdString(m_nativeStatus.current_tracker);
|
return Utils::String::fromStdString(m_nativeStatus.current_tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TorrentHandle::savePath() const
|
QString TorrentHandle::savePath(bool actual) const
|
||||||
{
|
{
|
||||||
return Utils::Fs::fromNativePath(m_savePath);
|
if (actual)
|
||||||
|
return Utils::Fs::fromNativePath(nativeActualSavePath());
|
||||||
|
else
|
||||||
|
return Utils::Fs::fromNativePath(m_savePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TorrentHandle::rootPath() const
|
QString TorrentHandle::rootPath(bool actual) const
|
||||||
{
|
{
|
||||||
if (filesCount() > 1) {
|
QString firstFilePath = filePath(0);
|
||||||
QString first_filepath = filePath(0);
|
const int slashIndex = firstFilePath.indexOf("/");
|
||||||
const int slashIndex = first_filepath.indexOf("/");
|
if (slashIndex >= 0)
|
||||||
if (slashIndex >= 0)
|
return QDir(savePath(actual)).absoluteFilePath(firstFilePath.left(slashIndex));
|
||||||
return QDir(actualSavePath()).absoluteFilePath(first_filepath.left(slashIndex));
|
else
|
||||||
}
|
return QDir(savePath(actual)).absoluteFilePath(firstFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
return actualSavePath();
|
QString TorrentHandle::contentPath(bool actual) const
|
||||||
|
{
|
||||||
|
if (filesCount() == 1)
|
||||||
|
return QDir(savePath(actual)).absoluteFilePath(filePath(0));
|
||||||
|
else
|
||||||
|
return rootPath(actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TorrentHandle::nativeActualSavePath() const
|
QString TorrentHandle::nativeActualSavePath() const
|
||||||
|
@ -319,11 +328,6 @@ QString TorrentHandle::nativeActualSavePath() const
|
||||||
return Utils::String::fromStdString(m_nativeStatus.save_path);
|
return Utils::String::fromStdString(m_nativeStatus.save_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TorrentHandle::actualSavePath() const
|
|
||||||
{
|
|
||||||
return Utils::Fs::fromNativePath(nativeActualSavePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<TrackerEntry> TorrentHandle::trackers() const
|
QList<TrackerEntry> TorrentHandle::trackers() const
|
||||||
{
|
{
|
||||||
QList<TrackerEntry> entries;
|
QList<TrackerEntry> entries;
|
||||||
|
@ -533,7 +537,7 @@ QStringList TorrentHandle::absoluteFilePaths() const
|
||||||
{
|
{
|
||||||
if (!hasMetadata()) return QStringList();
|
if (!hasMetadata()) return QStringList();
|
||||||
|
|
||||||
QDir saveDir(actualSavePath());
|
QDir saveDir(savePath(true));
|
||||||
QStringList res;
|
QStringList res;
|
||||||
for (int i = 0; i < filesCount(); ++i)
|
for (int i = 0; i < filesCount(); ++i)
|
||||||
res << Utils::Fs::expandPathAbs(saveDir.absoluteFilePath(filePath(i)));
|
res << Utils::Fs::expandPathAbs(saveDir.absoluteFilePath(filePath(i)));
|
||||||
|
@ -544,7 +548,7 @@ QStringList TorrentHandle::absoluteFilePathsUnwanted() const
|
||||||
{
|
{
|
||||||
if (!hasMetadata()) return QStringList();
|
if (!hasMetadata()) return QStringList();
|
||||||
|
|
||||||
QDir saveDir(actualSavePath());
|
QDir saveDir(savePath(true));
|
||||||
QStringList res;
|
QStringList res;
|
||||||
std::vector<int> fp;
|
std::vector<int> fp;
|
||||||
SAFE_GET(fp, file_priorities);
|
SAFE_GET(fp, file_priorities);
|
||||||
|
@ -1489,7 +1493,7 @@ void TorrentHandle::handleFileRenamedAlert(libtorrent::file_renamed_alert *p)
|
||||||
QString newPath = newPathParts.join("/");
|
QString newPath = newPathParts.join("/");
|
||||||
if (!newPathParts.isEmpty() && (oldPath != newPath)) {
|
if (!newPathParts.isEmpty() && (oldPath != newPath)) {
|
||||||
qDebug("oldPath(%s) != newPath(%s)", qPrintable(oldPath), qPrintable(newPath));
|
qDebug("oldPath(%s) != newPath(%s)", qPrintable(oldPath), qPrintable(newPath));
|
||||||
oldPath = QString("%1/%2").arg(actualSavePath()).arg(oldPath);
|
oldPath = QString("%1/%2").arg(savePath(true)).arg(oldPath);
|
||||||
qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(oldPath));
|
qDebug("Detected folder renaming, attempt to delete old folder: %s", qPrintable(oldPath));
|
||||||
QDir().rmpath(oldPath);
|
QDir().rmpath(oldPath);
|
||||||
}
|
}
|
||||||
|
@ -1784,7 +1788,7 @@ void TorrentHandle::prioritizeFiles(const QVector<int> &priorities)
|
||||||
SAFE_CALL(prioritize_files, priorities.toStdVector());
|
SAFE_CALL(prioritize_files, priorities.toStdVector());
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely...";
|
qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely...";
|
||||||
QString spath = actualSavePath();
|
QString spath = savePath(true);
|
||||||
for (int i = 0; i < priorities.size(); ++i) {
|
for (int i = 0; i < priorities.size(); ++i) {
|
||||||
QString filepath = filePath(i);
|
QString filepath = filePath(i);
|
||||||
// Move unwanted files to a .unwanted subfolder
|
// Move unwanted files to a .unwanted subfolder
|
||||||
|
|
|
@ -179,9 +179,50 @@ namespace BitTorrent
|
||||||
qlonglong pieceLength() const;
|
qlonglong pieceLength() const;
|
||||||
qlonglong wastedSize() const;
|
qlonglong wastedSize() const;
|
||||||
QString currentTracker() const;
|
QString currentTracker() const;
|
||||||
QString actualSavePath() const;
|
|
||||||
QString savePath() const;
|
// 1. savePath() - the path where all the files and subfolders of torrent are stored (as always).
|
||||||
QString rootPath() const;
|
// 2. rootPath() - absolute path of torrent file tree (save path + first item from 1st torrent file path).
|
||||||
|
// 3. contentPath() - absolute path of torrent content (root path for multifile torrents, absolute file path for singlefile torrents).
|
||||||
|
//
|
||||||
|
// These methods have 'actual' parameter (defaults to false) which allow to get actual or final path variant.
|
||||||
|
//
|
||||||
|
// Examples.
|
||||||
|
// Suppose we have three torrent with following structures and save path `/home/user/torrents`:
|
||||||
|
//
|
||||||
|
// Torrent A (multifile)
|
||||||
|
//
|
||||||
|
// torrentA/
|
||||||
|
// subdir1/
|
||||||
|
// subdir2/
|
||||||
|
// file1
|
||||||
|
// file2
|
||||||
|
// file3
|
||||||
|
// file4
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Torrent B (singlefile)
|
||||||
|
//
|
||||||
|
// torrentB/
|
||||||
|
// subdir1/
|
||||||
|
// file1
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Torrent C (singlefile)
|
||||||
|
//
|
||||||
|
// file1
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Results:
|
||||||
|
// | | rootPath | contentPath |
|
||||||
|
// |---|------------------------------|--------------------------------------------|
|
||||||
|
// | A | /home/user/torrents/torrentA | /home/user/torrents/torrentA |
|
||||||
|
// | B | /home/user/torrents/torrentB | /home/user/torrents/torrentB/subdir1/file1 |
|
||||||
|
// | C | /home/user/torrents/file1 | /home/user/torrents/file1 |
|
||||||
|
|
||||||
|
QString savePath(bool actual = false) const;
|
||||||
|
QString rootPath(bool actual = false) const;
|
||||||
|
QString contentPath(bool actual = false) const;
|
||||||
|
|
||||||
int filesCount() const;
|
int filesCount() const;
|
||||||
int piecesCount() const;
|
int piecesCount() const;
|
||||||
int piecesHave() const;
|
int piecesHave() const;
|
||||||
|
|
|
@ -269,7 +269,7 @@ BitTorrent::TorrentHandle *PropertiesWidget::getCurrentTorrent() const
|
||||||
void PropertiesWidget::updateSavePath(BitTorrent::TorrentHandle *const torrent)
|
void PropertiesWidget::updateSavePath(BitTorrent::TorrentHandle *const torrent)
|
||||||
{
|
{
|
||||||
if (m_torrent == torrent) {
|
if (m_torrent == torrent) {
|
||||||
save_path->setText(Utils::Fs::toNativePath(m_torrent->rootPath()));
|
save_path->setText(Utils::Fs::toNativePath(m_torrent->savePath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,7 +509,7 @@ void PropertiesWidget::openDoubleClickedFile(const QModelIndex &index) {
|
||||||
|
|
||||||
void PropertiesWidget::openFile(const QModelIndex &index) {
|
void PropertiesWidget::openFile(const QModelIndex &index) {
|
||||||
int i = PropListModel->getFileIndex(index);
|
int i = PropListModel->getFileIndex(index);
|
||||||
const QDir saveDir(m_torrent->actualSavePath());
|
const QDir saveDir(m_torrent->savePath(true));
|
||||||
const QString filename = m_torrent->filePath(i);
|
const QString filename = m_torrent->filePath(i);
|
||||||
const QString file_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(filename));
|
const QString file_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(filename));
|
||||||
qDebug("Trying to open file at %s", qPrintable(file_path));
|
qDebug("Trying to open file at %s", qPrintable(file_path));
|
||||||
|
@ -532,13 +532,13 @@ void PropertiesWidget::openFolder(const QModelIndex &index, bool containing_fold
|
||||||
}
|
}
|
||||||
if (path_items.isEmpty())
|
if (path_items.isEmpty())
|
||||||
return;
|
return;
|
||||||
const QDir saveDir(m_torrent->actualSavePath());
|
const QDir saveDir(m_torrent->savePath(true));
|
||||||
const QString relative_path = path_items.join("/");
|
const QString relative_path = path_items.join("/");
|
||||||
absolute_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(relative_path));
|
absolute_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(relative_path));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int i = PropListModel->getFileIndex(index);
|
int i = PropListModel->getFileIndex(index);
|
||||||
const QDir saveDir(m_torrent->actualSavePath());
|
const QDir saveDir(m_torrent->savePath(true));
|
||||||
const QString relative_path = m_torrent->filePath(i);
|
const QString relative_path = m_torrent->filePath(i);
|
||||||
absolute_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(relative_path));
|
absolute_path = Utils::Fs::expandPath(saveDir.absoluteFilePath(relative_path));
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,7 @@ void PropertiesWidget::renameSelectedFile() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const bool force_recheck = QFile::exists(m_torrent->actualSavePath() + "/" + new_name);
|
const bool force_recheck = QFile::exists(m_torrent->savePath(true) + "/" + new_name);
|
||||||
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(new_name));
|
qDebug("Renaming %s to %s", qPrintable(old_name), qPrintable(new_name));
|
||||||
m_torrent->renameFile(file_index, new_name);
|
m_torrent->renameFile(file_index, new_name);
|
||||||
// Force recheck
|
// Force recheck
|
||||||
|
@ -736,7 +736,7 @@ void PropertiesWidget::renameSelectedFile() {
|
||||||
if (current_name.startsWith(old_path)) {
|
if (current_name.startsWith(old_path)) {
|
||||||
QString new_name = current_name;
|
QString new_name = current_name;
|
||||||
new_name.replace(0, old_path.length(), new_path);
|
new_name.replace(0, old_path.length(), new_path);
|
||||||
if (!force_recheck && QDir(m_torrent->actualSavePath()).exists(new_name))
|
if (!force_recheck && QDir(m_torrent->savePath(true)).exists(new_name))
|
||||||
force_recheck = true;
|
force_recheck = true;
|
||||||
new_name = Utils::Fs::expandPath(new_name);
|
new_name = Utils::Fs::expandPath(new_name);
|
||||||
qDebug("Rename %s to %s", qPrintable(current_name), qPrintable(new_name));
|
qDebug("Rename %s to %s", qPrintable(current_name), qPrintable(new_name));
|
||||||
|
@ -748,7 +748,7 @@ void PropertiesWidget::renameSelectedFile() {
|
||||||
// Rename folder in torrent files model too
|
// Rename folder in torrent files model too
|
||||||
PropListModel->setData(index, new_name_last);
|
PropListModel->setData(index, new_name_last);
|
||||||
// Remove old folder
|
// Remove old folder
|
||||||
const QDir old_folder(m_torrent->actualSavePath() + "/" + old_path);
|
const QDir old_folder(m_torrent->savePath(true) + "/" + old_path);
|
||||||
int timeout = 10;
|
int timeout = 10;
|
||||||
while(!QDir().rmpath(old_folder.absolutePath()) && timeout > 0) {
|
while(!QDir().rmpath(old_folder.absolutePath()) && timeout > 0) {
|
||||||
// FIXME: We should not sleep here (freezes the UI for 1 second)
|
// FIXME: We should not sleep here (freezes the UI for 1 second)
|
||||||
|
|
|
@ -221,7 +221,7 @@ QVariant TorrentModel::data(const QModelIndex &index, int role) const
|
||||||
case TR_TIME_ELAPSED:
|
case TR_TIME_ELAPSED:
|
||||||
return (role == Qt::DisplayRole) ? torrent->activeTime() : torrent->seedingTime();
|
return (role == Qt::DisplayRole) ? torrent->activeTime() : torrent->seedingTime();
|
||||||
case TR_SAVE_PATH:
|
case TR_SAVE_PATH:
|
||||||
return Utils::Fs::toNativePath(torrent->rootPath());
|
return Utils::Fs::toNativePath(torrent->savePath());
|
||||||
case TR_COMPLETED:
|
case TR_COMPLETED:
|
||||||
return torrent->completedSize();
|
return torrent->completedSize();
|
||||||
case TR_RATIO_LIMIT:
|
case TR_RATIO_LIMIT:
|
||||||
|
|
|
@ -213,9 +213,9 @@ void TransferListWidget::torrentDoubleClicked(const QModelIndex& index)
|
||||||
break;
|
break;
|
||||||
case OPEN_DEST:
|
case OPEN_DEST:
|
||||||
if (torrent->filesCount() == 1)
|
if (torrent->filesCount() == 1)
|
||||||
Utils::Misc::openFolderSelect(QDir(torrent->rootPath()).absoluteFilePath(torrent->filePath(0)));
|
Utils::Misc::openFolderSelect(torrent->contentPath(true));
|
||||||
else
|
else
|
||||||
Utils::Misc::openPath(torrent->rootPath());
|
Utils::Misc::openPath(torrent->contentPath(true));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,15 +383,11 @@ void TransferListWidget::openSelectedTorrentsFolder() const
|
||||||
{
|
{
|
||||||
QSet<QString> pathsList;
|
QSet<QString> pathsList;
|
||||||
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) {
|
foreach (BitTorrent::TorrentHandle *const torrent, getSelectedTorrents()) {
|
||||||
QString path;
|
QString path = torrent->contentPath(true);
|
||||||
if (torrent->filesCount() == 1) {
|
if (!pathsList.contains(path)) {
|
||||||
path = QDir(torrent->rootPath()).absoluteFilePath(torrent->filePath(0));
|
if (torrent->filesCount() == 1)
|
||||||
if (!pathsList.contains(path))
|
|
||||||
Utils::Misc::openFolderSelect(path);
|
Utils::Misc::openFolderSelect(path);
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
path = torrent->rootPath();
|
|
||||||
if (!pathsList.contains(path))
|
|
||||||
Utils::Misc::openPath(path);
|
Utils::Misc::openPath(path);
|
||||||
}
|
}
|
||||||
pathsList.insert(path);
|
pathsList.insert(path);
|
||||||
|
|
|
@ -510,7 +510,7 @@ QByteArray btjson::getPropertiesForTorrent(const QString& hash)
|
||||||
dataDict[KEY_PROP_COMPLETION_DATE] = -1;
|
dataDict[KEY_PROP_COMPLETION_DATE] = -1;
|
||||||
dataDict[KEY_PROP_CREATION_DATE] = -1;
|
dataDict[KEY_PROP_CREATION_DATE] = -1;
|
||||||
}
|
}
|
||||||
dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->rootPath());
|
dataDict[KEY_PROP_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath());
|
||||||
dataDict[KEY_PROP_COMMENT] = torrent->comment();
|
dataDict[KEY_PROP_COMMENT] = torrent->comment();
|
||||||
|
|
||||||
return json::toJson(dataDict);
|
return json::toJson(dataDict);
|
||||||
|
@ -636,7 +636,7 @@ QVariantMap toMap(BitTorrent::TorrentHandle *const torrent)
|
||||||
ret[KEY_TORRENT_LABEL] = torrent->label();
|
ret[KEY_TORRENT_LABEL] = torrent->label();
|
||||||
ret[KEY_TORRENT_SUPER_SEEDING] = torrent->superSeeding();
|
ret[KEY_TORRENT_SUPER_SEEDING] = torrent->superSeeding();
|
||||||
ret[KEY_TORRENT_FORCE_START] = torrent->isForced();
|
ret[KEY_TORRENT_FORCE_START] = torrent->isForced();
|
||||||
ret[KEY_TORRENT_SAVE_PATH] = Utils::Fs::toNativePath(torrent->rootPath());
|
ret[KEY_TORRENT_SAVE_PATH] = Utils::Fs::toNativePath(torrent->savePath());
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue