qBittorrent
TorrentFilesWatcher Class Referencefinal

#include <torrentfileswatcher.h>

Inheritance diagram for TorrentFilesWatcher:
Collaboration diagram for TorrentFilesWatcher:

Classes

struct  WatchedFolderOptions
 
class  Worker
 

Signals

void watchedFolderSet (const QString &path, const WatchedFolderOptions &options)
 
void watchedFolderRemoved (const QString &path)
 

Public Member Functions

QHash< QString, WatchedFolderOptionsfolders () const
 
void setWatchedFolder (const QString &path, const WatchedFolderOptions &options)
 
void removeWatchedFolder (const QString &path)
 

Static Public Member Functions

static void initInstance ()
 
static void freeInstance ()
 
static TorrentFilesWatcherinstance ()
 
static QString makeCleanPath (const QString &path)
 

Private Slots

void onMagnetFound (const BitTorrent::MagnetUri &magnetURI, const BitTorrent::AddTorrentParams &addTorrentParams)
 
void onTorrentFound (const BitTorrent::TorrentInfo &torrentInfo, const BitTorrent::AddTorrentParams &addTorrentParams)
 

Private Member Functions

 TorrentFilesWatcher (QObject *parent=nullptr)
 
 ~TorrentFilesWatcher () override
 
void load ()
 
void loadLegacy ()
 
void store () const
 
void doSetWatchedFolder (const QString &path, const WatchedFolderOptions &options)
 

Private Attributes

QHash< QString, WatchedFolderOptionsm_watchedFolders
 
QThread * m_ioThread = nullptr
 
Workerm_asyncWorker = nullptr
 

Static Private Attributes

static TorrentFilesWatcherm_instance = nullptr
 

Detailed Description

Definition at line 48 of file torrentfileswatcher.h.

Constructor & Destructor Documentation

◆ TorrentFilesWatcher()

TorrentFilesWatcher::TorrentFilesWatcher ( QObject *  parent = nullptr)
explicitprivate

Definition at line 256 of file torrentfileswatcher.cpp.

257  : QObject {parent}
258  , m_ioThread {new QThread(this)}
260 {
263 
264  m_asyncWorker->moveToThread(m_ioThread);
265  m_ioThread->start();
266 
267  load();
268 }
void magnetFound(const BitTorrent::MagnetUri &magnetURI, const BitTorrent::AddTorrentParams &addTorrentParams)
void torrentFound(const BitTorrent::TorrentInfo &torrentInfo, const BitTorrent::AddTorrentParams &addTorrentParams)
void onTorrentFound(const BitTorrent::TorrentInfo &torrentInfo, const BitTorrent::AddTorrentParams &addTorrentParams)
void onMagnetFound(const BitTorrent::MagnetUri &magnetURI, const BitTorrent::AddTorrentParams &addTorrentParams)

References load(), m_asyncWorker, m_ioThread, TorrentFilesWatcher::Worker::magnetFound(), onMagnetFound(), onTorrentFound(), and TorrentFilesWatcher::Worker::torrentFound().

Here is the call graph for this function:

◆ ~TorrentFilesWatcher()

TorrentFilesWatcher::~TorrentFilesWatcher ( )
overrideprivate

Definition at line 270 of file torrentfileswatcher.cpp.

271 {
272  m_ioThread->quit();
273  m_ioThread->wait();
274  delete m_asyncWorker;
275 }

References m_asyncWorker, and m_ioThread.

Member Function Documentation

◆ doSetWatchedFolder()

void TorrentFilesWatcher::doSetWatchedFolder ( const QString &  path,
const WatchedFolderOptions options 
)
private

Definition at line 404 of file torrentfileswatcher.cpp.

405 {
406  const QString cleanPath = makeCleanPath(path);
407  m_watchedFolders[cleanPath] = options;
408 
409  QMetaObject::invokeMethod(m_asyncWorker, [this, path, options]()
410  {
411  m_asyncWorker->setWatchedFolder(path, options);
412  });
413 
414  emit watchedFolderSet(cleanPath, options);
415 }
void setWatchedFolder(const QString &path, const TorrentFilesWatcher::WatchedFolderOptions &options)
QHash< QString, WatchedFolderOptions > m_watchedFolders
static QString makeCleanPath(const QString &path)
void watchedFolderSet(const QString &path, const WatchedFolderOptions &options)

References m_asyncWorker, m_watchedFolders, makeCleanPath(), TorrentFilesWatcher::Worker::setWatchedFolder(), and watchedFolderSet().

Referenced by load(), loadLegacy(), and setWatchedFolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ folders()

QHash< QString, TorrentFilesWatcher::WatchedFolderOptions > TorrentFilesWatcher::folders ( ) const

Definition at line 393 of file torrentfileswatcher.cpp.

394 {
395  return m_watchedFolders;
396 }

References m_watchedFolders.

Referenced by AppController::preferencesAction(), and AppController::setPreferencesAction().

Here is the caller graph for this function:

◆ freeInstance()

void TorrentFilesWatcher::freeInstance ( )
static

Definition at line 245 of file torrentfileswatcher.cpp.

246 {
247  delete m_instance;
248  m_instance = nullptr;
249 }
static TorrentFilesWatcher * m_instance

Referenced by Application::cleanup().

Here is the caller graph for this function:

◆ initInstance()

void TorrentFilesWatcher::initInstance ( )
static

Definition at line 239 of file torrentfileswatcher.cpp.

240 {
241  if (!m_instance)
243 }
TorrentFilesWatcher(QObject *parent=nullptr)

Referenced by Application::exec().

Here is the caller graph for this function:

◆ instance()

TorrentFilesWatcher * TorrentFilesWatcher::instance ( )
static

Definition at line 251 of file torrentfileswatcher.cpp.

252 {
253  return m_instance;
254 }

Referenced by OptionsDialog::OptionsDialog(), AppController::preferencesAction(), and AppController::setPreferencesAction().

Here is the caller graph for this function:

◆ load()

void TorrentFilesWatcher::load ( )
private

Definition at line 288 of file torrentfileswatcher.cpp.

289 {
290  QFile confFile {QDir(specialFolderLocation(SpecialFolder::Config)).absoluteFilePath(CONF_FILE_NAME)};
291  if (!confFile.exists())
292  {
293  loadLegacy();
294  return;
295  }
296 
297  if (!confFile.open(QFile::ReadOnly))
298  {
299  LogMsg(tr("Couldn't load Watched Folders configuration from %1. Error: %2")
300  .arg(confFile.fileName(), confFile.errorString()), Log::WARNING);
301  return;
302  }
303 
304  QJsonParseError jsonError;
305  const QJsonDocument jsonDoc = QJsonDocument::fromJson(confFile.readAll(), &jsonError);
306  if (jsonError.error != QJsonParseError::NoError)
307  {
308  LogMsg(tr("Couldn't parse Watched Folders configuration from %1. Error: %2")
309  .arg(confFile.fileName(), jsonError.errorString()), Log::WARNING);
310  return;
311  }
312 
313  if (!jsonDoc.isObject())
314  {
315  LogMsg(tr("Couldn't load Watched Folders configuration from %1. Invalid data format.")
316  .arg(confFile.fileName()), Log::WARNING);
317  return;
318  }
319 
320  const QJsonObject jsonObj = jsonDoc.object();
321  for (auto it = jsonObj.constBegin(); it != jsonObj.constEnd(); ++it)
322  {
323  const QString &watchedFolder = it.key();
324  const WatchedFolderOptions options = parseWatchedFolderOptions(it.value().toObject());
325  try
326  {
327  doSetWatchedFolder(watchedFolder, options);
328  }
329  catch (const InvalidArgument &err)
330  {
331  LogMsg(err.message(), Log::WARNING);
332  }
333  }
334 }
QString message() const noexcept
Definition: exceptions.cpp:36
void doSetWatchedFolder(const QString &path, const WatchedFolderOptions &options)
void LogMsg(const QString &message, const Log::MsgType &type)
Definition: logger.cpp:125
@ WARNING
Definition: logger.h:47
TorrentFilesWatcher::WatchedFolderOptions parseWatchedFolderOptions(const QJsonObject &jsonObj)
QString specialFolderLocation(const SpecialFolder folder)
Definition: profile.cpp:131
const QString CONF_FILE_NAME

References CONF_FILE_NAME, Config, doSetWatchedFolder(), loadLegacy(), LogMsg(), Exception::message(), anonymous_namespace{torrentfileswatcher.cpp}::parseWatchedFolderOptions(), specialFolderLocation(), and Log::WARNING.

Referenced by TorrentFilesWatcher().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadLegacy()

void TorrentFilesWatcher::loadLegacy ( )
private

Definition at line 336 of file torrentfileswatcher.cpp.

337 {
338  const auto dirs = SettingsStorage::instance()->loadValue<QVariantHash>("Preferences/Downloads/ScanDirsV2");
339 
340  for (auto i = dirs.cbegin(); i != dirs.cend(); ++i)
341  {
342  const QString watchedFolder = i.key();
344  if (i.value().type() == QVariant::Int)
345  {
346  if (i.value().toInt() == 0)
347  {
348  params.savePath = watchedFolder;
349  params.useAutoTMM = false;
350  }
351  }
352  else
353  {
354  const QString customSavePath = i.value().toString();
355  params.savePath = customSavePath;
356  params.useAutoTMM = false;
357  }
358 
359  try
360  {
361  doSetWatchedFolder(watchedFolder, {params, false});
362  }
363  catch (const InvalidArgument &err)
364  {
365  LogMsg(err.message(), Log::WARNING);
366  }
367  }
368 
369  store();
370  SettingsStorage::instance()->removeValue("Preferences/Downloads/ScanDirsV2");
371 }
T loadValue(const QString &key, const T &defaultValue={}) const
static SettingsStorage * instance()
void removeValue(const QString &key)
std::optional< bool > useAutoTMM

References doSetWatchedFolder(), SettingsStorage::instance(), SettingsStorage::loadValue(), LogMsg(), Exception::message(), SettingsStorage::removeValue(), BitTorrent::AddTorrentParams::savePath, store(), BitTorrent::AddTorrentParams::useAutoTMM, and Log::WARNING.

Referenced by load().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ makeCleanPath()

QString TorrentFilesWatcher::makeCleanPath ( const QString &  path)
static

Definition at line 277 of file torrentfileswatcher.cpp.

278 {
279  if (path.isEmpty())
280  throw InvalidArgument(tr("Watched folder path cannot be empty."));
281 
282  if (QDir::isRelativePath(path))
283  throw InvalidArgument(tr("Watched folder path cannot be relative."));
284 
285  return QDir::cleanPath(path);
286 }

Referenced by WatchedFoldersModel::addFolder(), doSetWatchedFolder(), removeWatchedFolder(), and AppController::setPreferencesAction().

Here is the caller graph for this function:

◆ onMagnetFound

void TorrentFilesWatcher::onMagnetFound ( const BitTorrent::MagnetUri magnetURI,
const BitTorrent::AddTorrentParams addTorrentParams 
)
privateslot

Definition at line 433 of file torrentfileswatcher.cpp.

435 {
436  BitTorrent::Session::instance()->addTorrent(magnetURI, addTorrentParams);
437 }
static Session * instance()
Definition: session.cpp:997
bool addTorrent(const QString &source, const AddTorrentParams &params=AddTorrentParams())
Definition: session.cpp:2007

References BitTorrent::Session::addTorrent(), and BitTorrent::Session::instance().

Referenced by TorrentFilesWatcher().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ onTorrentFound

void TorrentFilesWatcher::onTorrentFound ( const BitTorrent::TorrentInfo torrentInfo,
const BitTorrent::AddTorrentParams addTorrentParams 
)
privateslot

Definition at line 439 of file torrentfileswatcher.cpp.

441 {
442  BitTorrent::Session::instance()->addTorrent(torrentInfo, addTorrentParams);
443 }

References BitTorrent::Session::addTorrent(), and BitTorrent::Session::instance().

Referenced by TorrentFilesWatcher().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ removeWatchedFolder()

void TorrentFilesWatcher::removeWatchedFolder ( const QString &  path)

Definition at line 417 of file torrentfileswatcher.cpp.

418 {
419  const QString cleanPath = makeCleanPath(path);
420  if (m_watchedFolders.remove(cleanPath))
421  {
422  QMetaObject::invokeMethod(m_asyncWorker, [this, cleanPath]()
423  {
425  });
426 
427  emit watchedFolderRemoved(cleanPath);
428 
429  store();
430  }
431 }
void removeWatchedFolder(const QString &path)
void watchedFolderRemoved(const QString &path)

References m_asyncWorker, m_watchedFolders, makeCleanPath(), TorrentFilesWatcher::Worker::removeWatchedFolder(), store(), and watchedFolderRemoved().

Referenced by WatchedFoldersModel::apply(), and AppController::setPreferencesAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ setWatchedFolder()

void TorrentFilesWatcher::setWatchedFolder ( const QString &  path,
const WatchedFolderOptions options 
)

Definition at line 398 of file torrentfileswatcher.cpp.

399 {
400  doSetWatchedFolder(path, options);
401  store();
402 }

References doSetWatchedFolder(), and store().

Referenced by WatchedFoldersModel::apply(), and AppController::setPreferencesAction().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ store()

void TorrentFilesWatcher::store ( ) const
private

Definition at line 373 of file torrentfileswatcher.cpp.

374 {
375  QJsonObject jsonObj;
376  for (auto it = m_watchedFolders.cbegin(); it != m_watchedFolders.cend(); ++it)
377  {
378  const QString &watchedFolder = it.key();
379  const WatchedFolderOptions &options = it.value();
380  jsonObj[watchedFolder] = serializeWatchedFolderOptions(options);
381  }
382 
383  const QString path = QDir(specialFolderLocation(SpecialFolder::Config)).absoluteFilePath(CONF_FILE_NAME);
384  const QByteArray data = QJsonDocument(jsonObj).toJson();
385  const nonstd::expected<void, QString> result = Utils::IO::saveToFile(path, data);
386  if (!result)
387  {
388  LogMsg(tr("Couldn't store Watched Folders configuration to %1. Error: %2")
389  .arg(path, result.error()), Log::WARNING);
390  }
391 }
nonstd::expected< void, QString > saveToFile(const QString &path, const QByteArray &data)
Definition: io.cpp:69
QJsonObject serializeWatchedFolderOptions(const TorrentFilesWatcher::WatchedFolderOptions &options)

References CONF_FILE_NAME, Config, LogMsg(), m_watchedFolders, Utils::IO::saveToFile(), anonymous_namespace{torrentfileswatcher.cpp}::serializeWatchedFolderOptions(), specialFolderLocation(), and Log::WARNING.

Referenced by loadLegacy(), removeWatchedFolder(), and setWatchedFolder().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ watchedFolderRemoved

void TorrentFilesWatcher::watchedFolderRemoved ( const QString &  path)
signal

Referenced by removeWatchedFolder(), and WatchedFoldersModel::WatchedFoldersModel().

Here is the caller graph for this function:

◆ watchedFolderSet

void TorrentFilesWatcher::watchedFolderSet ( const QString &  path,
const WatchedFolderOptions options 
)
signal

Referenced by doSetWatchedFolder(), and WatchedFoldersModel::WatchedFoldersModel().

Here is the caller graph for this function:

Member Data Documentation

◆ m_asyncWorker

Worker* TorrentFilesWatcher::m_asyncWorker = nullptr
private

◆ m_instance

TorrentFilesWatcher * TorrentFilesWatcher::m_instance = nullptr
staticprivate

Definition at line 88 of file torrentfileswatcher.h.

◆ m_ioThread

QThread* TorrentFilesWatcher::m_ioThread = nullptr
private

Definition at line 92 of file torrentfileswatcher.h.

Referenced by TorrentFilesWatcher(), and ~TorrentFilesWatcher().

◆ m_watchedFolders


The documentation for this class was generated from the following files: