File indexing completed on 2024-04-28 04:57:36
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 <KIO/ListJob> 0024 0025 #include <QDir> 0026 0027 FileHandlerThread::FileHandlerThread(QObject *parent) 0028 : QThread(parent) 0029 , abort(false) 0030 { 0031 } 0032 0033 FileHandlerThread::~FileHandlerThread() 0034 { 0035 mutex.lock(); 0036 abort = true; 0037 mutex.unlock(); 0038 0039 wait(); 0040 } 0041 0042 void FileHandlerThread::setData(const QList<FileData> &files, 0043 const QStringList &types, 0044 bool createPartial, 0045 const KGetMetalink::Resources &tempResources, 0046 const KGetMetalink::CommonData &tempCommonData) 0047 { 0048 QMutexLocker locker(&mutex); 0049 m_files.append(files); 0050 m_types.append(types); 0051 m_createPartial.append(createPartial); 0052 m_tempResources.append(tempResources); 0053 m_tempCommonDatas.append(tempCommonData); 0054 0055 if (!isRunning()) { 0056 start(); 0057 } 0058 } 0059 0060 void FileHandlerThread::run() 0061 { 0062 mutex.lock(); 0063 bool run = m_files.count(); 0064 mutex.unlock(); 0065 0066 while (run && !abort) { 0067 mutex.lock(); 0068 QList<FileData> files = m_files.takeFirst(); 0069 QStringList types = m_types.takeFirst(); 0070 bool createPartial = m_createPartial.takeFirst(); 0071 KGetMetalink::Resources tempResources = m_tempResources.takeFirst(); 0072 KGetMetalink::CommonData commonData = m_tempCommonDatas.takeFirst(); 0073 mutex.unlock(); 0074 0075 while (files.count() && !abort) { 0076 // take the first file and try to handle it 0077 FileData data = files.takeFirst(); 0078 const QUrl url = data.url; 0079 KGetMetalink::File file = data.file; 0080 file.data = commonData; 0081 0082 foreach (const KGetMetalink::Url &metalinkUrl, tempResources.urls) { 0083 KGetMetalink::Url mirror = metalinkUrl; 0084 mirror.url.setPath(mirror.url.toString() + "/" + file.name); 0085 0086 // if the url has already been added, remove it and readd it 0087 for (int i = 0; i < file.resources.urls.count(); ++i) { 0088 if (file.resources.urls[i].url == mirror.url) { 0089 file.resources.urls.removeAt(i); 0090 break; 0091 } 0092 } 0093 file.resources.urls.append(mirror); 0094 } 0095 0096 foreach (const QString &type, types) { 0097 if (abort) { 0098 return; 0099 } 0100 0101 const QString hash = Verifier::checksum(url, type, &abort); 0102 if (!hash.isEmpty()) { 0103 file.verification.hashes[type] = hash; 0104 } 0105 } 0106 0107 if (createPartial) { 0108 foreach (const QString &type, types) { 0109 if (abort) { 0110 return; 0111 } 0112 0113 const PartialChecksums partialChecksums = Verifier::partialChecksums(url, type, 0, &abort); 0114 if (partialChecksums.isValid()) { 0115 KGetMetalink::Pieces pieces; 0116 pieces.type = type; 0117 pieces.length = partialChecksums.length(); 0118 pieces.hashes = partialChecksums.checksums(); 0119 file.verification.pieces.append(pieces); 0120 } 0121 } 0122 } 0123 if (!abort) { 0124 Q_EMIT fileResult(file); 0125 } 0126 } 0127 mutex.lock(); 0128 run = m_files.count(); 0129 mutex.unlock(); 0130 } 0131 } 0132 0133 DirectoryHandler::DirectoryHandler(QObject *parent) 0134 : QObject(parent) 0135 , m_allJobsStarted(false) 0136 { 0137 } 0138 0139 DirectoryHandler::~DirectoryHandler() 0140 { 0141 } 0142 0143 QList<FileData> DirectoryHandler::takeFiles() 0144 { 0145 QList<FileData> files = m_files; 0146 m_files.clear(); 0147 0148 return files; 0149 } 0150 0151 void DirectoryHandler::slotFiles(const QList<QUrl> &files) 0152 { 0153 if (files.isEmpty()) { 0154 return; 0155 } 0156 0157 m_allJobsStarted = false; 0158 0159 foreach (const QUrl &url, files) { 0160 QDir dir(url.path()); 0161 if (dir.exists()) { 0162 KIO::ListJob *listJob = KIO::listRecursive(url); 0163 m_jobs[listJob] = url; 0164 0165 connect(listJob, &KIO::ListJob::entries, this, &DirectoryHandler::slotDirEntries); 0166 connect(listJob, &KIO::ListJob::result, this, &DirectoryHandler::slotFinished); 0167 } else { 0168 FileData data; 0169 data.url = url; 0170 data.file.name = url.fileName(); 0171 QFile localFile(url.path()); 0172 data.file.size = localFile.size(); 0173 0174 m_files.append(data); 0175 } 0176 } 0177 0178 m_allJobsStarted = true; 0179 evaluateFileProcess(); 0180 } 0181 0182 void DirectoryHandler::slotDirEntries(KIO::Job *j, const KIO::UDSEntryList &entries) 0183 { 0184 KJob *job = j; 0185 if (!m_jobs.contains(job)) { 0186 return; 0187 } 0188 0189 const QUrl baseUrl = m_jobs[job]; 0190 const QString baseDir = baseUrl.fileName() + '/'; 0191 0192 foreach (const KIO::UDSEntry &entry, entries) { 0193 // skip all found dirs 0194 if (!entry.isDir()) { 0195 const QString name = entry.stringValue(KIO::UDSEntry::UDS_NAME); 0196 FileData data; 0197 data.url.setPath(baseUrl.toString() + "/" + name); // FIXME: Does this work? 0198 data.file.name = baseDir + name; 0199 data.file.size = entry.numberValue(KIO::UDSEntry::UDS_SIZE, -1); 0200 0201 m_files.append(data); 0202 } 0203 } 0204 } 0205 0206 void DirectoryHandler::slotFinished(KJob *job) 0207 { 0208 if (m_jobs.contains(job)) { 0209 m_jobs.remove(job); 0210 evaluateFileProcess(); 0211 } 0212 } 0213 0214 void DirectoryHandler::evaluateFileProcess() 0215 { 0216 // all jobs finished 0217 if (m_jobs.isEmpty() && m_allJobsStarted && !m_files.isEmpty()) { 0218 Q_EMIT finished(); 0219 } 0220 } 0221 0222 #include "moc_filehandler.cpp"