File indexing completed on 2024-04-14 03:49:47

0001 /*
0002     This file is part of the KDE Baloo project.
0003     SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-or-later
0006 */
0007 
0008 #include "unindexedfileiterator.h"
0009 #include "fileindexerconfig.h"
0010 #include "idutils.h"
0011 #include "transaction.h"
0012 #include "baloodebug.h"
0013 
0014 #include <QFileInfo>
0015 #include <QDateTime>
0016 
0017 using namespace Baloo;
0018 
0019 UnIndexedFileIterator::UnIndexedFileIterator(const FileIndexerConfig* config, Transaction* transaction, const QString& folder)
0020     : m_config(config)
0021     , m_transaction(transaction)
0022     , m_iter(config, folder, FilteredDirIterator::FilesAndDirs)
0023     , m_mTimeChanged(false)
0024     , m_cTimeChanged(false)
0025 {
0026 }
0027 
0028 UnIndexedFileIterator::~UnIndexedFileIterator()
0029 {
0030 }
0031 
0032 QString UnIndexedFileIterator::filePath() const
0033 {
0034     return m_iter.filePath();
0035 }
0036 
0037 QString UnIndexedFileIterator::mimetype() const
0038 {
0039     return m_mimetype;
0040 }
0041 
0042 bool UnIndexedFileIterator::mTimeChanged() const
0043 {
0044     return m_mTimeChanged;
0045 }
0046 
0047 bool UnIndexedFileIterator::cTimeChanged() const
0048 {
0049     return m_cTimeChanged;
0050 }
0051 
0052 QString UnIndexedFileIterator::next()
0053 {
0054     while (1) {
0055         const QString filePath = m_iter.next();
0056         m_mTimeChanged = false;
0057         m_cTimeChanged = false;
0058 
0059         if (filePath.isEmpty()) {
0060             m_mimetype.clear();
0061             return QString();
0062         }
0063 
0064         if (shouldIndex(filePath)) {
0065             return filePath;
0066         }
0067     }
0068 }
0069 
0070 bool UnIndexedFileIterator::shouldIndex(const QString& filePath)
0071 {
0072     const QFileInfo fileInfo = m_iter.fileInfo();
0073     if (!fileInfo.exists()) {
0074         return false;
0075     }
0076 
0077     quint64 fileId = filePathToId(QFile::encodeName(filePath));
0078     if (!fileId) {
0079         // stat has failed, e.g. when file has been deleted after iteration
0080         return false;
0081     }
0082 
0083     DocumentTimeDB::TimeInfo timeInfo = m_transaction->documentTimeInfo(fileId);
0084     if ((timeInfo.mTime == 0) && (timeInfo.cTime == 0) && !m_transaction->hasDocument(fileId)) {
0085         m_mTimeChanged = true;
0086         m_cTimeChanged = true;
0087     } else {
0088         if (timeInfo.mTime != fileInfo.lastModified().toSecsSinceEpoch()) {
0089             m_mTimeChanged = true;
0090         }
0091         if (timeInfo.cTime != fileInfo.metadataChangeTime().toSecsSinceEpoch()) {
0092             m_cTimeChanged = true;
0093         }
0094     }
0095 
0096     if (fileInfo.isDir()) {
0097         // The folder ctime changes when the file is created, when the folder is
0098         // renamed, or when the xattrs (tags, comments, ...) change
0099         if (m_cTimeChanged) {
0100             qCDebug(BALOO) << filePath << "ctime changed:"
0101                 << timeInfo.cTime << "->" << fileInfo.metadataChangeTime().toSecsSinceEpoch();
0102             m_mimetype = QStringLiteral("inode/directory");
0103             return true;
0104         }
0105         // The mtime changes when an object inside the folder is added/removed/renamed,
0106         // there is no need to reindex the folder when that happens
0107         return false;
0108     }
0109 
0110     if (m_mTimeChanged || m_cTimeChanged) {
0111         // This mimetype may not be completely accurate, but that's okay. This is
0112         // just the initial phase of indexing. The second phase can try to find
0113         // a more accurate mimetype.
0114         m_mimetype = m_mimeDb.mimeTypeForFile(filePath, QMimeDatabase::MatchExtension).name();
0115 
0116         qCDebug(BALOO) << filePath << "mtime/ctime changed:"
0117             << timeInfo.mTime << "/" << timeInfo.cTime << "->"
0118             << fileInfo.lastModified().toSecsSinceEpoch() << "/"
0119             << fileInfo.metadataChangeTime().toSecsSinceEpoch();
0120         return true;
0121     }
0122 
0123     return false;
0124 }