/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. #include "scanmanager.h"
  19. #include <QtCore/QThread>
  20. #include <QtCore/QCoreApplication>
  21. #include <QtCore/QTimer>
  22. #include "musicscanner.h"
  23. #include "tomahawksettings.h"
  24. #include "utils/tomahawkutils.h"
  25. #include "libtomahawk/sourcelist.h"
  26. #include "database/database.h"
  27. #include "database/databasecommand_filemtimes.h"
  28. #include "database/databasecommand_deletefiles.h"
  29. #include "utils/logger.h"
  30. ScanManager* ScanManager::s_instance = 0;
  31. ScanManager*
  32. ScanManager::instance()
  33. {
  34. return s_instance;
  35. }
  36. ScanManager::ScanManager( QObject* parent )
  37. : QObject( parent )
  38. , m_musicScannerThreadController( 0 )
  39. , m_currScannerPaths()
  40. {
  41. s_instance = this;
  42. m_scanTimer = new QTimer( this );
  43. m_scanTimer->setSingleShot( false );
  44. m_scanTimer->setInterval( TomahawkSettings::instance()->scannerTime() * 1000 );
  45. connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( onSettingsChanged() ) );
  46. connect( m_scanTimer, SIGNAL( timeout() ), SLOT( scanTimerTimeout() ) );
  47. if ( TomahawkSettings::instance()->hasScannerPaths() )
  48. {
  49. m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
  50. m_scanTimer->start();
  51. if ( TomahawkSettings::instance()->watchForChanges() )
  52. QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) );
  53. }
  54. }
  55. ScanManager::~ScanManager()
  56. {
  57. qDebug() << Q_FUNC_INFO;
  58. if ( !m_scanner.isNull() )
  59. {
  60. m_musicScannerThreadController->quit();
  61. m_musicScannerThreadController->wait( 60000 );
  62. delete m_scanner.data();
  63. delete m_musicScannerThreadController;
  64. m_musicScannerThreadController = 0;
  65. }
  66. qDebug() << Q_FUNC_INFO << "scanner thread controller finished, exiting ScanManager";
  67. }
  68. void
  69. ScanManager::onSettingsChanged()
  70. {
  71. if ( !TomahawkSettings::instance()->watchForChanges() && m_scanTimer->isActive() )
  72. m_scanTimer->stop();
  73. m_scanTimer->setInterval( TomahawkSettings::instance()->scannerTime() * 1000 );
  74. if ( TomahawkSettings::instance()->hasScannerPaths() &&
  75. m_currScannerPaths != TomahawkSettings::instance()->scannerPaths() )
  76. {
  77. m_currScannerPaths = TomahawkSettings::instance()->scannerPaths();
  78. runScan();
  79. }
  80. if ( TomahawkSettings::instance()->watchForChanges() && !m_scanTimer->isActive() )
  81. m_scanTimer->start();
  82. }
  83. void
  84. ScanManager::runStartupScan()
  85. {
  86. qDebug() << Q_FUNC_INFO;
  87. if ( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
  88. QTimer::singleShot( 1000, this, SLOT( runStartupScan() ) );
  89. else
  90. runScan();
  91. }
  92. void
  93. ScanManager::scanTimerTimeout()
  94. {
  95. qDebug() << Q_FUNC_INFO;
  96. if ( !TomahawkSettings::instance()->watchForChanges() ||
  97. !Database::instance() ||
  98. ( Database::instance() && !Database::instance()->isReady() ) )
  99. return;
  100. else
  101. runScan();
  102. }
  103. void
  104. ScanManager::runScan( bool manualFull )
  105. {
  106. qDebug() << Q_FUNC_INFO;
  107. if ( !Database::instance() || ( Database::instance() && !Database::instance()->isReady() ) )
  108. return;
  109. if ( !m_musicScannerThreadController && m_scanner.isNull() ) //still running if these are not zero
  110. {
  111. if ( manualFull )
  112. {
  113. DatabaseCommand_DeleteFiles *cmd = new DatabaseCommand_DeleteFiles( SourceList::instance()->getLocal() );
  114. connect( cmd, SIGNAL( finished() ), SLOT( filesDeleted() ) );
  115. Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
  116. return;
  117. }
  118. DatabaseCommand_FileMtimes *cmd = new DatabaseCommand_FileMtimes( true );
  119. connect( cmd, SIGNAL( done( const QMap< QString, QMap< unsigned int, unsigned int > >& ) ),
  120. SLOT( fileMtimesCheck( const QMap< QString, QMap< unsigned int, unsigned int > >& ) ) );
  121. Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
  122. }
  123. else
  124. {
  125. qDebug() << "Could not run dir scan, old scan still running";
  126. return;
  127. }
  128. }
  129. void
  130. ScanManager::fileMtimesCheck( const QMap< QString, QMap< unsigned int, unsigned int > >& mtimes )
  131. {
  132. if ( !mtimes.isEmpty() && TomahawkSettings::instance()->scannerPaths().isEmpty() )
  133. {
  134. DatabaseCommand_DeleteFiles *cmd = new DatabaseCommand_DeleteFiles( SourceList::instance()->getLocal() );
  135. connect( cmd, SIGNAL( finished() ), SLOT( filesDeleted() ) );
  136. Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
  137. return;
  138. }
  139. runDirScan();
  140. }
  141. void
  142. ScanManager::filesDeleted()
  143. {
  144. if ( !TomahawkSettings::instance()->scannerPaths().isEmpty() )
  145. runDirScan();
  146. else
  147. scannerFinished();
  148. }
  149. void
  150. ScanManager::runDirScan()
  151. {
  152. qDebug() << Q_FUNC_INFO;
  153. QStringList paths = TomahawkSettings::instance()->scannerPaths();
  154. if ( !m_musicScannerThreadController && m_scanner.isNull() ) //still running if these are not zero
  155. {
  156. m_scanTimer->stop();
  157. m_musicScannerThreadController = new QThread( this );
  158. m_scanner = QWeakPointer< MusicScanner >( new MusicScanner( paths ) );
  159. m_scanner.data()->moveToThread( m_musicScannerThreadController );
  160. connect( m_scanner.data(), SIGNAL( finished() ), SLOT( scannerFinished() ) );
  161. m_musicScannerThreadController->start( QThread::IdlePriority );
  162. QMetaObject::invokeMethod( m_scanner.data(), "startScan" );
  163. }
  164. else
  165. {
  166. qDebug() << "Could not run dir scan, old scan still running";
  167. return;
  168. }
  169. }
  170. void
  171. ScanManager::scannerFinished()
  172. {
  173. tDebug() << "deleting scanner";
  174. if ( !m_scanner.isNull() )
  175. {
  176. m_musicScannerThreadController->quit();
  177. m_musicScannerThreadController->wait( 60000 );
  178. delete m_scanner.data();
  179. delete m_musicScannerThreadController;
  180. m_musicScannerThreadController = 0;
  181. }
  182. m_scanTimer->start();
  183. SourceList::instance()->getLocal()->scanningFinished( 0 );
  184. emit finished();
  185. }