transmission/qt/WatchDir.cc

168 lines
3.6 KiB
C++
Raw Normal View History

2009-04-09 18:55:47 +00:00
/*
* This file Copyright (C) 2009-2015 Mnemosyne LLC
2009-04-09 18:55:47 +00:00
*
* It may be used under the GNU GPL versions 2 or 3
* or any future license endorsed by Mnemosyne LLC.
2009-04-09 18:55:47 +00:00
*
*/
#include <iostream>
#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 "Prefs.h"
#include "TorrentModel.h"
#include "WatchDir.h"
2009-04-09 18:55:47 +00:00
/***
****
***/
WatchDir::WatchDir(const TorrentModel& model) :
myModel(model),
myWatcher(0)
2009-04-09 18:55:47 +00:00
{
}
WatchDir::~WatchDir()
2009-04-09 18:55:47 +00:00
{
}
/***
****
***/
int WatchDir::metainfoTest(const QString& filename) const
2009-04-09 18:55:47 +00:00
{
int ret;
tr_info inf;
tr_ctor* ctor = tr_ctorNew(0);
// parse
tr_ctorSetMetainfoFromFile(ctor, filename.toUtf8().constData());
const int err = tr_torrentParse(ctor, &inf);
if (err)
{
ret = ERROR;
}
else if (myModel.hasTorrent(QString::fromUtf8(inf.hashString)))
{
ret = DUPLICATE;
}
else
{
ret = OK;
}
// cleanup
if (!err)
{
tr_metainfoFree(&inf);
}
tr_ctorFree(ctor);
return ret;
2009-04-09 18:55:47 +00:00
}
void WatchDir::onTimeout()
2009-04-09 18:55:47 +00:00
{
QTimer* t = qobject_cast<QTimer*>(sender());
const QString filename = t->objectName();
2013-09-14 22:45:04 +00:00
if (metainfoTest(filename) == OK)
{
emit torrentFileAdded(filename);
}
2013-09-14 22:45:04 +00:00
t->deleteLater();
2009-04-09 18:55:47 +00:00
}
void WatchDir::setPath(const QString& path, bool isEnabled)
2009-04-09 18:55:47 +00:00
{
// clear out any remnants of the previous watcher, if any
myWatchDirFiles.clear();
if (myWatcher)
2013-09-14 22:45:04 +00:00
{
delete myWatcher;
myWatcher = 0;
2009-04-09 18:55:47 +00:00
}
// maybe create a new watcher
if (isEnabled)
2013-09-14 22:45:04 +00:00
{
myWatcher = new QFileSystemWatcher();
myWatcher->addPath(path);
connect(myWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(watcherActivated(QString)));
// std::cerr << "watching " << qPrintable(path) << " for new .torrent files" << std::endl;
QTimer::singleShot(0, this, SLOT(rescanAllWatchedDirectories())); // trigger the watchdir for .torrent files in there already
2009-04-09 18:55:47 +00:00
}
}
void WatchDir::watcherActivated(const QString& path)
2009-04-09 18:55:47 +00:00
{
const QDir dir(path);
// get the list of files currently in the watch directory
QSet<QString> files;
for (const QString& str : dir.entryList(QDir::Readable | QDir::Files))
{
files.insert(str);
}
2013-09-14 22:45:04 +00:00
// try to add any new files which end in .torrent
const QSet<QString> newFiles(files - myWatchDirFiles);
const QString torrentSuffix = QString::fromUtf8(".torrent");
2013-09-14 22:45:04 +00:00
for (const QString& name : newFiles)
2013-09-14 22:45:04 +00:00
{
if (name.endsWith(torrentSuffix, Qt::CaseInsensitive))
2013-09-14 22:45:04 +00:00
{
const QString filename = dir.absoluteFilePath(name);
switch (metainfoTest(filename))
2013-09-14 22:45:04 +00:00
{
case OK:
emit torrentFileAdded(filename);
2013-09-14 22:45:04 +00:00
break;
case DUPLICATE:
2013-09-14 22:45:04 +00:00
break;
case ERROR:
2013-09-14 22:45:04 +00:00
{
// give the .torrent a few seconds to finish downloading
QTimer* t = new QTimer(this);
t->setObjectName(dir.absoluteFilePath(name));
t->setSingleShot(true);
connect(t, SIGNAL(timeout()), this, SLOT(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
myWatchDirFiles = files;
2009-04-09 18:55:47 +00:00
}
void WatchDir::rescanAllWatchedDirectories()
{
if (myWatcher == nullptr)
{
return;
}
for (const QString& path : myWatcher->directories())
{
watcherActivated(path);
}
}