# Readability - plugin for Falkon # Copyright (C) 2019 Juraj Oravec # # 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 . import Falkon import os from PySide2 import QtCore, QtGui from readability.settingsDialog import SettingsDialog from readability.button import Button from readability.str2bool import str2bool class Readability(Falkon.PluginInterface, QtCore.QObject): config = None view = None buttons = None style = "" scriptReadability = "" scriptToolbar = "" scriptCall = "" def init(self, state, settingsPath): self.config = { "settingsFile": os.path.join(settingsPath, "readability", "settings.ini"), "icon": "dark", "contextMenu": False, "colorTheme": "sepia", "font": "sans-serif", "fontSize": 5 } self.buttons = {} self.loadSettings() self.onConfigUpdate() plugins = Falkon.MainApplication.instance().plugins() plugins.mainWindowCreated.connect(self.onMainWindowCreated) plugins.mainWindowDeleted.connect(self.onMainWindowDeleted) 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) 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 def onMainWindowDeleted(self, window): if window not in self.buttons: return button = self.buttons[window] window.navigationBar().removeToolButton(button) del self.buttons[window] 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) initConfigScript = "initConfig('{}', '{}', {});".format( self.config["colorTheme"], self.config["font"], self.config["fontSize"] ) self.view.page().runJavaScript( self.scriptCall + initConfigScript, Falkon.WebPage.SafeJsWorld ) 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.setValue("colorTheme", self.config["colorTheme"]) settings.setValue("font", self.config["font"]) settings.setValue("fontSize", self.config["fontSize"]) 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"]) ) self.config["colorTheme"] = str(settings.value("colorTheme", self.config["colorTheme"])) self.config["font"] = str(settings.value("font", self.config["font"])) self.config["fontSize"] = int(settings.value("fontSize", self.config["fontSize"])) settings.endGroup() def onConfigUpdate(self): for _, button in self.buttons.items(): button.updateIcon(self.config["icon"]) Falkon.registerPlugin(Readability())