From 6a0a78f3f7e4a7650cd3f82106587649f679bb89 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Mon, 11 May 2020 19:08:27 +0300 Subject: [PATCH] Drop ".unwanted folder" feature --- src/base/bittorrent/session.cpp | 70 +++---------------- src/base/bittorrent/session.h | 2 +- src/base/bittorrent/torrenthandleimpl.cpp | 77 ++++++--------------- src/gui/properties/pieceavailabilitybar.cpp | 5 -- src/gui/properties/pieceavailabilitybar.h | 1 - src/gui/properties/piecesbar.cpp | 11 +-- src/gui/properties/piecesbar.h | 3 - src/gui/torrentcontentmodel.cpp | 3 - 8 files changed, 35 insertions(+), 137 deletions(-) diff --git a/src/base/bittorrent/session.cpp b/src/base/bittorrent/session.cpp index 7a42d90e6..1a8e6394d 100644 --- a/src/base/bittorrent/session.cpp +++ b/src/base/bittorrent/session.cpp @@ -420,34 +420,6 @@ namespace return {}; } #endif - - QStringList getUnwantedFilePaths(const lt::torrent_handle &torrentHandle) - { - const TorrentInfo torrentInfo {torrentHandle.torrent_file()}; - if (!torrentInfo.isValid()) - return {}; - - const QString savePath = QString::fromStdString( - torrentHandle.status(lt::torrent_handle::query_save_path).save_path); - const QDir saveDir {savePath}; - #if (LIBTORRENT_VERSION_NUM < 10200) - const std::vector fp = torrentHandle.file_priorities(); - #else - const std::vector fp = torrentHandle.get_file_priorities(); - #endif - - QStringList res; - for (int i = 0; i < static_cast(fp.size()); ++i) { - if (fp[i] == LTDownloadPriority {0}) { - const QString path = Utils::Fs::expandPathAbs( - saveDir.absoluteFilePath(torrentInfo.filePath(i))); - if (path.contains(".unwanted")) - res << path; - } - } - - return res; - } } // Session @@ -1877,6 +1849,8 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio // Remove it from session if (deleteOption == Torrent) { + m_removingTorrents[torrent->hash()] = {torrent->name(), "", deleteOption}; + const lt::torrent_handle nativeHandle {torrent->nativeHandle()}; const auto iter = std::find_if(m_moveStorageQueue.begin(), m_moveStorageQueue.end() , [&nativeHandle](const MoveStorageJob &job) @@ -1892,27 +1866,20 @@ bool Session::deleteTorrent(const InfoHash &hash, const DeleteOption deleteOptio nativeHandle.unset_flags(lt::torrent_flags::auto_managed); #endif nativeHandle.pause(); - m_removingTorrents[torrent->hash()] = {torrent->name(), {}, deleteOption}; } else { - m_removingTorrents[torrent->hash()] = {torrent->name(), getUnwantedFilePaths(nativeHandle), deleteOption}; m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile); } } else { - const QString rootPath = torrent->rootPath(true); - if (!rootPath.isEmpty()) { - // torrent with root folder - m_removingTorrents[torrent->hash()] = {torrent->name(), {rootPath}, deleteOption}; - } - else if (torrent->useTempPath()) { + QString rootPath = torrent->rootPath(true); + if (!rootPath.isEmpty() && torrent->useTempPath()) { // torrent without root folder still has it in its temporary save path - m_removingTorrents[torrent->hash()] = {torrent->name(), {torrent->actualStorageLocation()}, deleteOption}; - } - else { - m_removingTorrents[torrent->hash()] = {torrent->name(), {}, deleteOption}; + rootPath = torrent->actualStorageLocation(); } + m_removingTorrents[torrent->hash()] = {torrent->name(), rootPath, deleteOption}; + if (m_moveStorageQueue.size() > 1) { // Delete "move storage job" for the deleted torrent // (note: we shouldn't delete active job) @@ -4147,11 +4114,9 @@ void Session::handleMoveTorrentStorageJobFinished(const QString &errorMessage) else { // Last job is completed for torrent that being removing, so actually remove it const lt::torrent_handle nativeHandle {finishedJob.torrentHandle}; - RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()]; - if (removingTorrentData.deleteOption == Torrent) { - removingTorrentData.pathsToRemove = getUnwantedFilePaths(nativeHandle); + const RemovingTorrentData &removingTorrentData = m_removingTorrents[nativeHandle.info_hash()]; + if (removingTorrentData.deleteOption == Torrent) m_nativeSession->remove_torrent(nativeHandle, lt::session::delete_partfile); - } } } } @@ -4662,15 +4627,6 @@ void Session::handleTorrentRemovedAlert(const lt::torrent_removed_alert *p) const auto removingTorrentDataIter = m_removingTorrents.find(infoHash); if (removingTorrentDataIter != m_removingTorrents.end()) { if (removingTorrentDataIter->deleteOption == Torrent) { - // Remove unwanted and incomplete files - for (const QString &unwantedFile : asConst(removingTorrentDataIter->pathsToRemove)) { - qDebug("Removing unwanted file: %s", qUtf8Printable(unwantedFile)); - Utils::Fs::forceRemove(unwantedFile); - const QString parentFolder = Utils::Fs::branchPath(unwantedFile); - qDebug("Attempt to remove parent folder (if empty): %s", qUtf8Printable(parentFolder)); - QDir().rmdir(parentFolder); - } - LogMsg(tr("'%1' was removed from the transfer list.", "'xxx.avi' was removed...").arg(removingTorrentDataIter->name)); m_removingTorrents.erase(removingTorrentDataIter); } @@ -4685,9 +4641,7 @@ void Session::handleTorrentDeletedAlert(const lt::torrent_deleted_alert *p) if (removingTorrentDataIter == m_removingTorrents.end()) return; - Q_ASSERT(removingTorrentDataIter->pathsToRemove.count() <= 1); - if (!removingTorrentDataIter->pathsToRemove.isEmpty()) - Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathsToRemove.first()); + Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove); LogMsg(tr("'%1' was removed from the transfer list and hard disk.", "'xxx.avi' was removed...").arg(removingTorrentDataIter->name)); m_removingTorrents.erase(removingTorrentDataIter); } @@ -4702,9 +4656,7 @@ void Session::handleTorrentDeleteFailedAlert(const lt::torrent_delete_failed_ale // libtorrent won't delete the directory if it contains files not listed in the torrent, // so we remove the directory ourselves - Q_ASSERT(removingTorrentDataIter->pathsToRemove.count() <= 1); - if (!removingTorrentDataIter->pathsToRemove.isEmpty()) - Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathsToRemove.first()); + Utils::Fs::smartRemoveEmptyFolderTree(removingTorrentDataIter->pathToRemove); if (p->error) { LogMsg(tr("'%1' was removed from the transfer list but the files couldn't be deleted. Error: %2", "'xxx.avi' was removed...") diff --git a/src/base/bittorrent/session.h b/src/base/bittorrent/session.h index bea23f3f8..139308581 100644 --- a/src/base/bittorrent/session.h +++ b/src/base/bittorrent/session.h @@ -537,7 +537,7 @@ namespace BitTorrent struct RemovingTorrentData { QString name; - QStringList pathsToRemove; + QString pathToRemove; DeleteOption deleteOption; }; diff --git a/src/base/bittorrent/torrenthandleimpl.cpp b/src/base/bittorrent/torrenthandleimpl.cpp index f7697f247..77226e2e4 100644 --- a/src/base/bittorrent/torrenthandleimpl.cpp +++ b/src/base/bittorrent/torrenthandleimpl.cpp @@ -203,6 +203,28 @@ TorrentHandleImpl::TorrentHandleImpl(Session *session, const lt::torrent_handle if (filesCount() == 1) m_hasRootFolder = false; } + + // TODO: Remove the following upgrade code in v.4.4 + // == BEGIN UPGRADE CODE == + const QString spath = actualStorageLocation(); + for (int i = 0; i < filesCount(); ++i) { + const QString filepath = filePath(i); + // Move "unwanted" files back to their original folder + const QString parentRelPath = Utils::Fs::branchPath(filepath); + if (QDir(parentRelPath).dirName() == ".unwanted") { + const QString oldName = Utils::Fs::fileName(filepath); + const QString newRelPath = Utils::Fs::branchPath(parentRelPath); + if (newRelPath.isEmpty()) + renameFile(i, oldName); + else + renameFile(i, QDir(newRelPath).filePath(oldName)); + + // Remove .unwanted directory if empty + qDebug() << "Attempting to remove \".unwanted\" folder at " << QDir(spath + '/' + newRelPath).absoluteFilePath(".unwanted"); + QDir(spath + '/' + newRelPath).rmdir(".unwanted"); + } + } + // == END UPGRADE CODE == } TorrentHandleImpl::~TorrentHandleImpl() {} @@ -2049,61 +2071,6 @@ void TorrentHandleImpl::prioritizeFiles(const QVector &priorit qDebug() << Q_FUNC_INFO << "Changing files priorities..."; m_nativeHandle.prioritize_files(toLTDownloadPriorities(priorities)); - qDebug() << Q_FUNC_INFO << "Moving unwanted files to .unwanted folder and conversely..."; - const QString spath = savePath(true); - for (int i = 0; i < priorities.size(); ++i) { - const QString filepath = filePath(i); - // Move unwanted files to a .unwanted subfolder - if (priorities[i] == DownloadPriority::Ignored) { - const QString oldAbsPath = QDir(spath).absoluteFilePath(filepath); - const QString parentAbsPath = Utils::Fs::branchPath(oldAbsPath); - // Make sure the file does not already exists - if (QDir(parentAbsPath).dirName() != ".unwanted") { - const QString unwantedAbsPath = parentAbsPath + "/.unwanted"; - const QString newAbsPath = unwantedAbsPath + '/' + Utils::Fs::fileName(filepath); - qDebug() << "Unwanted path is" << unwantedAbsPath; - if (QFile::exists(newAbsPath)) { - qWarning() << "File" << newAbsPath << "already exists at destination."; - continue; - } - - const bool created = QDir().mkpath(unwantedAbsPath); - qDebug() << "unwanted folder was created:" << created; -#ifdef Q_OS_WIN - if (created) { - // Hide the folder on Windows - qDebug() << "Hiding folder (Windows)"; - std::wstring winPath = Utils::Fs::toNativePath(unwantedAbsPath).toStdWString(); - DWORD dwAttrs = ::GetFileAttributesW(winPath.c_str()); - bool ret = ::SetFileAttributesW(winPath.c_str(), dwAttrs | FILE_ATTRIBUTE_HIDDEN); - Q_ASSERT(ret != 0); Q_UNUSED(ret); - } -#endif - QString parentPath = Utils::Fs::branchPath(filepath); - if (!parentPath.isEmpty() && !parentPath.endsWith('/')) - parentPath += '/'; - renameFile(i, parentPath + ".unwanted/" + Utils::Fs::fileName(filepath)); - } - } - - // Move wanted files back to their original folder - if (priorities[i] > DownloadPriority::Ignored) { - const QString parentRelPath = Utils::Fs::branchPath(filepath); - if (QDir(parentRelPath).dirName() == ".unwanted") { - const QString oldName = Utils::Fs::fileName(filepath); - const QString newRelPath = Utils::Fs::branchPath(parentRelPath); - if (newRelPath.isEmpty()) - renameFile(i, oldName); - else - renameFile(i, QDir(newRelPath).filePath(oldName)); - - // Remove .unwanted directory if empty - qDebug() << "Attempting to remove .unwanted folder at " << QDir(spath + '/' + newRelPath).absoluteFilePath(".unwanted"); - QDir(spath + '/' + newRelPath).rmdir(".unwanted"); - } - } - } - // Restore first/last piece first option if necessary if (firstLastPieceFirst) setFirstLastPiecePriorityImpl(true, priorities); diff --git a/src/gui/properties/pieceavailabilitybar.cpp b/src/gui/properties/pieceavailabilitybar.cpp index dd6411348..922220661 100644 --- a/src/gui/properties/pieceavailabilitybar.cpp +++ b/src/gui/properties/pieceavailabilitybar.cpp @@ -161,8 +161,3 @@ QString PieceAvailabilityBar::simpleToolTipText() const return tr("White: Unavailable pieces") + '\n' + tr("Blue: Available pieces") + '\n'; } - -bool PieceAvailabilityBar::isFileNameCorrectionNeeded() const -{ - return true; -} diff --git a/src/gui/properties/pieceavailabilitybar.h b/src/gui/properties/pieceavailabilitybar.h index 3581b4a7e..3fe495847 100644 --- a/src/gui/properties/pieceavailabilitybar.h +++ b/src/gui/properties/pieceavailabilitybar.h @@ -48,7 +48,6 @@ public: private: bool updateImage(QImage &image) override; QString simpleToolTipText() const override; - bool isFileNameCorrectionNeeded() const override; // last used int vector, uses to better resize redraw // TODO: make a diff pieces to new pieces and update only changed pixels, speedup when update > 20x faster diff --git a/src/gui/properties/piecesbar.cpp b/src/gui/properties/piecesbar.cpp index 8ac138b67..37d455618 100644 --- a/src/gui/properties/piecesbar.cpp +++ b/src/gui/properties/piecesbar.cpp @@ -276,12 +276,8 @@ void PiecesBar::showToolTip(const QHelpEvent *e) DetailedTooltipRenderer renderer(stream, tooltipTitle); - const bool isFileNameCorrectionNeeded = this->isFileNameCorrectionNeeded(); for (int f : files) { - QString filePath {m_torrent->info().filePath(f)}; - if (isFileNameCorrectionNeeded) - filePath.replace(QLatin1String("/.unwanted"), QString()); - + const QString filePath {m_torrent->info().filePath(f)}; renderer(Utils::Misc::friendlyUnit(m_torrent->info().fileSize(f)), filePath); } stream << ""; @@ -333,8 +329,3 @@ void PiecesBar::updatePieceColors() m_pieceColors[i] = mixTwoColors(backgroundColor().rgb(), m_pieceColor.rgb(), ratio); } } - -bool PiecesBar::isFileNameCorrectionNeeded() const -{ - return false; -} diff --git a/src/gui/properties/piecesbar.h b/src/gui/properties/piecesbar.h index 0e7a335fc..7d555aeff 100644 --- a/src/gui/properties/piecesbar.h +++ b/src/gui/properties/piecesbar.h @@ -83,9 +83,6 @@ private: virtual QString simpleToolTipText() const = 0; - /// whether to perform removing of ".unwanted" directory from paths - virtual bool isFileNameCorrectionNeeded() const; - // draw new image to replace the actual image // returns true if image was successfully updated virtual bool updateImage(QImage &image) = 0; diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index 4886f826d..7462f44ab 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -458,9 +458,6 @@ void TorrentContentModel::setupModelData(const BitTorrent::TorrentInfo &info) pathFolders.removeLast(); for (const QStringRef &pathPartRef : asConst(pathFolders)) { - if (pathPartRef == QLatin1String(".unwanted")) - continue; - const QString pathPart = pathPartRef.toString(); TorrentContentModelFolder *newParent = currentParent->childFolderWithName(pathPart); if (!newParent) {