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 #ifndef GENERICSCANMANAGER_H
0024 #define GENERICSCANMANAGER_H
0025 
0026 #include "amarok_export.h"
0027 #include "collectionscanner/Directory.h"
0028 
0029 #include <QUrl>
0030 
0031 #include <QObject>
0032 #include <QSharedPointer>
0033 #include <QString>
0034 #include <QMutex>
0035 
0036 class GenericScannerJob;
0037 
0038 /**
0039  * The ScanManager manages the scanning and directory watching.
0040  *
0041  * The scan manager will check the version of the amarokcollectionscanner application,
0042  * watch directories using the KDirWatch and initiate the scanning.
0043  *
0044  * For the scanning an external process with the scanner is started and the result
0045  * is handled in a separate thread.
0046  */
0047 class AMAROK_EXPORT GenericScanManager : public QObject
0048 {
0049     Q_OBJECT
0050     public:
0051         explicit GenericScanManager( QObject* parent = nullptr );
0052         ~GenericScanManager() override;
0053 
0054         /** The scan mode.
0055             In general a full scan will consider the information read from the disk
0056             as being superior to the one in the database.
0057             The full scan will overwrite existing album covers and statistics.
0058 
0059             An update scan is a scan done automatically by Amarok. I will check
0060             for new and changed tracks and will add to information already existing
0061             in the database.
0062 
0063             A partial update scan is an update scan that does not cover all directories, so
0064             the processor cannot rely on getting all directories from the scanner
0065 
0066             TODO: the ScanResultProcessor should be smart enough to figure out if directories
0067             should be removed.
0068          */
0069         enum ScanType
0070         {
0071             /** This type of scan is done from the configuration dialog.
0072              *  It should react as if it's the first time that the collection is scanned.
0073              *  So it might e.g. throw away album covers added by the user.
0074              *
0075              *  The ScanResultProcessor may assume that directories not found
0076              *  during the scan are really gone (and not just excluded).
0077              */
0078             FullScan = 0,
0079 
0080             /** This scan type scans the whole set of directories from a collection.
0081              *  The ScanResultProcessor may assume that directories not found
0082              *  during the scan are really gone (and not just excluded).
0083              */
0084             UpdateScan = 1,
0085 
0086             /** This is an UpdateScan that does not include the whole set from a collection.
0087              *  That means that directories not reported by the ScannerJob might not
0088              *  have been excluded.
0089              */
0090             PartialUpdateScan = 2
0091         };
0092 
0093         /** Returns true if the scanner job is currently scanning */
0094         virtual bool isRunning();
0095 
0096         /** Write the batch file
0097          *  The batch file contains the known modification dates so that the scanner only
0098          *  needs to report changed directories
0099          *  @returns the path to the batch file or an empty string if nothing was written.
0100          */
0101         virtual QString getBatchFile( const QStringList& scanDirsRequested );
0102 
0103 
0104     public Q_SLOTS:
0105         /** Requests the scanner to do a full scan at the next possibility. */
0106         virtual void requestScan( QList<QUrl> directories, GenericScanManager::ScanType type = UpdateScan );
0107 
0108         /** Requests the scanner to do a full scan using the given import file.
0109          */
0110         virtual void requestImport( QIODevice *input, GenericScanManager::ScanType type = UpdateScan );
0111 
0112         /** Abort the request and all currently running scans.
0113          *  Note: this function does not block further scans, so better
0114          *  stop your directory watcher to stop scanning for a while.
0115          */
0116         virtual void abort();
0117 
0118     Q_SIGNALS:
0119         // the following signals are created by the scanner job and just
0120         // routed through
0121         // They are directly connected to the GenericScannerJob, so
0122         // beware of multi-threading
0123 
0124         void started( GenericScanManager::ScanType type );
0125 
0126         /** Gives the estimated count of directories that this scan will have.
0127             This signal might not be emitted or emitted multiple times if the
0128             count is updated.
0129         */
0130         void directoryCount( int count );
0131 
0132         /** Emitted once we get the complete data for a directory.
0133          *  @param dir The directory structure with all containing tracks.
0134          *
0135          *  The dir pointer will stay valid until after the done signal.
0136          *  Be careful, you need to have direct connections to
0137          *  ensure that you don't access the pointer before it's being freed.
0138          *  That also means that your slots are called within the job context.
0139         */
0140         void directoryScanned( QSharedPointer<CollectionScanner::Directory> dir );
0141 
0142         void succeeded();
0143         void failed( const QString& message );
0144 
0145     protected:
0146         /** Connects all the signals to m_scannerJob */
0147         void connectSignalsToJob();
0148 
0149         QWeakPointer<GenericScannerJob> m_scannerJob;
0150 
0151         /**
0152          * This mutex is protecting the variables:
0153          * m_scannerJob
0154          */
0155         QMutex m_mutex;
0156 };
0157 
0158 Q_DECLARE_METATYPE(GenericScanManager::ScanType);
0159 
0160 #endif // GENERICSCANMANAGER_H