2009-04-09 18:55:47 +00:00
|
|
|
/*
|
2014-01-19 01:09:44 +00:00
|
|
|
* This file Copyright (C) 2009-2014 Mnemosyne LLC
|
2009-04-09 18:55:47 +00:00
|
|
|
*
|
2014-12-21 23:49:39 +00:00
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
2014-01-19 01:09:44 +00:00
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
2009-04-09 18:55:47 +00:00
|
|
|
*
|
2009-05-31 19:33:48 +00:00
|
|
|
* $Id$
|
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 "torrent-model.h"
|
|
|
|
#include "watchdir.h"
|
|
|
|
|
|
|
|
/***
|
|
|
|
****
|
|
|
|
***/
|
|
|
|
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::WatchDir (const TorrentModel& model):
|
2013-09-14 22:45:04 +00:00
|
|
|
myModel (model),
|
|
|
|
myWatcher (0)
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::~WatchDir ()
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/***
|
|
|
|
****
|
|
|
|
***/
|
|
|
|
|
|
|
|
int
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::metainfoTest (const QString& filename) const
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
2013-09-14 22:45:04 +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
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::onTimeout ()
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
2013-09-14 22:45:04 +00:00
|
|
|
QTimer * t = qobject_cast<QTimer*>(sender());
|
|
|
|
const QString filename = t->objectName ();
|
|
|
|
|
|
|
|
if (metainfoTest (filename) == OK)
|
|
|
|
emit torrentFileAdded( filename );
|
|
|
|
|
|
|
|
t->deleteLater( );
|
2009-04-09 18:55:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::setPath (const QString& path, bool isEnabled)
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
2013-09-14 22:45:04 +00:00
|
|
|
// clear out any remnants of the previous watcher, if any
|
|
|
|
myWatchDirFiles.clear ();
|
|
|
|
if (myWatcher)
|
|
|
|
{
|
|
|
|
delete myWatcher;
|
|
|
|
myWatcher = 0;
|
2009-04-09 18:55:47 +00:00
|
|
|
}
|
|
|
|
|
2013-09-14 22:45:04 +00:00
|
|
|
// maybe create a new watcher
|
|
|
|
if (isEnabled)
|
|
|
|
{
|
|
|
|
myWatcher = new QFileSystemWatcher ();
|
|
|
|
myWatcher->addPath( path );
|
2014-12-13 09:04:10 +00:00
|
|
|
connect (myWatcher, SIGNAL(directoryChanged(QString)),
|
|
|
|
this, SLOT(watcherActivated(QString)));
|
2013-09-14 22:45:04 +00:00
|
|
|
//std::cerr << "watching " << qPrintable(path) << " for new .torrent files" << std::endl;
|
2014-12-11 22:21:24 +00:00
|
|
|
QTimer::singleShot (0, this, SLOT (rescanAllWatchedDirectories ())); // trigger the watchdir for .torrent files in there already
|
2009-04-09 18:55:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::watcherActivated (const QString& path)
|
2009-04-09 18:55:47 +00:00
|
|
|
{
|
2013-09-14 22:45:04 +00:00
|
|
|
const QDir dir(path);
|
|
|
|
|
|
|
|
// get the list of files currently in the watch directory
|
|
|
|
QSet<QString> files;
|
|
|
|
foreach (QString str, dir.entryList (QDir::Readable|QDir::Files))
|
|
|
|
files.insert (str);
|
|
|
|
|
|
|
|
// try to add any new files which end in .torrent
|
|
|
|
const QSet<QString> newFiles (files - myWatchDirFiles);
|
|
|
|
const QString torrentSuffix = QString::fromUtf8 (".torrent");
|
|
|
|
foreach (QString name, newFiles)
|
|
|
|
{
|
|
|
|
if (name.endsWith (torrentSuffix, Qt::CaseInsensitive))
|
|
|
|
{
|
|
|
|
const QString filename = dir.absoluteFilePath (name);
|
|
|
|
switch (metainfoTest (filename))
|
|
|
|
{
|
|
|
|
case OK:
|
|
|
|
emit torrentFileAdded (filename);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DUPLICATE:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ERROR:
|
|
|
|
{
|
|
|
|
// 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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-14 22:45:04 +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
|
|
|
}
|
2014-12-11 22:21:24 +00:00
|
|
|
|
|
|
|
void
|
2014-12-12 23:05:10 +00:00
|
|
|
WatchDir::rescanAllWatchedDirectories ()
|
2014-12-11 22:21:24 +00:00
|
|
|
{
|
|
|
|
if (myWatcher == nullptr)
|
|
|
|
return;
|
|
|
|
|
|
|
|
foreach (const QString& path, myWatcher->directories ())
|
|
|
|
watcherActivated (path);
|
|
|
|
}
|