~hendrik-grewe/transmission/private-patch

« back to all changes in this revision

Viewing changes to qt/watchdir.cc

  • Committer: charles
  • Date: 2009-04-09 17:55:47 UTC
  • Revision ID: svn-v4:f4695dd4-2c0a-0410-b89c-da849a56a58e:trunk:8188
(trunk) add the Qt beta into svn 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file Copyright (C) 2009 Charles Kerr <charles@transmissionbt.com>
 
3
 *
 
4
 * This file is licensed by the GPL version 2.  Works owned by the
 
5
 * Transmission project are granted a special exemption to clause 2(b)
 
6
 * so that the bulk of its code can remain under the MIT license.
 
7
 * This exemption does not extend to derived works not owned by
 
8
 * the Transmission project.
 
9
 *
 
10
 * $Id:$
 
11
 */
 
12
 
 
13
#include <iostream>
 
14
 
 
15
#include <QDir>
 
16
#include <QTimer>
 
17
#include <QFileSystemWatcher>
 
18
 
 
19
#include <libtransmission/transmission.h>
 
20
 
 
21
#include "prefs.h"
 
22
#include "torrent-model.h"
 
23
#include "watchdir.h"
 
24
 
 
25
/***
 
26
****
 
27
***/
 
28
 
 
29
WatchDir :: WatchDir( const TorrentModel& model ):
 
30
    myModel( model ),
 
31
    myWatcher( 0 )
 
32
{
 
33
}
 
34
 
 
35
WatchDir :: ~WatchDir( )
 
36
{
 
37
}
 
38
 
 
39
/***
 
40
****
 
41
***/
 
42
 
 
43
int
 
44
WatchDir :: metainfoTest( const QString& filename ) const
 
45
{
 
46
    int ret;
 
47
    tr_info inf;
 
48
    tr_ctor * ctor = tr_ctorNew( 0 );
 
49
 
 
50
    // parse
 
51
    tr_ctorSetMetainfoFromFile( ctor, filename.toUtf8().constData() );
 
52
    const int err = tr_torrentParse( ctor, &inf );
 
53
    if( err )
 
54
        ret = ERROR;
 
55
    else if( myModel.hasTorrent( inf.hashString ) )
 
56
        ret = DUPLICATE;
 
57
    else
 
58
        ret = OK;
 
59
 
 
60
    // cleanup
 
61
    if( !err )
 
62
        tr_metainfoFree( &inf );
 
63
    tr_ctorFree( ctor );
 
64
    return ret;
 
65
}
 
66
 
 
67
void
 
68
WatchDir :: onTimeout( )
 
69
{
 
70
    QTimer * t = qobject_cast<QTimer*>(sender());
 
71
    const QString filename = t->objectName( );
 
72
    if( metainfoTest( filename ) == OK )
 
73
        emit torrentFileAdded( filename );
 
74
    t->deleteLater( );
 
75
}
 
76
 
 
77
void
 
78
WatchDir :: setPath( const QString& path, bool isEnabled )
 
79
{
 
80
    // clear out any remnants of the previous watcher, if any
 
81
    myWatchDirFiles.clear( );
 
82
    if( myWatcher ) {
 
83
        delete myWatcher;
 
84
        myWatcher = 0;
 
85
    }
 
86
 
 
87
    // maybe create a new watcher
 
88
    if( isEnabled ) {
 
89
        myWatcher = new QFileSystemWatcher( );
 
90
        myWatcher->addPath( path );
 
91
        connect( myWatcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(watcherActivated(const QString&)));
 
92
        //std::cerr << "watching " << qPrintable(path) << " for new .torrent files" << std::endl;
 
93
        watcherActivated( path ); // trigger the watchdir for .torrent files in there already
 
94
    }
 
95
}
 
96
 
 
97
void
 
98
WatchDir :: watcherActivated( const QString& path )
 
99
{
 
100
    const QDir dir(path);
 
101
 
 
102
    // get the list of files currently in the watch directory
 
103
    QSet<QString> files;
 
104
    foreach( QString str, dir.entryList( QDir::Readable|QDir::Files ) )
 
105
        files.insert( str );
 
106
 
 
107
    // try to add any new files which end in .torrent
 
108
    const QSet<QString> newFiles( files - myWatchDirFiles );
 
109
    foreach( QString name, newFiles ) {
 
110
        if( name.endsWith( ".torrent", Qt::CaseInsensitive ) ) {
 
111
            const QString filename = dir.absoluteFilePath( name );
 
112
            switch( metainfoTest( filename ) ) {
 
113
                case OK:
 
114
                    emit torrentFileAdded( filename );
 
115
                    break;
 
116
                case DUPLICATE:
 
117
                    break;
 
118
                case ERROR: {
 
119
                    // give the .torrent a few seconds to finish downloading
 
120
                    QTimer * t = new QTimer( this );
 
121
                    t->setObjectName( dir.absoluteFilePath( name ) );
 
122
                    t->setSingleShot( true );
 
123
                    connect( t, SIGNAL(timeout()), this, SLOT(onTimeout()));
 
124
                    t->start( 5000 );
 
125
                }
 
126
            }
 
127
        }
 
128
    }
 
129
 
 
130
    // update our file list so that we can use it
 
131
    // for comparison the next time around
 
132
    myWatchDirFiles = files;
 
133
}