Warning, file /plasma/kdeplasma-addons/applets/comic/engine/comicprovider.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> 0003 * SPDX-FileCopyrightText: 2022 Alexander Lohnau <alexander.lohnau@gmx.de> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "comicprovider.h" 0009 #include "comic_debug.h" 0010 0011 #include <QTimer> 0012 #include <QUrl> 0013 0014 #include <KIO/Job> 0015 #include <KIO/StoredTransferJob> 0016 0017 class ComicProvider::Private 0018 { 0019 public: 0020 Private(ComicProvider *parent, const KPluginMetaData &data, IdentifierType suffixType) 0021 : mParent(parent) 0022 , mIsCurrent(false) 0023 , mFirstStripNumber(1) 0024 , mComicDescription(data) 0025 , mSuffixType(suffixType) 0026 { 0027 mTimer = new QTimer(parent); 0028 mTimer->setSingleShot(true); 0029 mTimer->setInterval(60000); // timeout after 1 minute 0030 connect(mTimer, &QTimer::timeout, mParent, [this]() { 0031 // operation took too long, abort it 0032 Q_EMIT mParent->error(mParent); 0033 }); 0034 } 0035 0036 void jobDone(KJob *job) 0037 { 0038 if (job->error()) { 0039 mParent->pageError(job->property("uid").toInt(), job->errorText()); 0040 } else { 0041 KIO::StoredTransferJob *storedJob = qobject_cast<KIO::StoredTransferJob *>(job); 0042 mParent->pageRetrieved(job->property("uid").toInt(), storedJob->data()); 0043 } 0044 } 0045 0046 void slotRedirection(KIO::Job *job, const QUrl &oldUrl, const QUrl &newUrl) 0047 { 0048 Q_UNUSED(oldUrl) 0049 0050 mParent->redirected(job->property("uid").toInt(), newUrl); 0051 mRedirections.remove(job); 0052 } 0053 0054 void slotRedirectionDone(KJob *job) 0055 { 0056 if (job->error()) { 0057 qCDebug(PLASMA_COMIC) << "Redirection job with id" << job->property("uid").toInt() << "finished with an error."; 0058 } 0059 0060 if (mRedirections.contains(job)) { 0061 // no redirection took place, return the original url 0062 mParent->redirected(job->property("uid").toInt(), mRedirections[job]); 0063 mRedirections.remove(job); 0064 } 0065 } 0066 0067 ComicProvider *mParent; 0068 QString mRequestedId; 0069 QString mRequestedComicName; 0070 QString mComicAuthor; 0071 QUrl mImageUrl; 0072 bool mIsCurrent; 0073 bool mIsLeftToRight; 0074 bool mIsTopToBottom; 0075 QDate mRequestedDate; 0076 QDate mFirstStripDate; 0077 int mRequestedNumber; 0078 int mFirstStripNumber; 0079 const KPluginMetaData mComicDescription; 0080 QTimer *mTimer; 0081 QHash<KJob *, QUrl> mRedirections; 0082 const IdentifierType mSuffixType; 0083 }; 0084 0085 ComicProvider::ComicProvider(QObject *parent, const KPluginMetaData &data, IdentifierType type, const QVariant &identifier) 0086 : QObject(parent) 0087 , d(new Private(this, data, type)) 0088 { 0089 if (type == IdentifierType::DateIdentifier) { 0090 d->mRequestedDate = identifier.toDate(); 0091 } else if (type == IdentifierType::NumberIdentifier) { 0092 d->mRequestedNumber = identifier.toInt(); 0093 } else if (type == IdentifierType::StringIdentifier) { 0094 d->mRequestedId = identifier.toString(); 0095 0096 int index = d->mRequestedId.indexOf(QLatin1Char(':')); 0097 d->mRequestedComicName = d->mRequestedId.mid(0, index); 0098 } else { 0099 qFatal("Invalid type passed to comic provider"); 0100 } 0101 0102 d->mTimer->start(); 0103 connect(this, &ComicProvider::finished, this, [this]() { 0104 // everything finished, stop the timeout timer 0105 d->mTimer->stop(); 0106 }); 0107 } 0108 0109 ComicProvider::~ComicProvider() 0110 { 0111 delete d; 0112 } 0113 0114 QString ComicProvider::nextIdentifier() const 0115 { 0116 if (identifierType() == IdentifierType::DateIdentifier && d->mRequestedDate != QDate::currentDate()) { 0117 return d->mRequestedDate.addDays(1).toString(Qt::ISODate); 0118 } 0119 0120 return QString(); 0121 } 0122 0123 QString ComicProvider::previousIdentifier() const 0124 { 0125 if ((identifierType() == IdentifierType::DateIdentifier) && (!firstStripDate().isValid() || d->mRequestedDate > firstStripDate())) { 0126 return d->mRequestedDate.addDays(-1).toString(Qt::ISODate); 0127 } 0128 0129 return QString(); 0130 } 0131 0132 QString ComicProvider::stripTitle() const 0133 { 0134 return QString(); 0135 } 0136 0137 QString ComicProvider::additionalText() const 0138 { 0139 return QString(); 0140 } 0141 0142 void ComicProvider::setIsCurrent(bool value) 0143 { 0144 d->mIsCurrent = value; 0145 } 0146 0147 bool ComicProvider::isCurrent() const 0148 { 0149 return d->mIsCurrent; 0150 } 0151 0152 QDate ComicProvider::requestedDate() const 0153 { 0154 return d->mRequestedDate; 0155 } 0156 0157 QDate ComicProvider::firstStripDate() const 0158 { 0159 return d->mFirstStripDate; 0160 } 0161 0162 QString ComicProvider::comicAuthor() const 0163 { 0164 return d->mComicAuthor; 0165 } 0166 0167 void ComicProvider::setComicAuthor(const QString &author) 0168 { 0169 d->mComicAuthor = author; 0170 } 0171 0172 void ComicProvider::setFirstStripDate(const QDate &date) 0173 { 0174 d->mFirstStripDate = date; 0175 } 0176 0177 int ComicProvider::firstStripNumber() const 0178 { 0179 return d->mFirstStripNumber; 0180 } 0181 0182 void ComicProvider::setFirstStripNumber(int number) 0183 { 0184 d->mFirstStripNumber = number; 0185 } 0186 0187 QString ComicProvider::firstStripIdentifier() const 0188 { 0189 if ((identifierType() == IdentifierType::DateIdentifier) && d->mFirstStripDate.isValid()) { 0190 return d->mFirstStripDate.toString(Qt::ISODate); 0191 } else if (identifierType() == IdentifierType::NumberIdentifier) { 0192 return QString::number(d->mFirstStripNumber); 0193 } 0194 0195 return QString(); 0196 } 0197 0198 int ComicProvider::requestedNumber() const 0199 { 0200 return d->mRequestedNumber; 0201 } 0202 0203 QString ComicProvider::requestedString() const 0204 { 0205 return d->mRequestedId; 0206 } 0207 0208 QString ComicProvider::requestedComicName() const 0209 { 0210 return d->mRequestedComicName; 0211 } 0212 0213 void ComicProvider::requestPage(const QUrl &url, int id, const MetaInfos &infos) 0214 { 0215 qCDebug(PLASMA_COMIC) << "Requested page" << url << "with id" << id << "and additional metadata" << infos; 0216 // each request restarts the timer 0217 d->mTimer->start(); 0218 0219 if (id == Image) { 0220 d->mImageUrl = url; 0221 } 0222 0223 KIO::StoredTransferJob *job; 0224 if (id == Image) { 0225 // use cached information for the image if available 0226 job = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo); 0227 } else { 0228 // for webpages we always reload, making sure, that changes are recognised 0229 job = KIO::storedGet(url, KIO::Reload, KIO::HideProgressInfo); 0230 } 0231 job->setProperty("uid", id); 0232 connect(job, &KJob::result, this, [this](KJob *job) { 0233 d->jobDone(job); 0234 }); 0235 0236 if (!infos.isEmpty()) { 0237 QMapIterator<QString, QString> it(infos); 0238 while (it.hasNext()) { 0239 it.next(); 0240 job->addMetaData(it.key(), it.value()); 0241 } 0242 } 0243 } 0244 0245 void ComicProvider::requestRedirectedUrl(const QUrl &url, int id, const MetaInfos &infos) 0246 { 0247 // each request restarts the timer 0248 d->mTimer->start(); 0249 0250 KIO::MimetypeJob *job = KIO::mimetype(url, KIO::HideProgressInfo); 0251 job->setProperty("uid", id); 0252 d->mRedirections[job] = url; 0253 connect(job, &KIO::MimetypeJob::redirection, this, [this](KIO::Job *job, const QUrl &newUrl) { 0254 d->slotRedirection(job, QUrl(), newUrl); 0255 }); 0256 connect(job, &KIO::MimetypeJob::permanentRedirection, this, [this](KIO::Job *job, const QUrl &oldUrl, const QUrl &newUrl) { 0257 d->slotRedirection(job, oldUrl, newUrl); 0258 }); 0259 connect(job, &KIO::MimetypeJob::result, this, [this](KJob *job) { 0260 d->slotRedirectionDone(job); 0261 }); 0262 0263 if (!infos.isEmpty()) { 0264 QMapIterator<QString, QString> it(infos); 0265 while (it.hasNext()) { 0266 it.next(); 0267 job->addMetaData(it.key(), it.value()); 0268 } 0269 } 0270 } 0271 0272 void ComicProvider::pageRetrieved(int, const QByteArray &) 0273 { 0274 } 0275 0276 void ComicProvider::pageError(int, const QString &) 0277 { 0278 } 0279 0280 void ComicProvider::redirected(int, const QUrl &) 0281 { 0282 } 0283 0284 QString ComicProvider::pluginName() const 0285 { 0286 if (!d->mComicDescription.isValid()) { 0287 return QString(); 0288 } 0289 return d->mComicDescription.pluginId(); 0290 } 0291 0292 QString ComicProvider::name() const 0293 { 0294 if (!d->mComicDescription.isValid()) { 0295 return QString(); 0296 } 0297 return d->mComicDescription.name(); 0298 } 0299 0300 KPluginMetaData ComicProvider::description() const 0301 { 0302 return d->mComicDescription; 0303 } 0304 0305 QUrl ComicProvider::shopUrl() const 0306 { 0307 return QUrl(); 0308 } 0309 0310 QUrl ComicProvider::imageUrl() const 0311 { 0312 return d->mImageUrl; 0313 } 0314 0315 bool ComicProvider::isLeftToRight() const 0316 { 0317 return true; 0318 } 0319 0320 bool ComicProvider::isTopToBottom() const 0321 { 0322 return true; 0323 } 0324 0325 #include "moc_comicprovider.cpp"