Browse Source

Merge pull request #3984 from glassez/root_path

Fix TorrentHandle path methods. Closes #3847.
adaptive-webui-19844
sledgehammer999 9 years ago
parent
commit
472fff06dc
  1. 7
      src/app/application.cpp
  2. 8
      src/core/bittorrent/session.cpp
  3. 42
      src/core/bittorrent/torrenthandle.cpp
  4. 47
      src/core/bittorrent/torrenthandle.h
  5. 4
      src/gui/options_imp.cpp
  6. 14
      src/gui/properties/propertieswidget.cpp
  7. 2
      src/gui/torrentmodel.cpp
  8. 16
      src/gui/transferlistwidget.cpp
  9. 4
      src/webui/btjson.cpp

7
src/app/application.cpp

@ -142,13 +142,12 @@ 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();
program.replace("%N", torrent->name()); program.replace("%N", torrent->name());
program.replace("%F", (file_count > 1) ? "" : torrent->fileName(0));
program.replace("%L", torrent->label()); program.replace("%L", torrent->label());
program.replace("%D", Utils::Fs::toNativePath(torrent->rootPath())); program.replace("%F", Utils::Fs::toNativePath(torrent->contentPath()));
program.replace("%K", (file_count > 1) ? "multi" : "single"); program.replace("%R", Utils::Fs::toNativePath(torrent->rootPath()));
program.replace("%D", Utils::Fs::toNativePath(torrent->savePath()));
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());

8
src/core/bittorrent/session.cpp

@ -827,11 +827,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 {
@ -1736,7 +1732,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()) {

42
src/core/bittorrent/torrenthandle.cpp

@ -294,31 +294,35 @@ 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::nativeActualSavePath() const QString TorrentHandle::contentPath(bool actual) const
{ {
return Utils::String::fromStdString(m_nativeStatus.save_path); if (filesCount() == 1)
return QDir(savePath(actual)).absoluteFilePath(filePath(0));
else
return rootPath(actual);
} }
QString TorrentHandle::actualSavePath() const QString TorrentHandle::nativeActualSavePath() const
{ {
return Utils::Fs::fromNativePath(nativeActualSavePath()); return Utils::String::fromStdString(m_nativeStatus.save_path);
} }
QList<TrackerEntry> TorrentHandle::trackers() const QList<TrackerEntry> TorrentHandle::trackers() const
@ -530,7 +534,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)));
@ -541,7 +545,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);
@ -1486,7 +1490,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);
} }
@ -1781,7 +1785,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

47
src/core/bittorrent/torrenthandle.h

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

4
src/gui/options_imp.cpp

@ -184,10 +184,10 @@ options_imp::options_imp(QWidget *parent)
autoRun_param->setText(QString::fromUtf8("%1\n %2\n %3\n %4\n %5\n %6\n %7\n %8\n %9\n %10") autoRun_param->setText(QString::fromUtf8("%1\n %2\n %3\n %4\n %5\n %6\n %7\n %8\n %9\n %10")
.arg(tr("Supported parameters (case sensitive):")) .arg(tr("Supported parameters (case sensitive):"))
.arg(tr("%N: Torrent name")) .arg(tr("%N: Torrent name"))
.arg(tr("%F: Downloaded file name (single-file torrent only)"))
.arg(tr("%L: Label")) .arg(tr("%L: Label"))
.arg(tr("%F: Content path (same as root path for multifile torrent)"))
.arg(tr("%R: Root path (first torrent subdirectory path)"))
.arg(tr("%D: Save path")) .arg(tr("%D: Save path"))
.arg(tr("%K: \"single\"|\"multi\" file(s)"))
.arg(tr("%C: Number of files")) .arg(tr("%C: Number of files"))
.arg(tr("%Z: Torrent size (bytes)")) .arg(tr("%Z: Torrent size (bytes)"))
.arg(tr("%T: Current tracker")) .arg(tr("%T: Current tracker"))

14
src/gui/properties/propertieswidget.cpp

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

2
src/gui/torrentmodel.cpp

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

16
src/gui/transferlistwidget.cpp

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

4
src/webui/btjson.cpp

@ -511,7 +511,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);
@ -637,7 +637,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…
Cancel
Save