File indexing completed on 2024-04-28 04:57:30
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 "checksumsearchtransferdatasource.h" 0021 #include "checksumsearch.h" 0022 #include "checksumsearchsettings.h" 0023 #include "kget_debug.h" 0024 0025 #include <QFile> 0026 0027 #include <KIO/DeleteJob> 0028 #include <KIO/FileCopyJob> 0029 #include <KIO/ListJob> 0030 0031 #include <QStandardPaths> 0032 0033 ChecksumSearchController ChecksumSearchTransferDataSource::s_controller; 0034 0035 ChecksumSearchController::ChecksumSearchController(QObject *parent) 0036 : QObject(parent) 0037 { 0038 } 0039 0040 ChecksumSearchController::~ChecksumSearchController() 0041 { 0042 } 0043 0044 void ChecksumSearchController::registerSearch(ChecksumSearchTransferDataSource *search, const QUrl &baseUrl) 0045 { 0046 if (m_finished.contains(baseUrl)) { 0047 qCDebug(KGET_DEBUG) << "Already downloaded" << baseUrl; 0048 const QUrl urlToFile = m_finished[baseUrl]; 0049 if (!urlToFile.isEmpty()) { 0050 search->gotBaseUrl(m_finished[baseUrl]); 0051 } 0052 } else { 0053 const bool alreadySearchedFor = m_searches.contains(baseUrl); 0054 if (!m_searches.contains(baseUrl, search)) { 0055 m_searches.insert(baseUrl, search); 0056 0057 if (alreadySearchedFor) { 0058 qCDebug(KGET_DEBUG) << "Search already started for" << baseUrl; 0059 return; 0060 } 0061 qCDebug(KGET_DEBUG) << "Creating download for" << baseUrl; 0062 static int files = 0; 0063 0064 const QUrl dest = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/checksumsearch/") 0065 + QString::number(files++)); 0066 if (QFile::exists(dest.toLocalFile())) { 0067 KIO::Job *del = KIO::del(dest, KIO::HideProgressInfo); 0068 if (!del->exec()) { 0069 qCDebug(KGET_DEBUG) << "Could not delete " << dest.path(); 0070 } 0071 } 0072 0073 if (baseUrl.scheme() != "ftp" && baseUrl.scheme() != "sftp") { 0074 qCDebug(KGET_DEBUG) << "Downloading" << baseUrl; 0075 KIO::FileCopyJob *job = KIO::file_copy(baseUrl, dest, -1, KIO::HideProgressInfo); 0076 job->addMetaData("errorPage", "false"); 0077 connect(job, &KJob::result, this, &ChecksumSearchController::slotResult); 0078 m_jobs[job] = qMakePair(baseUrl, dest); 0079 } else { 0080 qCDebug(KGET_DEBUG) << "ftp, doing a listjob"; 0081 KIO::ListJob *job = KIO::listDir(baseUrl, KIO::HideProgressInfo); 0082 connect(job, &KIO::ListJob::entries, this, &ChecksumSearchController::slotEntries); 0083 connect(job, &KJob::result, this, &ChecksumSearchController::slotResult); 0084 m_jobs[job] = qMakePair(baseUrl, dest); 0085 } 0086 } 0087 } 0088 } 0089 0090 void ChecksumSearchController::unregisterSearch(ChecksumSearchTransferDataSource *search, const QUrl &baseUrl) 0091 { 0092 if (baseUrl.isEmpty()) { 0093 const QList<QUrl> keys = m_searches.keys(search); 0094 foreach (const QUrl &key, keys) { 0095 m_searches.remove(key, search); 0096 } 0097 } else { 0098 m_searches.remove(baseUrl, search); 0099 } 0100 } 0101 0102 void ChecksumSearchController::slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries) 0103 { 0104 qCDebug(KGET_DEBUG); 0105 0106 if (!m_jobs.contains(job)) { 0107 return; 0108 } 0109 0110 const QUrl baseUrl = m_jobs[job].first; 0111 const QUrl urlToFile = m_jobs[job].second; 0112 QFile file(urlToFile.toLocalFile()); 0113 if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { 0114 qCDebug(KGET_DEBUG) << "Could not open file" << urlToFile; 0115 } 0116 0117 QTextStream out(&file); 0118 foreach (const KIO::UDSEntry &entry, entries) { 0119 if (!entry.isDir()) { 0120 out << entry.stringValue(KIO::UDSEntry::UDS_NAME) << '\n'; 0121 } 0122 } 0123 file.close(); 0124 } 0125 0126 void ChecksumSearchController::slotResult(KJob *job) 0127 { 0128 qCDebug(KGET_DEBUG); 0129 0130 if (!m_jobs.contains(job)) { 0131 return; 0132 } 0133 0134 const QUrl baseUrl = m_jobs[job].first; 0135 const QUrl urlToFile = m_jobs[job].second; 0136 m_jobs.remove(job); 0137 if (job->error()) { 0138 qCDebug(KGET_DEBUG) << "Error while getting baseurl:" << baseUrl << job->error() << job->errorString(); 0139 m_finished[baseUrl] = QUrl(); 0140 return; 0141 } 0142 0143 m_finished[baseUrl] = urlToFile; 0144 0145 const QList<ChecksumSearchTransferDataSource *> searches = m_searches.values(baseUrl); 0146 m_searches.remove(baseUrl); 0147 foreach (ChecksumSearchTransferDataSource *search, searches) { 0148 search->gotBaseUrl(urlToFile); 0149 } 0150 } 0151 0152 ChecksumSearchTransferDataSource::ChecksumSearchTransferDataSource(const QUrl &srcUrl, QObject *parent) 0153 : TransferDataSource(srcUrl, parent) 0154 { 0155 } 0156 0157 ChecksumSearchTransferDataSource::~ChecksumSearchTransferDataSource() 0158 { 0159 s_controller.unregisterSearch(this, m_sourceUrl.adjusted(QUrl::RemoveFilename)); 0160 } 0161 0162 void ChecksumSearchTransferDataSource::start() 0163 { 0164 qCDebug(KGET_DEBUG); 0165 0166 const QUrl baseUrl = m_sourceUrl.adjusted(QUrl::RemoveFilename); 0167 s_controller.registerSearch(this, baseUrl); 0168 } 0169 0170 void ChecksumSearchTransferDataSource::gotBaseUrl(const QUrl &urlToFile) 0171 { 0172 QFile file(urlToFile.toLocalFile()); 0173 if (!file.open(QIODevice::ReadOnly)) { 0174 qCDebug(KGET_DEBUG) << "Could not open file" << urlToFile; 0175 return; 0176 } 0177 0178 const QByteArray data = file.readAll(); 0179 file.close(); 0180 0181 QStringList changes = ChecksumSearchSettings::self()->searchStrings(); 0182 QList<int> modes = ChecksumSearchSettings::self()->urlChangeModeList(); 0183 QStringList types = ChecksumSearchSettings::self()->checksumTypeList(); 0184 0185 QList<QUrl> urls; 0186 0187 for (int i = 0, k = 0; i < changes.size(); ++i) { 0188 const auto mode = static_cast<ChecksumSearch::UrlChangeMode>(modes.at(i)); 0189 const QUrl source = ChecksumSearch::createUrl(m_sourceUrl, changes.at(i), mode); 0190 if (data.indexOf(source.fileName().toLatin1()) != -1) { 0191 urls.append(source); 0192 ++k; 0193 } else { 0194 types.removeAt(k); 0195 } 0196 } 0197 0198 qCDebug(KGET_DEBUG) << "Creating Checksumsearch for" << urls.count() << "urls."; 0199 0200 if (urls.count() && types.count()) { 0201 auto *search = new ChecksumSearch(urls, m_sourceUrl.fileName(), types); 0202 0203 connect(search, &ChecksumSearch::data, this, [this](QString type, QString checksum) { 0204 this->data(type, checksum); 0205 }); 0206 } 0207 } 0208 0209 void ChecksumSearchTransferDataSource::stop() 0210 { 0211 qCDebug(KGET_DEBUG); 0212 } 0213 0214 void ChecksumSearchTransferDataSource::addSegments(const QPair<KIO::fileoffset_t, KIO::fileoffset_t> &segmentSize, const QPair<int, int> &segmentRange) 0215 { 0216 Q_UNUSED(segmentSize) 0217 Q_UNUSED(segmentRange) 0218 qCDebug(KGET_DEBUG); 0219 } 0220 0221 #include "moc_checksumsearchtransferdatasource.cpp"