File indexing completed on 2023-12-03 08:26:47
0001 /*************************************************************************** 0002 * Copyright (C) 2009 Matthias Fuchs <mat69@gmx.net> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify * 0005 * it under the terms of the GNU General Public License as published by * 0006 * the Free Software Foundation; either version 2 of the License, or * 0007 * (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the * 0016 * Free Software Foundation, Inc., * 0017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * 0018 ***************************************************************************/ 0019 0020 #include "filehandler.h" 0021 #include "core/verifier.h" 0022 0023 #include <QDir> 0024 0025 FileHandlerThread::FileHandlerThread(QObject *parent) 0026 : QThread(parent) 0027 , abort(false) 0028 { 0029 } 0030 0031 FileHandlerThread::~FileHandlerThread() 0032 { 0033 mutex.lock(); 0034 abort = true; 0035 mutex.unlock(); 0036 0037 wait(); 0038 } 0039 0040 void FileHandlerThread::setData(const QList<FileData> &files, 0041 const QStringList &types, 0042 bool createPartial, 0043 const KGetMetalink::Resources &tempResources, 0044 const KGetMetalink::CommonData &tempCommonData) 0045 { 0046 QMutexLocker locker(&mutex); 0047 m_files.append(files); 0048 m_types.append(types); 0049 m_createPartial.append(createPartial); 0050 m_tempResources.append(tempResources); 0051 m_tempCommonDatas.append(tempCommonData); 0052 0053 if (!isRunning()) { 0054 start(); 0055 } 0056 } 0057 0058 void FileHandlerThread::run() 0059 { 0060 mutex.lock(); 0061 bool run = m_files.count(); 0062 mutex.unlock(); 0063 0064 while (run && !abort) { 0065 mutex.lock(); 0066 QList<FileData> files = m_files.takeFirst(); 0067 QStringList types = m_types.takeFirst(); 0068 bool createPartial = m_createPartial.takeFirst(); 0069 KGetMetalink::Resources tempResources = m_tempResources.takeFirst(); 0070 KGetMetalink::CommonData commonData = m_tempCommonDatas.takeFirst(); 0071 mutex.unlock(); 0072 0073 while (files.count() && !abort) { 0074 // take the first file and try to handle it 0075 FileData data = files.takeFirst(); 0076 const QUrl url = data.url; 0077 KGetMetalink::File file = data.file; 0078 file.data = commonData; 0079 0080 foreach (const KGetMetalink::Url &metalinkUrl, tempResources.urls) { 0081 KGetMetalink::Url mirror = metalinkUrl; 0082 mirror.url.setPath(mirror.url.toString() + "/" + file.name); 0083 0084 // if the url has already been added, remove it and readd it 0085 for (int i = 0; i < file.resources.urls.count(); ++i) { 0086 if (file.resources.urls[i].url == mirror.url) { 0087 file.resources.urls.removeAt(i); 0088 break; 0089 } 0090 } 0091 file.resources.urls.append(mirror); 0092 } 0093 0094 foreach (const QString &type, types) { 0095 if (abort) { 0096 return; 0097 } 0098 0099 const QString hash = Verifier::checksum(url, type, &abort); 0100 if (!hash.isEmpty()) { 0101 file.verification.hashes[type] = hash; 0102 } 0103 } 0104 0105 if (createPartial) { 0106 foreach (const QString &type, types) { 0107 if (abort) { 0108 return; 0109 } 0110 0111 const PartialChecksums partialChecksums = Verifier::partialChecksums(url, type, 0, &abort); 0112 if (partialChecksums.isValid()) { 0113 KGetMetalink::Pieces pieces; 0114 pieces.type = type; 0115 pieces.length = partialChecksums.length(); 0116 pieces.hashes = partialChecksums.checksums(); 0117 file.verification.pieces.append(pieces); 0118 } 0119 } 0120 } 0121 if (!abort) { 0122 Q_EMIT fileResult(file); 0123 } 0124 } 0125 mutex.lock(); 0126 run = m_files.count(); 0127 mutex.unlock(); 0128 } 0129 } 0130 0131 DirectoryHandler::DirectoryHandler(QObject *parent) 0132 : QObject(parent) 0133 , m_allJobsStarted(false) 0134 { 0135 } 0136 0137 DirectoryHandler::~DirectoryHandler() 0138 { 0139 } 0140 0141 QList<FileData> DirectoryHandler::takeFiles() 0142 { 0143 QList<FileData> files = m_files; 0144 m_files.clear(); 0145 0146 return files; 0147 } 0148 0149 void DirectoryHandler::slotFiles(const QList<QUrl> &files) 0150 { 0151 if (files.isEmpty()) { 0152 return; 0153 } 0154 0155 m_allJobsStarted = false; 0156 0157 foreach (const QUrl &url, files) { 0158 QDir dir(url.path()); 0159 if (dir.exists()) { 0160 KIO::ListJob *listJob = KIO::listRecursive(url); 0161 m_jobs[listJob] = url; 0162 0163 connect(listJob, &KIO::ListJob::entries, this, &DirectoryHandler::slotDirEntries); 0164 connect(listJob, &KIO::ListJob::result, this, &DirectoryHandler::slotFinished); 0165 } else { 0166 FileData data; 0167 data.url = url; 0168 data.file.name = url.fileName(); 0169 QFile localFile(url.path()); 0170 data.file.size = localFile.size(); 0171 0172 m_files.append(data); 0173 } 0174 } 0175 0176 m_allJobsStarted = true; 0177 evaluateFileProcess(); 0178 } 0179 0180 void DirectoryHandler::slotDirEntries(KIO::Job *j, const KIO::UDSEntryList &entries) 0181 { 0182 KJob *job = j; 0183 if (!m_jobs.contains(job)) { 0184 return; 0185 } 0186 0187 const QUrl baseUrl = m_jobs[job]; 0188 const QString baseDir = baseUrl.fileName() + '/'; 0189 0190 foreach (const KIO::UDSEntry &entry, entries) { 0191 // skip all found dirs 0192 if (!entry.isDir()) { 0193 const QString name = entry.stringValue(KIO::UDSEntry::UDS_NAME); 0194 FileData data; 0195 data.url.setPath(baseUrl.toString() + "/" + name); // FIXME: Does this work? 0196 data.file.name = baseDir + name; 0197 data.file.size = entry.numberValue(KIO::UDSEntry::UDS_SIZE, -1); 0198 0199 m_files.append(data); 0200 } 0201 } 0202 } 0203 0204 void DirectoryHandler::slotFinished(KJob *job) 0205 { 0206 if (m_jobs.contains(job)) { 0207 m_jobs.remove(job); 0208 evaluateFileProcess(); 0209 } 0210 } 0211 0212 void DirectoryHandler::evaluateFileProcess() 0213 { 0214 // all jobs finished 0215 if (m_jobs.isEmpty() && m_allJobsStarted && !m_files.isEmpty()) { 0216 Q_EMIT finished(); 0217 } 0218 } 0219 0220 #include "moc_filehandler.cpp"