save
This commit is contained in:
parent
1389a86083
commit
4ec98eb322
9 changed files with 117 additions and 43 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
37
src/librssguard/network-web/readability.cpp
Executable file
37
src/librssguard/network-web/readability.cpp
Executable 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();
|
||||||
|
}
|
26
src/librssguard/network-web/readability.h
Executable file
26
src/librssguard/network-web/readability.h
Executable 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
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue