This commit is contained in:
Martin Rotter 2022-02-11 15:19:05 +01:00
parent 1389a86083
commit 4ec98eb322
9 changed files with 117 additions and 43 deletions

View file

@ -229,6 +229,8 @@ set(SOURCES
network-web/oauth2service.h network-web/oauth2service.h
network-web/oauthhttphandler.cpp network-web/oauthhttphandler.cpp
network-web/oauthhttphandler.h network-web/oauthhttphandler.h
network-web/readability.cpp
network-web/readability.h
network-web/silentnetworkaccessmanager.cpp network-web/silentnetworkaccessmanager.cpp
network-web/silentnetworkaccessmanager.h network-web/silentnetworkaccessmanager.h
network-web/webfactory.cpp network-web/webfactory.cpp

View file

@ -11,6 +11,7 @@
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "network-web/networkfactory.h" #include "network-web/networkfactory.h"
#include "network-web/readability.h"
#include "network-web/webfactory.h" #include "network-web/webfactory.h"
#include "services/abstract/serviceroot.h" #include "services/abstract/serviceroot.h"
@ -36,7 +37,10 @@ WebBrowser::WebBrowser(QWidget* parent) : TabContent(parent),
m_actionStop(m_webView->pageAction(QWebEnginePage::WebAction::Stop)), m_actionStop(m_webView->pageAction(QWebEnginePage::WebAction::Stop)),
m_actionOpenInSystemBrowser(new QAction(qApp->icons()->fromTheme(QSL("document-open")), m_actionOpenInSystemBrowser(new QAction(qApp->icons()->fromTheme(QSL("document-open")),
tr("Open this website in system web browser"), tr("Open this website in system web browser"),
this)) { this)),
m_actionReadabilePage(new QAction(qApp->icons()->fromTheme(QSL("document-preview")),
tr("View website in reader mode"),
this)) {
// Initialize the components and layout. // Initialize the components and layout.
initializeLayout(); initializeLayout();
setFocusProxy(m_txtLocation); setFocusProxy(m_txtLocation);
@ -64,6 +68,7 @@ void WebBrowser::createConnections() {
}); });
connect(m_actionOpenInSystemBrowser, &QAction::triggered, this, &WebBrowser::openCurrentSiteInSystemBrowser); connect(m_actionOpenInSystemBrowser, &QAction::triggered, this, &WebBrowser::openCurrentSiteInSystemBrowser);
connect(m_actionReadabilePage, &QAction::triggered, this, &WebBrowser::readabilePage);
connect(m_txtLocation, &LocationLineEdit::submitted, connect(m_txtLocation, &LocationLineEdit::submitted,
this, static_cast<void (WebBrowser::*)(const QString&)>(&WebBrowser::loadUrl)); this, static_cast<void (WebBrowser::*)(const QString&)>(&WebBrowser::loadUrl));
@ -79,6 +84,8 @@ void WebBrowser::createConnections() {
connect(m_webView, &WebViewer::iconChanged, this, &WebBrowser::onIconChanged); connect(m_webView, &WebViewer::iconChanged, this, &WebBrowser::onIconChanged);
connect(m_webView->page(), &WebPage::windowCloseRequested, this, &WebBrowser::closeRequested); connect(m_webView->page(), &WebPage::windowCloseRequested, this, &WebBrowser::closeRequested);
connect(qApp->web()->readability(), &Readability::htmlReadabled, this, &WebBrowser::setReadabledHtml);
connect(qApp->web()->readability(), &Readability::errorOnHtmlReadabiliting, this, &WebBrowser::readabilityFailed);
} }
void WebBrowser::updateUrl(const QUrl& url) { void WebBrowser::updateUrl(const QUrl& url) {
@ -167,6 +174,13 @@ void WebBrowser::loadMessage(const Message& message, RootItem* root) {
loadMessages({ message }, root); loadMessages({ message }, root);
} }
void WebBrowser::readabilePage() {
m_actionReadabilePage->setEnabled(false);
m_webView->page()->toHtml([this](const QString& htm) {
qApp->web()->readability()->makeHtmlReadable(htm, m_webView->url().toString());
});
}
bool WebBrowser::eventFilter(QObject* watched, QEvent* event) { bool WebBrowser::eventFilter(QObject* watched, QEvent* event) {
Q_UNUSED(watched) Q_UNUSED(watched)
@ -208,6 +222,18 @@ void WebBrowser::onIconChanged(const QIcon& icon) {
emit iconChanged(m_index, icon); emit iconChanged(m_index, icon);
} }
void WebBrowser::setReadabledHtml(const QString& better_html) {
m_webView->setHtml(better_html, m_webView->url());
}
void WebBrowser::readabilityFailed(const QString& error) {
MessageBox::show({}, QMessageBox::Icon::Critical,
tr("Reader mode failed for this website"),
tr("Reader mode cannot be applied to current page."),
{},
error);
}
void WebBrowser::initializeLayout() { void WebBrowser::initializeLayout() {
m_toolBar->setFloatable(false); m_toolBar->setFloatable(false);
m_toolBar->setMovable(false); m_toolBar->setMovable(false);
@ -227,6 +253,8 @@ void WebBrowser::initializeLayout() {
QWidgetAction* act_discover = new QWidgetAction(this); QWidgetAction* act_discover = new QWidgetAction(this);
m_actionOpenInSystemBrowser->setEnabled(false); m_actionOpenInSystemBrowser->setEnabled(false);
m_actionReadabilePage->setEnabled(false);
act_discover->setDefaultWidget(m_btnDiscoverFeeds); act_discover->setDefaultWidget(m_btnDiscoverFeeds);
// Add needed actions into toolbar. // Add needed actions into toolbar.
@ -235,6 +263,7 @@ void WebBrowser::initializeLayout() {
m_toolBar->addAction(m_actionReload); m_toolBar->addAction(m_actionReload);
m_toolBar->addAction(m_actionStop); m_toolBar->addAction(m_actionStop);
m_toolBar->addAction(m_actionOpenInSystemBrowser); m_toolBar->addAction(m_actionOpenInSystemBrowser);
m_toolBar->addAction(m_actionReadabilePage);
m_toolBar->addAction(act_discover); m_toolBar->addAction(act_discover);
m_toolBar->addWidget(m_txtLocation); m_toolBar->addWidget(m_txtLocation);
@ -260,6 +289,7 @@ void WebBrowser::onLoadingStarted() {
m_btnDiscoverFeeds->clearFeedAddresses(); m_btnDiscoverFeeds->clearFeedAddresses();
m_loadingProgress->show(); m_loadingProgress->show();
m_actionOpenInSystemBrowser->setEnabled(false); m_actionOpenInSystemBrowser->setEnabled(false);
m_actionReadabilePage->setEnabled(false);
} }
void WebBrowser::onLoadingProgress(int progress) { void WebBrowser::onLoadingProgress(int progress) {
@ -270,8 +300,13 @@ void WebBrowser::onLoadingFinished(bool success) {
if (success) { if (success) {
auto url = m_webView->url(); auto url = m_webView->url();
if (url.isValid() && !url.host().contains(QSL(APP_LOW_NAME))) { if (url.isValid() && !url.host().isEmpty()) {
m_actionOpenInSystemBrowser->setEnabled(true); m_actionOpenInSystemBrowser->setEnabled(true);
m_actionReadabilePage->setEnabled(true);
}
else {
m_actionOpenInSystemBrowser->setEnabled(false);
m_actionReadabilePage->setEnabled(false);
} }
// Let's check if there are any feeds defined on the web and eventually // Let's check if there are any feeds defined on the web and eventually

View file

@ -55,6 +55,7 @@ class WebBrowser : public TabContent {
virtual bool eventFilter(QObject* watched, QEvent* event); virtual bool eventFilter(QObject* watched, QEvent* event);
private slots: private slots:
void readabilePage();
void openCurrentSiteInSystemBrowser(); void openCurrentSiteInSystemBrowser();
void updateUrl(const QUrl& url); void updateUrl(const QUrl& url);
void onLoadingStarted(); void onLoadingStarted();
@ -62,6 +63,8 @@ class WebBrowser : public TabContent {
void onLoadingFinished(bool success); void onLoadingFinished(bool success);
void onTitleChanged(const QString& new_title); void onTitleChanged(const QString& new_title);
void onIconChanged(const QIcon& icon); void onIconChanged(const QIcon& icon);
void setReadabledHtml(const QString& better_html);
void readabilityFailed(const QString& error);
signals: signals:
void closeRequested(); void closeRequested();
@ -87,6 +90,7 @@ class WebBrowser : public TabContent {
QAction* m_actionReload; QAction* m_actionReload;
QAction* m_actionStop; QAction* m_actionStop;
QAction* m_actionOpenInSystemBrowser; QAction* m_actionOpenInSystemBrowser;
QAction* m_actionReadabilePage;
QList<Message> m_messages; QList<Message> m_messages;
QPointer<RootItem> m_root; QPointer<RootItem> m_root;
}; };

View file

@ -51,7 +51,8 @@ DVALUE(bool) AdBlock::AdBlockEnabledDef = false;
DKEY AdBlock::FilterLists = "filter_lists"; DKEY AdBlock::FilterLists = "filter_lists";
DVALUE(QStringList) AdBlock::FilterListsDef = { DVALUE(QStringList) AdBlock::FilterListsDef = {
QSL("https://easylist.to/easylist/easylist.txt"), QSL("https://easylist.to/easylist/easylist.txt"),
QSL("https://easylist.to/easylist/easyprivacy.txt") QSL("https://easylist.to/easylist/easyprivacy.txt"),
QSL("https://easylist.to/easylist/fanboy-social.txt")
}; };
DKEY AdBlock::CustomFilters = "custom_filters"; DKEY AdBlock::CustomFilters = "custom_filters";

View file

@ -328,46 +328,6 @@ QProcess* AdBlockManager::startServer(int port) {
QDir::toNativeSeparators(m_unifiedFiltersFile) QDir::toNativeSeparators(m_unifiedFiltersFile)
}); });
/*
#if defined(Q_OS_WIN)
proc->setProgram(QSL("node.exe"));
#else
proc->setProgram(QSL("node"));
#endif
proc->setArguments({
QDir::toNativeSeparators(temp_server),
QString::number(port),
QDir::toNativeSeparators(m_unifiedFiltersFile)
});
proc->setProcessEnvironment(QProcessEnvironment::systemEnvironment());
auto pe = proc->processEnvironment();
if (!pe.contains(QSL("NODE_PATH"))) {
try {
const QString system_node_prefix = IOFactory::startProcessGetOutput(
#if defined(Q_OS_WIN)
QSL("npm.cmd")
#else
QSL("npm")
#endif
, { QSL("root"), QSL("--quiet"), QSL("-g") }
);
if (!system_node_prefix.isEmpty()) {
pe.insert(QSL("NODE_PATH"), system_node_prefix.simplified());
}
}
catch (const ApplicationException& ex) {
qWarningNN << LOGSEC_ADBLOCK << "Failed to get NPM root path:" << QUOTE_W_SPACE_DOT(ex.message());
}
}
proc->setProcessEnvironment(pe);
*/
qDebugNN << LOGSEC_ADBLOCK << "Attempting to start AdBlock server."; qDebugNN << LOGSEC_ADBLOCK << "Attempting to start AdBlock server.";
return proc; return proc;
} }

View file

@ -0,0 +1,37 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#include "network-web/readability.h"
#include "miscellaneous/application.h"
#include "miscellaneous/nodejs.h"
Readability::Readability(QObject* parent) : QObject{parent} {}
void Readability::makeHtmlReadable(const QString& html, const QString& base_url) {
QProcess* proc = new QProcess(this);
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &Readability::onReadabilityFinished);
qApp->nodejs()->runScript(proc,
QSL("c:\\Projekty\\Moje\\build-rssguard-Desktop_Qt_6_2_3_MSVC2017_64bit-Debug\\"
"src\\rssguard\\data4\\node-packages-windows\\article-to-readable.js"),
{ base_url });
proc->write(html.toUtf8());
proc->closeWriteChannel();
}
void Readability::onReadabilityFinished(int exit_code, QProcess::ExitStatus exit_status) {
QProcess* proc = qobject_cast<QProcess*>(sender());
if (exit_status == QProcess::ExitStatus::NormalExit &&
exit_code == EXIT_SUCCESS) {
emit htmlReadabled(QString::fromUtf8(proc->readAllStandardOutput()));
}
else {
QString err = QString::fromUtf8(proc->readAllStandardError());
emit errorOnHtmlReadabiliting(err);
}
proc->deleteLater();
}

View file

@ -0,0 +1,26 @@
// For license of this file, see <project-root-folder>/LICENSE.md.
#ifndef READABILITY_H
#define READABILITY_H
#include <QObject>
#include <QProcess>
class Readability : public QObject {
Q_OBJECT
public:
explicit Readability(QObject* parent = nullptr);
void makeHtmlReadable(const QString& html, const QString& base_url = {});
private slots:
void onReadabilityFinished(int exit_code, QProcess::ExitStatus exit_status);
signals:
void htmlReadabled(const QString& better_html);
void errorOnHtmlReadabiliting(const QString& error);
};
#endif // READABILITY_H

View file

@ -6,6 +6,7 @@
#include "miscellaneous/application.h" #include "miscellaneous/application.h"
#include "miscellaneous/iconfactory.h" #include "miscellaneous/iconfactory.h"
#include "network-web/cookiejar.h" #include "network-web/cookiejar.h"
#include "network-web/readability.h"
#include <QDesktopServices> #include <QDesktopServices>
#include <QProcess> #include <QProcess>
@ -37,6 +38,7 @@ WebFactory::WebFactory(QObject* parent)
#endif #endif
m_cookieJar = new CookieJar(nullptr); m_cookieJar = new CookieJar(nullptr);
m_readability = new Readability(this);
#if defined(USE_WEBENGINE) #if defined(USE_WEBENGINE)
#if QT_VERSION >= 0x050D00 // Qt >= 5.13.0 #if QT_VERSION >= 0x050D00 // Qt >= 5.13.0
@ -363,6 +365,10 @@ CookieJar* WebFactory::cookieJar() const {
return m_cookieJar; return m_cookieJar;
} }
Readability* WebFactory::readability() const {
return m_readability;
}
void WebFactory::generateUnescapes() { void WebFactory::generateUnescapes() {
m_htmlNamedEntities[QSL("AElig")] = 0x00c6; m_htmlNamedEntities[QSL("AElig")] = 0x00c6;
m_htmlNamedEntities[QSL("AMP")] = 38; m_htmlNamedEntities[QSL("AMP")] = 38;

View file

@ -20,6 +20,7 @@ class NetworkUrlInterceptor;
#endif #endif
class CookieJar; class CookieJar;
class Readability;
class WebFactory : public QObject { class WebFactory : public QObject {
Q_OBJECT Q_OBJECT
@ -46,6 +47,7 @@ class WebFactory : public QObject {
#endif #endif
CookieJar* cookieJar() const; CookieJar* cookieJar() const;
Readability* readability() const;
void updateProxy(); void updateProxy();
bool openUrlInExternalBrowser(const QString& url) const; bool openUrlInExternalBrowser(const QString& url) const;
@ -71,6 +73,7 @@ class WebFactory : public QObject {
#endif #endif
CookieJar* m_cookieJar; CookieJar* m_cookieJar;
Readability* m_readability;
QMap<QString, char16_t> m_htmlNamedEntities; QMap<QString, char16_t> m_htmlNamedEntities;
}; };