Implement gateway for adding new torrents

PR #19355.
This commit is contained in:
Vladimir Golovnev 2023-08-14 18:17:56 +03:00 committed by GitHub
parent e4313d6651
commit dcf3e97291
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
42 changed files with 933 additions and 639 deletions

View file

@ -50,6 +50,7 @@
#include <QProcess>
#ifndef DISABLE_GUI
#include <QAbstractButton>
#include <QMenu>
#include <QMessageBox>
#include <QPixmapCache>
@ -63,6 +64,7 @@
#endif // Q_OS_MACOS
#endif
#include "base/addtorrentmanager.h"
#include "base/bittorrent/infohash.h"
#include "base/bittorrent/session.h"
#include "base/bittorrent/torrent.h"
@ -81,7 +83,6 @@
#include "base/search/searchpluginmanager.h"
#include "base/settingsstorage.h"
#include "base/torrentfileswatcher.h"
#include "base/utils/compare.h"
#include "base/utils/fs.h"
#include "base/utils/misc.h"
#include "base/utils/string.h"
@ -91,7 +92,7 @@
#include "upgrade.h"
#ifndef DISABLE_GUI
#include "gui/addnewtorrentdialog.h"
#include "gui/guiaddtorrentmanager.h"
#include "gui/desktopintegration.h"
#include "gui/mainwindow.h"
#include "gui/shutdownconfirmdialog.h"
@ -682,6 +683,21 @@ void Application::torrentFinished(const BitTorrent::Torrent *torrent)
LogMsg(tr("Torrent: %1, sending mail notification").arg(torrent->name()));
sendNotificationEmail(torrent);
}
#ifndef DISABLE_GUI
if (Preferences::instance()->isRecursiveDownloadEnabled())
{
// Check whether it contains .torrent files
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
{
if (torrentRelpath.hasExtension(u".torrent"_s))
{
askRecursiveTorrentDownloadConfirmation(torrent);
break;
}
}
}
#endif
}
void Application::allTorrentsFinished()
@ -744,18 +760,15 @@ void Application::processParams(const QBtCommandLineParameters &params)
// be shown and skipTorrentDialog is undefined. The other is when
// skipTorrentDialog is false, meaning that the application setting
// should be overridden.
const bool showDialog = !params.skipDialog.value_or(!AddNewTorrentDialog::isEnabled());
if (showDialog)
{
for (const QString &torrentSource : params.torrentSources)
AddNewTorrentDialog::show(torrentSource, params.addTorrentParams, m_window);
}
else
AddTorrentOption addTorrentOption = AddTorrentOption::Default;
if (params.skipDialog.has_value())
addTorrentOption = params.skipDialog.value() ? AddTorrentOption::SkipDialog : AddTorrentOption::ShowDialog;
for (const QString &torrentSource : params.torrentSources)
m_addTorrentManager->addTorrent(torrentSource, params.addTorrentParams, addTorrentOption);
#else
for (const QString &torrentSource : params.torrentSources)
m_addTorrentManager->addTorrent(torrentSource, params.addTorrentParams);
#endif
{
for (const QString &torrentSource : params.torrentSources)
BitTorrent::Session::instance()->addTorrent(torrentSource, params.addTorrentParams);
}
}
int Application::exec()
@ -822,11 +835,13 @@ int Application::exec()
connect(BitTorrent::Session::instance(), &BitTorrent::Session::torrentFinished, this, &Application::torrentFinished);
connect(BitTorrent::Session::instance(), &BitTorrent::Session::allTorrentsFinished, this, &Application::allTorrentsFinished, Qt::QueuedConnection);
m_addTorrentManager = new AddTorrentManagerImpl(this, BitTorrent::Session::instance(), this);
Net::GeoIPManager::initInstance();
TorrentFilesWatcher::initInstance();
new RSS::Session; // create RSS::Session singleton
new RSS::AutoDownloader; // create RSS::AutoDownloader singleton
new RSS::AutoDownloader(this); // create RSS::AutoDownloader singleton
#ifndef DISABLE_GUI
const auto *btSession = BitTorrent::Session::instance();
@ -834,30 +849,25 @@ int Application::exec()
, [this](const BitTorrent::Torrent *torrent, const QString &msg)
{
m_desktopIntegration->showNotification(tr("I/O Error", "i.e: Input/Output Error")
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
});
connect(btSession, &BitTorrent::Session::loadTorrentFailed, this
, [this](const QString &error)
{
m_desktopIntegration->showNotification(tr("Error"), tr("Failed to add torrent: %1").arg(error));
});
connect(btSession, &BitTorrent::Session::torrentAdded, this
, [this](const BitTorrent::Torrent *torrent)
{
if (isTorrentAddedNotificationsEnabled())
m_desktopIntegration->showNotification(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
, tr("An I/O error occurred for torrent '%1'.\n Reason: %2"
, "e.g: An error occurred for torrent 'xxx.avi'.\n Reason: disk is full.").arg(torrent->name(), msg));
});
connect(btSession, &BitTorrent::Session::torrentFinished, this
, [this](const BitTorrent::Torrent *torrent)
{
m_desktopIntegration->showNotification(tr("Download completed"), tr("'%1' has finished downloading.", "e.g: xxx.avi has finished downloading.").arg(torrent->name()));
});
connect(btSession, &BitTorrent::Session::downloadFromUrlFailed, this
, [this](const QString &url, const QString &reason)
connect(m_addTorrentManager, &AddTorrentManager::torrentAdded, this
, [this]([[maybe_unused]] const QString &source, const BitTorrent::Torrent *torrent)
{
m_desktopIntegration->showNotification(tr("URL download error")
, tr("Couldn't download file at URL '%1', reason: %2.").arg(url, reason));
if (isTorrentAddedNotificationsEnabled())
m_desktopIntegration->showNotification(tr("Torrent added"), tr("'%1' was added.", "e.g: xxx.avi was added.").arg(torrent->name()));
});
connect(m_addTorrentManager, &AddTorrentManager::addTorrentFailed, this
, [this](const QString &source, const QString &reason)
{
m_desktopIntegration->showNotification(tr("Add torrent failed")
, tr("Couldn't add torrent '%1', reason: %2.").arg(source, reason));
});
disconnect(m_desktopIntegration, &DesktopIntegration::activationRequested, this, &Application::createStartupProgressDialog);
@ -983,6 +993,57 @@ void Application::createStartupProgressDialog()
});
}
void Application::askRecursiveTorrentDownloadConfirmation(const BitTorrent::Torrent *torrent)
{
const auto torrentID = torrent->id();
QMessageBox *confirmBox = new QMessageBox(QMessageBox::Question, tr("Recursive download confirmation")
, tr("The torrent '%1' contains .torrent files, do you want to proceed with their downloads?").arg(torrent->name())
, (QMessageBox::Yes | QMessageBox::No | QMessageBox::NoToAll), mainWindow());
confirmBox->setAttribute(Qt::WA_DeleteOnClose);
const QAbstractButton *yesButton = confirmBox->button(QMessageBox::Yes);
QAbstractButton *neverButton = confirmBox->button(QMessageBox::NoToAll);
neverButton->setText(tr("Never"));
connect(confirmBox, &QMessageBox::buttonClicked, this
, [this, torrentID, yesButton, neverButton](const QAbstractButton *button)
{
if (button == yesButton)
{
recursiveTorrentDownload(torrentID);
}
else if (button == neverButton)
{
Preferences::instance()->setRecursiveDownloadEnabled(false);
}
});
confirmBox->open();
}
void Application::recursiveTorrentDownload(const BitTorrent::TorrentID &torrentID)
{
const BitTorrent::Torrent *torrent = BitTorrent::Session::instance()->getTorrent(torrentID);
if (!torrent)
return;
for (const Path &torrentRelpath : asConst(torrent->filePaths()))
{
if (torrentRelpath.hasExtension(u".torrent"_s))
{
const Path torrentFullpath = torrent->savePath() / torrentRelpath;
LogMsg(tr("Recursive download .torrent file within torrent. Source torrent: \"%1\". File: \"%2\"")
.arg(torrent->name(), torrentFullpath.toString()));
BitTorrent::AddTorrentParams params;
// Passing the save path along to the sub torrent file
params.savePath = torrent->savePath();
addTorrentManager()->addTorrent(torrentFullpath.data(), params, AddTorrentOption::SkipDialog);
}
}
}
#ifdef Q_OS_MACOS
bool Application::event(QEvent *ev)
{
@ -1018,7 +1079,7 @@ void Application::initializeTranslation()
const QString localeStr = pref->getLocale();
if (m_qtTranslator.load((u"qtbase_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath))
|| m_qtTranslator.load((u"qt_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
|| m_qtTranslator.load((u"qt_" + localeStr), QLibraryInfo::path(QLibraryInfo::TranslationsPath)))
{
qDebug("Qt %s locale recognized, using translation.", qUtf8Printable(localeStr));
}
@ -1262,6 +1323,7 @@ void Application::cleanup()
delete RSS::Session::instance();
TorrentFilesWatcher::freeInstance();
delete m_addTorrentManager;
BitTorrent::Session::freeInstance();
Net::GeoIPManager::freeInstance();
Net::DownloadManager::freeInstance();
@ -1296,3 +1358,8 @@ void Application::cleanup()
Utils::Misc::shutdownComputer(m_shutdownAct);
}
}
AddTorrentManagerImpl *Application::addTorrentManager() const
{
return m_addTorrentManager;
}