PageRenderTime 124ms CodeModel.GetById 50ms app.highlight 35ms RepoModel.GetById 35ms app.codeStats 0ms

/src/scanmanager.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 229 lines | 168 code | 44 blank | 17 comment | 26 complexity | f4ac66d452b2bfad2348962e50ee26f7 MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "scanmanager.h"
 20
 21#include <QtCore/QThread>
 22#include <QtCore/QCoreApplication>
 23#include <QtCore/QTimer>
 24
 25#include "musicscanner.h"
 26#include "tomahawksettings.h"
 27#include "utils/tomahawkutils.h"
 28#include "libtomahawk/sourcelist.h"
 29
 30#include "database/database.h"
 31#include "database/databasecommand_filemtimes.h"
 32#include "database/databasecommand_deletefiles.h"
 33
 34#include "utils/logger.h"
 35
 36ScanManager* ScanManager::s_instance = 0;
 37
 38
 39ScanManager*
 40ScanManager::instance()
 41{
 42    return s_instance;
 43}
 44
 45
 46ScanManager::ScanManager( QObject* parent )
 47    : QObject( parent )
 48    , m_musicScannerThreadController( 0 )
 49    , m_currScannerPaths()
 50{
 51    s_instance = this;
 52
 53    m_scanTimer = new QTimer( this );
 54    m_scanTimer->setSingleShot( false );
 55    m_scanTimer->setInterval( TomahawkSettings::instance()->scannerTime() * 1000 );
 56
 57    connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
 58    connect( m_scanTimer, SIGNAL( timeout() ), SLOT( scanTimerTimeout() ) );
 59
 60    if ( TomahawkSettings::instance()->hasScannerPaths() )
 61    {
 62        m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
 63        m_scanTimer->start();
 64        if ( TomahawkSettings::instance()->watchForChanges() )
 65            QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) );
 66    }
 67}
 68
 69
 70ScanManager::~ScanManager()
 71{
 72    qDebug() << Q_FUNC_INFO;
 73
 74    if ( !m_scanner.isNull() )
 75    {
 76        m_musicScannerThreadController->quit();
 77        m_musicScannerThreadController->wait( 60000 );
 78
 79        delete m_scanner.data();
 80        delete m_musicScannerThreadController;
 81        m_musicScannerThreadController = 0;
 82    }
 83    qDebug() << Q_FUNC_INFO << "scanner thread controller finished, exiting ScanManager";
 84}
 85
 86
 87void
 88ScanManager::onSettingsChanged()
 89{
 90    if ( !TomahawkSettings::instance()->watchForChanges() && m_scanTimer->isActive() )
 91        m_scanTimer->stop();
 92
 93    m_scanTimer->setInterval( TomahawkSettings::instance()->scannerTime() * 1000 );
 94
 95    if ( TomahawkSettings::instance()->hasScannerPaths() &&
 96        m_currScannerPaths != TomahawkSettings::instance()->scannerPaths() )
 97    {
 98        m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
 99        runScan();
100    }
101
102    if ( TomahawkSettings::instance()->watchForChanges() && !m_scanTimer->isActive() )
103        m_scanTimer->start();
104}
105
106
107void
108ScanManager::runStartupScan()
109{
110    qDebug() << Q_FUNC_INFO;
111    if ( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
112        QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) );
113    else
114        runScan();
115}
116
117
118void
119ScanManager::scanTimerTimeout()
120{
121    qDebug() << Q_FUNC_INFO;
122    if ( !TomahawkSettings::instance()->watchForChanges() ||
123         !Database::instance() ||
124         ( Database::instance() && !Database::instance()->isReady() ) )
125        return;
126    else
127        runScan();
128}
129
130
131void
132ScanManager::runScan( bool manualFull )
133{
134    qDebug() << Q_FUNC_INFO;
135    if ( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
136        return;
137
138    if ( !m_musicScannerThreadController && m_scanner.isNull() ) //still running if these are not zero
139    {
140        if ( manualFull )
141        {
142            DatabaseCommand_DeleteFiles *cmd = new DatabaseCommand_DeleteFiles( SourceList::instance()->getLocal() );
143            connect( cmd, SIGNAL( finished() ), SLOT( filesDeleted() ) );
144            Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
145            return;
146        }
147
148        DatabaseCommand_FileMtimes *cmd = new DatabaseCommand_FileMtimes( true );
149        connect( cmd, SIGNAL( done( const QMap< QString, QMap< unsigned int, unsigned int > >& ) ),
150                        SLOT( fileMtimesCheck( const QMap< QString, QMap< unsigned int, unsigned int > >& ) ) );
151
152        Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
153    }
154    else
155    {
156        qDebug() << "Could not run dir scan, old scan still running";
157        return;
158    }
159}
160
161
162void
163ScanManager::fileMtimesCheck( const QMap< QString, QMap< unsigned int, unsigned int > >& mtimes )
164{
165    if ( !mtimes.isEmpty() && TomahawkSettings::instance()->scannerPaths().isEmpty() )
166    {
167        DatabaseCommand_DeleteFiles *cmd = new DatabaseCommand_DeleteFiles( SourceList::instance()->getLocal() );
168        connect( cmd, SIGNAL( finished() ), SLOT( filesDeleted() ) );
169        Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
170        return;
171    }
172
173    runDirScan();
174}
175
176
177void
178ScanManager::filesDeleted()
179{
180    if ( !TomahawkSettings::instance()->scannerPaths().isEmpty() )
181        runDirScan();
182    else
183        scannerFinished();
184}
185
186
187void
188ScanManager::runDirScan()
189{
190    qDebug() << Q_FUNC_INFO;
191
192    QStringList paths = TomahawkSettings::instance()->scannerPaths();
193
194    if ( !m_musicScannerThreadController && m_scanner.isNull() ) //still running if these are not zero
195    {
196        m_scanTimer->stop();
197        m_musicScannerThreadController = new QThread( this );
198        m_scanner = QWeakPointer< MusicScanner >( new MusicScanner( paths ) );
199        m_scanner.data()->moveToThread( m_musicScannerThreadController );
200        connect( m_scanner.data(), SIGNAL( finished() ), SLOT( scannerFinished() ) );
201        m_musicScannerThreadController->start( QThread::IdlePriority );
202        QMetaObject::invokeMethod( m_scanner.data(), "startScan" );
203    }
204    else
205    {
206        qDebug() << "Could not run dir scan, old scan still running";
207        return;
208    }
209}
210
211
212void
213ScanManager::scannerFinished()
214{
215    tDebug() << "deleting scanner";
216    if ( !m_scanner.isNull() )
217    {
218        m_musicScannerThreadController->quit();
219        m_musicScannerThreadController->wait( 60000 );
220
221        delete m_scanner.data();
222        delete m_musicScannerThreadController;
223        m_musicScannerThreadController = 0;
224    }
225
226    m_scanTimer->start();
227    SourceList::instance()->getLocal()->scanningFinished( 0 );
228    emit finished();
229}