File indexing completed on 2024-05-05 04:48:50
0001 /**************************************************************************************** 0002 * Copyright (c) 2003-2008 Mark Kretschmann <kretschmann@kde.org> * 0003 * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0004 * Copyright (c) 2007 Casey Link <unnamedrambler@gmail.com> * 0005 * Copyright (c) 2008-2009 Jeff Mitchell <mitchell@kde.org> * 0006 * Copyright (c) 2010-2011 Ralf Engels <ralf-engels@gmx.de> * 0007 * Copyright (c) 2011 Bart Cerneels <bart.cerneels@kde.org> * 0008 * Copyright (c) 2013 Ralf Engels <ralf-engels@gmx.de> * 0009 * * 0010 * This program is free software; you can redistribute it and/or modify it under * 0011 * the terms of the GNU General Public License as published by the Free Software * 0012 * Foundation; either version 2 of the License, or (at your option) any later * 0013 * version. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0016 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0017 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0018 * * 0019 * You should have received a copy of the GNU General Public License along with * 0020 * this program. If not, see <http://www.gnu.org/licenses/>. * 0021 ****************************************************************************************/ 0022 0023 #define DEBUG_PREFIX "GenericScanManager" 0024 0025 #include "GenericScanManager.h" 0026 0027 #include "core/support/Debug.h" 0028 #include "scanner/GenericScannerJob.h" 0029 0030 #include <ThreadWeaver/Queue> 0031 0032 #include <QFileInfo> 0033 #include <QSharedPointer> 0034 0035 GenericScanManager::GenericScanManager( QObject *parent ) 0036 : QObject( parent ) 0037 { 0038 qRegisterMetaType<GenericScanManager::ScanType>( "GenericScanManager::ScanType" ); 0039 qRegisterMetaType<QSharedPointer<CollectionScanner::Directory> >( "QSharedPointer<CollectionScanner::Directory>" ); 0040 } 0041 0042 GenericScanManager::~GenericScanManager() 0043 { 0044 abort(); 0045 } 0046 0047 bool 0048 GenericScanManager::isRunning() 0049 { 0050 QMutexLocker locker( &m_mutex ); 0051 return m_scannerJob; 0052 } 0053 0054 QString 0055 GenericScanManager::getBatchFile( const QStringList& scanDirsRequested ) 0056 { 0057 Q_UNUSED( scanDirsRequested ); 0058 return QString(); 0059 } 0060 0061 void 0062 GenericScanManager::requestScan( QList<QUrl> directories, ScanType type ) 0063 { 0064 DEBUG_BLOCK; 0065 0066 QMutexLocker locker( &m_mutex ); 0067 if( m_scannerJob ) 0068 { 0069 //TODO: add to queue requests 0070 error() << "Scanner already running, not starting another instance."; 0071 return; 0072 } 0073 0074 QSet<QString> scanDirsSet; 0075 foreach( const QUrl &url, directories ) 0076 { 0077 if( !url.isLocalFile() ) 0078 { 0079 warning() << "scan of non-local directory" << url << "requested, skipping it."; 0080 continue; 0081 } 0082 0083 QString path = url.adjusted(QUrl::StripTrailingSlash).path(); 0084 if( !QFileInfo( path ).isDir() ) 0085 { 0086 warning() << "scan of a non-directory" << path << "requested, skipping it."; 0087 continue; 0088 } 0089 //TODO: most local path 0090 0091 scanDirsSet << path; 0092 } 0093 0094 // we cannot skip the scan even for empty scanDirsSet and non-partial scan, bug 316216 0095 if( scanDirsSet.isEmpty() && type == PartialUpdateScan ) 0096 return; // nothing to do 0097 0098 auto scannerJob = QSharedPointer<GenericScannerJob>( new GenericScannerJob( this, scanDirsSet.values(), type ) ); 0099 m_scannerJob = scannerJob.toWeakRef(); 0100 connectSignalsToJob(); 0101 ThreadWeaver::Queue::instance()->enqueue( scannerJob ); 0102 } 0103 0104 void 0105 GenericScanManager::requestImport( QIODevice *input, ScanType type ) 0106 { 0107 QMutexLocker locker( &m_mutex ); 0108 if( m_scannerJob ) 0109 { 0110 //TODO: add to queue requests 0111 error() << "Scanner already running"; 0112 return; 0113 } 0114 0115 auto scannerJob = QSharedPointer<GenericScannerJob>( new GenericScannerJob( this, input, type ) ); 0116 m_scannerJob = scannerJob.toWeakRef(); 0117 connectSignalsToJob(); 0118 ThreadWeaver::Queue::instance()->enqueue( scannerJob ); 0119 } 0120 0121 void 0122 GenericScanManager::abort() 0123 { 0124 QMutexLocker locker( &m_mutex ); 0125 0126 auto scannerJob = m_scannerJob.toStrongRef(); 0127 if( scannerJob ) 0128 scannerJob->abort(); 0129 } 0130 0131 void 0132 GenericScanManager::connectSignalsToJob() 0133 { 0134 auto scannerJobPointer = m_scannerJob.toStrongRef(); 0135 if( scannerJobPointer ) { 0136 auto scannerJob = scannerJobPointer.data(); 0137 // we used to have direct connections here, but that caused too much work being done 0138 // in the non-main thread, even in code that wasn't thread-safe, which lead to 0139 // crashes (bug 319835) and other potential data races 0140 connect( scannerJob, QOverload<ScanType>::of(&GenericScannerJob::started), 0141 this, &GenericScanManager::started ); 0142 connect( scannerJob, &GenericScannerJob::directoryCount, 0143 this, &GenericScanManager::directoryCount); 0144 connect( scannerJob, &GenericScannerJob::directoryScanned, 0145 this, &GenericScanManager::directoryScanned ); 0146 connect( scannerJob, &GenericScannerJob::succeeded, 0147 this, &GenericScanManager::succeeded ); 0148 connect( scannerJob, QOverload<QString>::of(&GenericScannerJob::failed), 0149 this, &GenericScanManager::failed ); 0150 } 0151 }