void Image::loadDetails(bool rateLimit) { if (m_loadingDetails) return; if (m_loadedDetails || m_pageUrl.isEmpty()) { emit finishedLoadingTags(); return; } m_parentSite->getAsync(rateLimit ? Site::QueryType::Retry : Site::QueryType::Details, m_pageUrl, [this](QNetworkReply *reply) { if (m_loadDetails != nullptr) m_loadDetails->deleteLater(); m_loadDetails = reply; m_loadDetails->setParent(this); m_loadingDetails = true; connect(m_loadDetails, &QNetworkReply::finished, this, &Image::parseDetails); }); }
void Page::parseTags() { // Check redirection QUrl redir = m_replyTags->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (!redir.isEmpty()) { m_urlRegex = m_site->fixUrl(redir.toString(), m_urlRegex); loadTags(); return; } QString source = QString::fromUtf8(m_replyTags->readAll()); m_tags.clear(); if (m_site->contains("Regex/Tags")) { QRegExp rxtags(m_site->value("Regex/Tags")); rxtags.setMinimal(true); int p = 0; QStringList order = m_site->value("Regex/TagsOrder").split('|', QString::SkipEmptyParts); while ((p = rxtags.indexIn(source, p)) != -1) { p += rxtags.matchedLength(); QString type = "", tag = ""; int count = 1; if (order.empty()) { switch (rxtags.captureCount()) { case 4: order << "type" << "" << "count" << "tag"; break; case 3: order << "type" << "tag" << "count"; break; case 2: order << "type" << "tag"; break; case 1: order << "tag"; break; } } for (int o = 0; o < order.size(); o++) { if (order.at(o) == "tag" && tag.isEmpty()) { tag = rxtags.cap(o + 1).replace(" ", "_").replace("&", "&").trimmed(); } else if (order.at(o) == "type" && type.isEmpty()) { type = rxtags.cap(o + 1).toLower().trimmed(); if (type.contains(", ")) { type = type.split(", ").at(0).trimmed(); } if (type == "series") { type = "copyright"; } else if (type == "mangaka") { type = "artist"; } else if (type == "game") { type = "copyright"; } else if (type == "studio") { type = "circle"; } else if (type == "source") { type = "general"; } else if (type == "character group") { type = "general"; } else if (type.length() == 1) { int tpe = type.toInt(); if (tpe >= 0 && tpe <= 4) { QStringList types = QStringList() << "general" << "artist" << "unknown" << "copyright" << "character"; type = types[tpe]; } } } else if (order.at(o) == "count" && count != 0) { count = rxtags.cap(o + 1).toLower().endsWith('k') ? rxtags.cap(3).left(rxtags.cap(3).length() - 1).toInt() * 1000 : rxtags.cap(3).toInt(); } } if (type.isEmpty()) { type = "unknown"; } m_tags.append(Tag(tag, type, count)); } } // Getting last page if (m_site->contains("Regex/Count") && m_imagesCount < 1) { QRegExp rxlast(m_site->value("Regex/Count")); rxlast.indexIn(source, 0); m_imagesCount = rxlast.cap(1).remove(",").toInt(); } if (m_imagesCount < 1) { for (Tag tag : m_tags) { if (tag.text() == m_search.join(" ")) { m_imagesCount = tag.count(); if (m_pagesCount < 0) m_pagesCount = (int)ceil((m_imagesCount * 1.) / m_imagesPerPage); } } } if (m_site->contains("Regex/LastPage") && (m_imagesCount < 1 || m_imagesCount % 1000 == 0)) { QRegExp rxlast(m_site->value("Regex/LastPage")); rxlast.indexIn(source, 0); m_pagesCount = rxlast.cap(1).remove(",").toInt(); if (m_pagesCount != 0) m_imagesCount = m_pagesCount * m_imagesPerPage; } // Wiki m_wiki.clear(); if (m_site->contains("Regex/Wiki")) { QRegExp rxwiki(m_site->value("Regex/Wiki")); rxwiki.setMinimal(true); if (rxwiki.indexIn(source) != -1) { m_wiki = rxwiki.cap(1); m_wiki.remove("/wiki/show?title=").remove(QRegExp("<p><a href=\"([^\"]+)\">Full entry »</a></p>")).replace("<h6>", "<span class=\"title\">").replace("</h6>", "</span>"); } } m_replyTags->deleteLater(); m_replyTagsExists = false; emit finishedLoadingTags(this); }
void Image::parseDetails() { m_loadingDetails = false; // Aborted if (m_loadDetails->error() == QNetworkReply::OperationCanceledError) { m_loadDetails->deleteLater(); m_loadDetails = nullptr; return; } // Check redirection QUrl redir = m_loadDetails->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (!redir.isEmpty()) { m_pageUrl = redir; loadDetails(); return; } int statusCode = m_loadDetails->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (statusCode == 429) { log(QStringLiteral("Details limit reached (429). New try.")); loadDetails(true); return; } QString source = QString::fromUtf8(m_loadDetails->readAll()); // Get an api able to parse details Api *api = m_parentSite->detailsApi(); if (api == Q_NULLPTR) return; // Parse source ParsedDetails ret = api->parseDetails(source, m_parentSite); if (!ret.error.isEmpty()) { log(QStringLiteral("[%1][%2] %3").arg(m_parentSite->url(), api->getName(), ret.error), Logger::Warning); emit finishedLoadingTags(); return; } // Fill data from parsing result if (!ret.pools.isEmpty()) { m_pools = ret.pools; } if (!ret.tags.isEmpty()) { m_tags = ret.tags; } if (ret.createdAt.isValid()) { m_createdAt = ret.createdAt; } // Image url if (!ret.imageUrl.isEmpty()) { QString before = m_url; QUrl newUrl = m_parentSite->fixUrl(ret.imageUrl, before); m_url = newUrl.toString(); m_fileUrl = newUrl; if (before != m_url) { delete m_extensionRotator; m_extensionRotator = nullptr; setFileSize(0); emit urlChanged(before, m_url); } } // Get rating from tags if (m_rating.isEmpty()) { int ratingTagIndex = -1; for (int it = 0; it < m_tags.count(); ++it) { if (m_tags[it].type().name() == "rating") { m_rating = m_tags[it].text(); ratingTagIndex = it; break; } } if (ratingTagIndex != -1) { m_tags.removeAt(ratingTagIndex); } } m_loadDetails->deleteLater(); m_loadDetails = nullptr; m_loadedDetails = true; refreshTokens(); emit finishedLoadingTags(); }