From d413bc65eff957aec03fb7fa4e12e6e8f5ca6e91 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Mon, 4 Jan 2016 16:00:50 +0300 Subject: [PATCH] Improve strip torrent root folder Fix issue when you rename the "root item" in the "Add New Torrent" dialog and uncheck "Create subfolder", it will create the subfolder with the renamed name. Fix PropertiesWidget first folder is expanded after app restart. Strip root folder if torrent was added via magnet link. Fix crash when you get name of torrent without metadata. --- src/base/bittorrent/session.cpp | 9 ++++--- src/base/bittorrent/torrenthandle.cpp | 24 +++++++++++++++---- src/base/bittorrent/torrenthandle.h | 7 ++++-- src/base/bittorrent/torrentinfo.cpp | 32 ++++++++++++------------- src/base/bittorrent/torrentinfo.h | 5 +--- src/gui/properties/propertieswidget.cpp | 6 ++--- 6 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 62e8ee5b6..ea6e8cf15 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -1652,11 +1652,9 @@ bool Session::addTorrent_impl(AddTorrentData addData, const MagnetUri &magnetUri p = magnetUri.addTorrentParams(); } else if (torrentInfo.isValid()) { - if (!addData.resumed && !addData.createSubfolder && torrentInfo.filesCount() > 1) { - libtorrent::file_storage files = torrentInfo.files(); - files.set_name(""); - torrentInfo.remapFiles(files); - } + if (!addData.resumed && !addData.hasRootFolder) + torrentInfo.stripRootFolder(); + // Metadata if (!addData.resumed && !addData.hasSeedStatus) findIncompleteFiles(torrentInfo, savePath); @@ -3651,6 +3649,7 @@ namespace torrentData.name = QString::fromStdString(fast.dict_find_string_value("qBt-name")); torrentData.hasSeedStatus = fast.dict_find_int_value("qBt-seedStatus"); torrentData.disableTempPath = fast.dict_find_int_value("qBt-tempPathDisabled"); + torrentData.hasRootFolder = fast.dict_find_int_value("qBt-hasRootFolder"); magnetUri = MagnetUri(QString::fromStdString(fast.dict_find_string_value("qBt-magnetUri"))); torrentData.addPaused = fast.dict_find_int_value("qBt-paused"); diff --git a/src/base/bittorrent/torrenthandle.cpp b/src/base/bittorrent/torrenthandle.cpp index 4a220f37f..05788a8db 100644 --- a/src/base/bittorrent/torrenthandle.cpp +++ b/src/base/bittorrent/torrenthandle.cpp @@ -89,6 +89,7 @@ AddTorrentData::AddTorrentData(const AddTorrentParams ¶ms) , sequential(params.sequential) , hasSeedStatus(params.skipChecking) // do not react on 'torrent_finished_alert' when skipping , skipChecking(params.skipChecking) + , hasRootFolder(params.createSubfolder) , addForced(params.addForced) , addPaused(params.addPaused) , filePriorities(params.filePriorities) @@ -152,7 +153,6 @@ TorrentState::operator int() const return m_value; } - , createSubfolder(in.createSubfolder) // TorrentHandle const qreal TorrentHandle::USE_GLOBAL_RATIO = -2.; @@ -200,6 +200,7 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle , m_ratioLimit(data.ratioLimit) , m_tempPathDisabled(data.disableTempPath) , m_hasMissingFiles(false) + , m_hasRootFolder(data.hasRootFolder) , m_pauseAfterRecheck(false) , m_needSaveResumeData(false) { @@ -209,8 +210,13 @@ TorrentHandle::TorrentHandle(Session *session, const libtorrent::torrent_handle updateStatus(); m_hash = InfoHash(m_nativeStatus.info_hash); - if (!data.resumed) + if (!data.resumed) { setSequentialDownload(data.sequential); + if (hasMetadata()) { + if (filesCount() == 1) + m_hasRootFolder = false; + } + } } TorrentHandle::~TorrentHandle() {} @@ -231,8 +237,8 @@ QString TorrentHandle::name() const if (name.isEmpty()) name = QString::fromStdString(m_nativeStatus.name); - if (name.isEmpty()) - name = QString::fromStdString(m_torrentInfo.origFiles().name()); + if (name.isEmpty() && hasMetadata()) + name = QString::fromStdString(m_torrentInfo.nativeInfo()->orig_files().name()); if (name.isEmpty()) name = m_hash; @@ -338,6 +344,11 @@ void TorrentHandle::setAutoTMMEnabled(bool enabled) move_impl(m_session->categorySavePath(m_category)); } +bool TorrentHandle::hasRootFolder() const +{ + return m_hasRootFolder; +} + QString TorrentHandle::nativeActualSavePath() const { return QString::fromStdString(m_nativeStatus.save_path); @@ -1493,6 +1504,7 @@ void TorrentHandle::handleSaveResumeDataAlert(libtorrent::save_resume_data_alert resumeData["qBt-seedStatus"] = m_hasSeedStatus; resumeData["qBt-tempPathDisabled"] = m_tempPathDisabled; resumeData["qBt-queuePosition"] = queuePosition(); + resumeData["qBt-hasRootFolder"] = m_hasRootFolder; m_session->handleTorrentResumeDataReady(this, resumeData); } @@ -1594,6 +1606,10 @@ void TorrentHandle::handleMetadataReceivedAlert(libt::metadata_received_alert *p updateStatus(); if (m_session->isAppendExtensionEnabled()) manageIncompleteFiles(); + if (!m_hasRootFolder) + m_torrentInfo.stripRootFolder(); + if (filesCount() == 1) + m_hasRootFolder = false; m_session->handleTorrentMetadataReceived(this); if (isPaused()) { diff --git a/src/base/bittorrent/torrenthandle.h b/src/base/bittorrent/torrenthandle.h index e43f0cf50..4d1360f61 100644 --- a/src/base/bittorrent/torrenthandle.h +++ b/src/base/bittorrent/torrenthandle.h @@ -98,7 +98,7 @@ namespace BitTorrent bool sequential; bool hasSeedStatus; bool skipChecking; - bool createSubfolder; + bool hasRootFolder; TriStateBool addForced; TriStateBool addPaused; // for new torrents @@ -236,6 +236,8 @@ namespace BitTorrent bool belongsToCategory(const QString &category) const; bool setCategory(const QString &category); + bool hasRootFolder() const; + int filesCount() const; int piecesCount() const; int piecesHave() const; @@ -396,7 +398,7 @@ namespace BitTorrent Session *const m_session; libtorrent::torrent_handle m_nativeHandle; libtorrent::torrent_status m_nativeStatus; - TorrentState m_state; + TorrentState m_state; TorrentInfo m_torrentInfo; SpeedMonitor m_speedMonitor; @@ -422,6 +424,7 @@ namespace BitTorrent qreal m_ratioLimit; bool m_tempPathDisabled; bool m_hasMissingFiles; + bool m_hasRootFolder; bool m_pauseAfterRecheck; bool m_needSaveResumeData; diff --git a/src/base/bittorrent/torrentinfo.cpp b/src/base/bittorrent/torrentinfo.cpp index db23445f7..357378bd2 100644 --- a/src/base/bittorrent/torrentinfo.cpp +++ b/src/base/bittorrent/torrentinfo.cpp @@ -276,22 +276,10 @@ TorrentInfo::PieceRange TorrentInfo::filePieces(int fileIndex) const static_cast((firstOffset + fileSize - 1) / pieceLength())); } -libtorrent::file_storage TorrentInfo::files() const -{ - if (!isValid()) return libtorrent::file_storage(); - return m_nativeInfo->files(); -} - -libtorrent::file_storage TorrentInfo::origFiles() const -{ - if (!isValid()) return libtorrent::file_storage(); - return m_nativeInfo->orig_files(); -} - void TorrentInfo::renameFile(uint index, const QString &newPath) { if (!isValid()) return; - nativeInfo()->rename_file(index, newPath.toStdString()); + nativeInfo()->rename_file(index, Utils::Fs::toNativePath(newPath).toStdString()); } int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const @@ -305,10 +293,22 @@ int BitTorrent::TorrentInfo::fileIndex(const QString& fileName) const return -1; } -void TorrentInfo::remapFiles(libtorrent::file_storage const &fileStorage) +void TorrentInfo::stripRootFolder() { - if (!isValid()) return; - m_nativeInfo->remap_files(fileStorage); + if (filesCount() <= 1) return; + + libtorrent::file_storage files = m_nativeInfo->files(); + + // Solution for case of renamed root folder + std::string testName = filePath(0).split('/').value(0).toStdString(); + if (files.name() != testName) { + files.set_name(testName); + for (int i = 0; i < files.num_files(); ++i) + files.rename_file(i, files.file_path(i)); + } + + files.set_name(""); + m_nativeInfo->remap_files(files); } TorrentInfo::NativePtr TorrentInfo::nativeInfo() const diff --git a/src/base/bittorrent/torrentinfo.h b/src/base/bittorrent/torrentinfo.h index 9c371fc4f..8f918087b 100644 --- a/src/base/bittorrent/torrentinfo.h +++ b/src/base/bittorrent/torrentinfo.h @@ -98,12 +98,9 @@ namespace BitTorrent PieceRange filePieces(const QString &file) const; PieceRange filePieces(int fileIndex) const; - libtorrent::file_storage files() const; - libtorrent::file_storage origFiles() const; - void renameFile(uint index, const QString &newPath); + void stripRootFolder(); - void remapFiles(libtorrent::file_storage const &fileStorage); NativePtr nativeInfo() const; private: diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 2a53fceb5..06fccc1b8 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -315,10 +315,8 @@ void PropertiesWidget::loadTorrentInfos(BitTorrent::TorrentHandle *const torrent label_created_by_val->setText(m_torrent->creator().toHtmlEscaped()); // List files in torrent - BitTorrent::TorrentInfo info = m_torrent->info(); - libtorrent::file_storage files = info.files(); - PropListModel->model()->setupModelData(info); - if (!(info.filesCount() > 1 && files.name().empty())) + PropListModel->model()->setupModelData(m_torrent->info()); + if ((m_torrent->filesCount() > 1) && (PropListModel->model()->rowCount() == 1)) filesList->setExpanded(PropListModel->index(0, 0), true); // Load file priorities