Skip to content

Instantly share code, notes, and snippets.

@RPG-18
Last active September 1, 2021 08:46
Show Gist options
  • Save RPG-18/17712234419aa3d155d99da441c378d2 to your computer and use it in GitHub Desktop.
Save RPG-18/17712234419aa3d155d99da441c378d2 to your computer and use it in GitHub Desktop.
Get books from one book resource
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include <QtCore/QUrl>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QTimer>
#include <QtCore/QUrlQuery>
#include <QtCore/QStandardPaths>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkCookie>
#include <QtNetwork/QNetworkCookieJar>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkAccessManager>
#include <QtGui/QImage>
#include <QtGui/QPainter>
#include <QtGui/QPdfWriter>
#include <QtWebEngineCore/QWebEngineCookieStore>
#include <QtWebEngineWidgets/QWebEngineProfile>
#include "mainwindow.h"
#include "ui_mainwindow.h"
namespace {
const QString BasePath = "липкиеручки.рф/pages/read_book_online/";
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_ui(new Ui::MainWindow),
m_store(nullptr),
m_cookieJar(new QNetworkCookieJar (this)),
m_networmManager(new QNetworkAccessManager(this)),
m_try(0),
m_currentPage(0),
m_capches(1)
{
m_ui->setupUi(this);
m_store = m_ui->webView->page()->profile()->cookieStore();
Q_ASSERT(m_store != nullptr);
connect(m_store, &QWebEngineCookieStore::cookieAdded, this, &MainWindow::handleCookieAdded);
m_store->loadAllCookies();
m_ui->webView->load(QUrl("липкиеручки.рф"));
m_networmManager->setCookieJar(m_cookieJar);
connect(m_networmManager, &QNetworkAccessManager::finished,
this, &MainWindow::handleImage);
}
MainWindow::~MainWindow() = default;
void MainWindow::onGrabButtonClicked()
{
if(!parseUrl(m_ui->webView->url()))
{
return;
}
const auto paths = QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
if (paths.isEmpty()) {
qWarning()<<"There is no standard path to download";
return;
}
downloadTo(*paths.begin());
}
void MainWindow::handleCookieAdded(const QNetworkCookie &cookie)
{
m_cookieJar->insertCookie(cookie);
}
bool MainWindow::parseUrl(const QUrl &url)
{
const auto query = QUrlQuery(url.query(QUrl::FullyDecoded));
if (query.isEmpty()){
return false;
}
static const QVector<QString> fields = {
"file", "bname", "uuid"
};
for (const auto& key: fields) {
if (!query.hasQueryItem(key)) {
qWarning()<<"Query hasn't param"<< key;
return false;
}
}
m_name = query.queryItemValue("bname", QUrl::FullyDecoded);
m_file = query.queryItemValue("file");
m_format = "jpg";
return true;
}
void MainWindow::downloadTo(const QString &path)
{
QDir dir(path);
m_writer = std::make_unique<QPdfWriter>(dir.absoluteFilePath(m_name+".pdf"));
QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait,
QMarginsF(0,0,0,0));
m_writer->setPageLayout(layout);
m_writer->setResolution(96);
m_writer->setTitle(m_name);
m_painter = std::make_unique<QPainter>();
m_painter->begin(m_writer.get());
nextImage();
}
void MainWindow::handleImage(QNetworkReply *reply)
{
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
qWarning()<<"Network error"<<reply->errorString();
if(m_try == 3) {
m_painter->end();
m_painter.reset();
m_writer.reset();
return;
}
if (m_format == "gif") {
m_format = "jpg";
} else {
m_format = "gif";
}
--m_currentPage;
++m_try;
nextImage();
return;
}
m_try = 0;
qDebug()<<"Write page"<<m_currentPage<<reply->url();
std::string f;
if (m_format == "jpg") {
f = "JPEG";
} else {
f = "GIF";
}
const auto data = reply->readAll();
const auto source = QImage::fromData(data, f.c_str());
if (source.isNull()) {
//handleCapcha(data, reply->url());
--m_currentPage;
nextImage();
return;
}
m_ui->pages->setText(QString::number(m_currentPage));
const auto dest = source.scaledToWidth(m_writer->width(), Qt::SmoothTransformation);
m_painter->drawImage(QPoint(0,0), dest);
m_writer->newPage();
nextImage();
}
void MainWindow::handleCapcha(const QByteArray &page, const QUrl &url )
{
++m_capches;
m_ui->webView->page()->setHtml(page, url);
m_ui->captches->setText(QString::number(m_capches));
QEventLoop loop;
constexpr int duration = 1000*60*5;
QTimer::singleShot(duration, &loop, &QEventLoop::quit);
loop.exec();
}
void MainWindow::nextImage()
{
QUrlQuery query;
query.addQueryItem("file", m_file);
query.addQueryItem("rt", "w640");
query.addQueryItem("ft", m_format);
query.addQueryItem("page", QString::number(m_currentPage));
QUrl url(BasePath);
url.setQuery(query);
m_networmManager->get(QNetworkRequest(url));
++m_currentPage;
}
#pragma once
#include <memory>
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class QPainter;
class QNetworkReply;
class QNetworkCookie;
class QNetworkCookieJar;
class QWebEngineCookieStore;
class QNetworkAccessManager;
class QPdfWriter;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void onGrabButtonClicked();
void handleCookieAdded(const QNetworkCookie &cookie);
void handleImage(QNetworkReply *reply);
private:
bool parseUrl(const QUrl &url);
void downloadTo(const QString &path);
void nextImage();
void handleCapcha(const QByteArray &page, const QUrl &url);
private:
std::unique_ptr<Ui::MainWindow> m_ui;
QWebEngineCookieStore *m_store;
QNetworkCookieJar* m_cookieJar;
QNetworkAccessManager* m_networmManager;
QString m_file;
QString m_name;
QString m_format;
std::unique_ptr<QPdfWriter> m_writer;
std::unique_ptr<QPainter> m_painter;
int m_try;
int m_currentPage;
int m_capches;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment