File indexing completed on 2025-01-05 04:37:09
0001 /* 0002 SPDX-FileCopyrightText: 2009 Joris Guisson <joris.guisson@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "datacheckerjob.h" 0008 #include "datacheckerthread.h" 0009 #include "multidatachecker.h" 0010 #include "singledatachecker.h" 0011 #include <KIO/Global> 0012 #include <klocalizedstring.h> 0013 #include <torrent/torrentcontrol.h> 0014 #include <util/functions.h> 0015 0016 namespace bt 0017 { 0018 static ResourceManager data_checker_slot(1); 0019 0020 DataCheckerJob::DataCheckerJob(bool auto_import, bt::TorrentControl *tc, bt::Uint32 from, bt::Uint32 to) 0021 : Job(true, tc) 0022 , Resource(&data_checker_slot, tc->getInfoHash().toString()) 0023 , dcheck_thread(nullptr) 0024 , killed(false) 0025 , auto_import(auto_import) 0026 , started(false) 0027 , from(from) 0028 , to(to) 0029 { 0030 if (this->from >= tc->getStats().total_chunks) 0031 this->from = 0; 0032 if (this->to >= tc->getStats().total_chunks) 0033 this->to = tc->getStats().total_chunks - 1; 0034 } 0035 0036 DataCheckerJob::~DataCheckerJob() 0037 { 0038 } 0039 0040 void DataCheckerJob::start() 0041 { 0042 registerWithTracker(); 0043 DataChecker *dc = nullptr; 0044 const TorrentStats &stats = torrent()->getStats(); 0045 if (stats.multi_file_torrent) 0046 dc = new MultiDataChecker(from, to); 0047 else 0048 dc = new SingleDataChecker(from, to); 0049 0050 connect(dc, &DataChecker::progress, this, &DataCheckerJob::progress, Qt::QueuedConnection); 0051 connect(dc, &DataChecker::status, this, &DataCheckerJob::status, Qt::QueuedConnection); 0052 0053 TorrentControl *tor = torrent(); 0054 dcheck_thread = new DataCheckerThread(dc, // 0055 tor->downloadedChunksBitSet(), 0056 stats.output_path, 0057 tor->getTorrent(), 0058 tor->getTorDir() + "dnd" + bt::DirSeparator()); 0059 0060 connect(dcheck_thread, &DataCheckerThread::finished, this, &DataCheckerJob::threadFinished, Qt::QueuedConnection); 0061 0062 torrent()->beforeDataCheck(); 0063 0064 setTotalAmount(Bytes, to - from + 1); 0065 data_checker_slot.add(this); 0066 if (!started) 0067 infoMessage(this, i18n("Waiting for other data checks to finish")); 0068 } 0069 0070 void DataCheckerJob::acquired() 0071 { 0072 started = true; 0073 description(this, i18n("Checking data")); 0074 dcheck_thread->start(QThread::IdlePriority); 0075 } 0076 0077 void DataCheckerJob::kill(bool quietly) 0078 { 0079 killed = true; 0080 if (dcheck_thread && dcheck_thread->isRunning()) { 0081 dcheck_thread->getDataChecker()->stop(); 0082 dcheck_thread->wait(); 0083 dcheck_thread->deleteLater(); 0084 dcheck_thread = nullptr; 0085 } 0086 bt::Job::kill(quietly); 0087 } 0088 0089 void DataCheckerJob::threadFinished() 0090 { 0091 if (!killed) { 0092 DataChecker *dc = dcheck_thread->getDataChecker(); 0093 torrent()->afterDataCheck(this, dc->getResult()); 0094 if (!dcheck_thread->getError().isEmpty()) { 0095 setErrorText(dcheck_thread->getError()); 0096 setError(KIO::ERR_UNKNOWN); 0097 } else 0098 setError(0); 0099 } else 0100 setError(0); 0101 0102 dcheck_thread->deleteLater(); 0103 dcheck_thread = nullptr; 0104 if (!killed) // Job::kill already emitted the result 0105 emitResult(); 0106 0107 release(); 0108 } 0109 0110 void DataCheckerJob::progress(quint32 num, quint32 total) 0111 { 0112 Q_UNUSED(total); 0113 setProcessedAmount(Bytes, num); 0114 } 0115 0116 void DataCheckerJob::status(quint32 num_failed, quint32 num_found, quint32 num_downloaded, quint32 num_not_downloaded) 0117 { 0118 QPair<QString, QString> field1 = qMakePair(QString::number(num_failed), QString::number(num_found)); 0119 QPair<QString, QString> field2 = qMakePair(QString::number(num_downloaded), QString::number(num_not_downloaded)); 0120 description(this, i18n("Checking Data"), field1, field2); 0121 } 0122 }