transmission/qt/WatchDir.cc

131 lines
3.2 KiB
C++
Raw Normal View History

// This file Copyright © Mnemosyne LLC.
// It may be used under GPLv2 (SPDX: GPL-2.0-only), GPLv3 (SPDX: GPL-3.0-only),
// or any future license endorsed by Mnemosyne LLC.
// License text can be found in the licenses/ folder.
#include <memory>
2009-04-09 18:55:47 +00:00
#include <QDir>
#include <QFileSystemWatcher>
2009-10-06 00:27:26 +00:00
#include <QTimer>
2009-04-09 18:55:47 +00:00
#include <libtransmission/transmission.h>
#include <libtransmission/torrent-metainfo.h>
#include "Prefs.h"
#include "TorrentModel.h"
#include "WatchDir.h"
2009-04-09 18:55:47 +00:00
/***
****
***/
WatchDir::WatchDir(TorrentModel const& model)
: model_{ model }
2009-04-09 18:55:47 +00:00
{
}
/***
****
***/
WatchDir::AddResult WatchDir::metainfoTest(QString const& filename) const
2009-04-09 18:55:47 +00:00
{
auto metainfo = tr_torrent_metainfo();
if (!metainfo.parse_torrent_file(filename.toUtf8().constData()))
{
return AddResult::Error;
}
if (model_.hasTorrent(TorrentHash{ metainfo.info_hash() }))
{
return AddResult::Duplicate;
}
return AddResult::Success;
2009-04-09 18:55:47 +00:00
}
void WatchDir::onTimeout()
2009-04-09 18:55:47 +00:00
{
auto* t = qobject_cast<QTimer*>(sender());
2013-09-14 22:45:04 +00:00
if (auto const filename = t->objectName(); metainfoTest(filename) == AddResult::Success)
{
emit torrentFileAdded(filename);
}
2013-09-14 22:45:04 +00:00
t->deleteLater();
2009-04-09 18:55:47 +00:00
}
void WatchDir::setPath(QString const& path, bool is_enabled)
2009-04-09 18:55:47 +00:00
{
// clear out any remnants of the previous watcher, if any
watch_dir_files_.clear();
watcher_.reset();
2009-04-09 18:55:47 +00:00
// maybe create a new watcher
if (is_enabled)
2013-09-14 22:45:04 +00:00
{
watcher_ = std::make_unique<QFileSystemWatcher>(QStringList{ path });
connect(watcher_.get(), &QFileSystemWatcher::directoryChanged, this, &WatchDir::watcherActivated);
// trigger the watchdir for torrent files in there already
QTimer::singleShot(0, this, SLOT(rescanAllWatchedDirectories()));
2009-04-09 18:55:47 +00:00
}
}
void WatchDir::watcherActivated(QString const& path)
2009-04-09 18:55:47 +00:00
{
// get the list of files currently in the watch directory
auto const dir = QDir{ path };
auto const files = dir.entryList(QDir::Readable | QDir::Files);
2013-09-14 22:45:04 +00:00
// try to add any new files which end in torrent
auto const torrent_suffix = QStringLiteral(".torrent");
for (auto const& name : files)
2013-09-14 22:45:04 +00:00
{
if (!name.endsWith(torrent_suffix, Qt::CaseInsensitive) || (watch_dir_files_.count(name) != 0U))
2013-09-14 22:45:04 +00:00
{
continue;
}
auto const filename = dir.absoluteFilePath(name);
switch (metainfoTest(filename))
{
case AddResult::Success:
emit torrentFileAdded(filename);
break;
case AddResult::Duplicate:
break;
case AddResult::Error:
2013-09-14 22:45:04 +00:00
{
// give the torrent a few seconds to finish downloading
auto* t = new QTimer(this);
t->setObjectName(dir.absoluteFilePath(name));
t->setSingleShot(true);
connect(t, &QTimer::timeout, this, &WatchDir::onTimeout);
t->start(5000);
2009-04-09 18:55:47 +00:00
}
}
}
// update our file list so that we can use it
// for comparison the next time around
watch_dir_files_ = { std::begin(files), std::end(files) };
2009-04-09 18:55:47 +00:00
}
void WatchDir::rescanAllWatchedDirectories()
{
if (!watcher_)
{
return;
}
for (auto const& path : watcher_->directories())
{
watcherActivated(path);
}
}