Readability/readability/__init__.py

190 lines
6.9 KiB
Python
Raw Normal View History

# Readability - plugin for Falkon
# Copyright (C) 2019 Juraj Oravec <sgd.orava@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2019-06-10 22:24:42 +02:00
import Falkon
import os
from PySide2 import QtCore, QtGui
from readability.settingsDialog import SettingsDialog
from readability.button import Button
from readability.str2bool import str2bool
2019-06-10 22:24:42 +02:00
class Readability(Falkon.PluginInterface, QtCore.QObject):
config = None
view = None
buttons = None
style = ""
scriptReadability = ""
scriptToolbar = ""
scriptCall = ""
2019-06-10 22:24:42 +02:00
def init(self, state, settingsPath):
self.config = {
"settingsFile": os.path.join(settingsPath, "readability", "settings.ini"),
"icon": "dark",
"contextMenu": False
}
self.buttons = {}
self.loadSettings()
self.onConfigUpdate()
2019-06-10 22:24:42 +02:00
plugins = Falkon.MainApplication.instance().plugins()
plugins.mainWindowCreated.connect(self.onMainWindowCreated)
plugins.mainWindowDeleted.connect(self.onMainWindowDeleted)
2019-06-10 22:24:42 +02:00
if state == Falkon.PluginInterface.LateInitState:
for window in Falkon.MainApplication.instance().windows():
self.onMainWindowCreated(window)
def unload(self):
for window in Falkon.MainApplication.instance().windows():
self.onMainWindowDeleted(window)
2019-06-10 22:24:42 +02:00
def testPlugin(self):
return True
def onMainWindowCreated(self, window):
button = Button(self.config["icon"])
button.clicked.connect(lambda: self.makeReadability(button.webView()))
window.navigationBar().addToolButton(button)
self.buttons[window] = button
2019-06-10 22:24:42 +02:00
def onMainWindowDeleted(self, window):
if window not in self.buttons:
return
button = self.buttons[window]
window.navigationBar().removeToolButton(button)
del self.buttons[window]
2019-06-10 22:24:42 +02:00
def populateWebViewMenu(self, menu, view, hitTestResult):
if not self.config["contextMenu"]:
return
self.view = view
if (hitTestResult.imageUrl().isEmpty()
and hitTestResult.linkUrl().isEmpty()
and hitTestResult.mediaUrl().isEmpty()
and not hitTestResult.isContentEditable()
and not hitTestResult.isContentSelected()):
icon = "icon-light.png" if self.config["icon"] == "light" else "icon-dark.png"
menu.addAction(
QtGui.QIcon(os.path.join(os.path.dirname(__file__), "data", icon)),
"Readability",
self.makeReadability
)
def loadStyle(self):
dataDir = os.path.join(os.path.dirname(__file__), "data")
iconClose = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-close.png"))
).toString()
iconCloseHover = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-close-hover.png"))
).toString()
iconDelete = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-Delete-24x24.png"))
).toString()
iconPlus = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-Plus-24x24.png"))
).toString()
iconMinus = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-Minus-24x24.png"))
).toString()
iconArrow = Falkon.QzTools.readAllFileContents(
os.path.join(dataDir, "RM-Type-Controls-Arrow.png")
)
iconControls = Falkon.QzTools.pixmapToDataUrl(
QtGui.QPixmap(os.path.join(dataDir, "RM-Type-Controls-24x24.png"))
).toString()
css = Falkon.QzTools.readAllFileContents(
os.path.join(dataDir, "style.css")
).replace("\n", "")
css = css.replace("{iconClose}", iconClose)
css = css.replace("{iconCloseHover}", iconCloseHover)
css = css.replace("{iconDelete}", iconDelete)
css = css.replace("{iconPlus}", iconPlus)
css = css.replace("{iconMinus}", iconMinus)
css = css.replace("{iconArrow}", iconArrow)
css = css.replace("{iconControls}", iconControls)
return css
def makeReadability(self, view=None):
if view:
self.view = view
dataDir = os.path.join(os.path.dirname(__file__), "data")
if not self.style:
self.style = self.loadStyle()
if not self.scriptReadability:
self.scriptReadability = Falkon.QzTools.readAllFileContents(
os.path.join(dataDir, "Readability.js")
)
if not self.scriptToolbar:
self.scriptToolbar = Falkon.QzTools.readAllFileContents(
os.path.join(dataDir, "Toolbar.js")
)
if not self.scriptCall:
self.scriptCall = Falkon.QzTools.readAllFileContents(
os.path.join(dataDir, "Call.js")
)
self.scriptCall = self.scriptCall.replace("{readability.js}", self.scriptReadability)
self.scriptCall = self.scriptCall.replace("{toolbar.js}", self.scriptToolbar)
self.scriptCall = self.scriptCall.replace("{style.css}", self.style)
self.view.page().runJavaScript(self.scriptCall)
def showSettings(self, parent):
settings = SettingsDialog(self.config, parent)
settings.accepted.connect(self.saveSettings)
settings.accepted.connect(self.onConfigUpdate)
settings.exec_()
def saveSettings(self):
settings = QtCore.QSettings(self.config["settingsFile"], QtCore.QSettings.IniFormat)
settings.beginGroup("Readability")
settings.setValue("icon", self.config["icon"])
settings.setValue("showInContextMenu", self.config["contextMenu"])
settings.endGroup()
settings.sync()
def loadSettings(self):
settings = QtCore.QSettings(self.config["settingsFile"], QtCore.QSettings.IniFormat)
settings.beginGroup("Readability")
self.config["icon"] = str(settings.value("icon", self.config["icon"]))
self.config["contextMenu"] = str2bool(
settings.value("showInContextMenu", self.config["contextMenu"])
)
settings.endGroup()
def onConfigUpdate(self):
for _, button in self.buttons.items():
button.updateIcon(self.config["icon"])
2019-06-10 22:24:42 +02:00
Falkon.registerPlugin(Readability())