Wed, 14 Apr 2021 19:59:16 +0200
Applied some more code simplifications suggested by the new Simplify checker (Y105: use contextlib.suppress) (batch 1).
# -*- coding: utf-8 -*- # Copyright (c) 2016 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module containing a web site icon storage object. """ import json import os import contextlib from PyQt5.QtCore import ( pyqtSignal, QObject, QByteArray, QBuffer, QIODevice, QUrl ) from PyQt5.QtGui import QIcon, QPixmap, QImage from PyQt5.QtWidgets import QDialog from Utilities.AutoSaver import AutoSaver import UI.PixmapCache class WebIconProvider(QObject): """ Class implementing a web site icon storage. @signal changed() emitted to indicate a change of the icons database """ changed = pyqtSignal() def __init__(self, parent=None): """ Constructor @param parent reference to the parent object (QObject) """ super().__init__(parent) self.__encoding = "iso-8859-1" self.__iconsFileName = "web_site_icons.json" self.__iconDatabasePath = "" # saving of icons disabled self.__iconsDB = {} self.__loaded = False self.__saveTimer = AutoSaver(self, self.save) self.changed.connect(self.__saveTimer.changeOccurred) def setIconDatabasePath(self, path): """ Public method to set the path for the web site icons store. @param path path to store the icons file to @type str """ if path != self.__iconDatabasePath: self.close() self.__iconDatabasePath = path def iconDatabasePath(self): """ Public method o get the path for the web site icons store. @return path to store the icons file to @rtype str """ return self.__iconDatabasePath def close(self): """ Public method to close the web icon provider. """ self.__saveTimer.saveIfNeccessary() self.__loaded = False self.__iconsDB = {} def load(self): """ Public method to load the web site icons. """ if self.__loaded: return if self.__iconDatabasePath: filename = os.path.join(self.__iconDatabasePath, self.__iconsFileName) try: with open(filename, "r") as f: db = json.load(f) except OSError: # ignore silentyl db = {} self.__iconsDB = {} for url, data in db.items(): self.__iconsDB[url] = QIcon(QPixmap.fromImage(QImage.fromData( QByteArray(data.encode(self.__encoding))))) self.__loaded = True def save(self): """ Public method to save the web site icons. """ if not self.__loaded: return from WebBrowser.WebBrowserWindow import WebBrowserWindow if not WebBrowserWindow.isPrivate() and bool(self.__iconDatabasePath): db = {} for url, icon in self.__iconsDB.items(): ba = QByteArray() buffer = QBuffer(ba) buffer.open(QIODevice.OpenModeFlag.WriteOnly) icon.pixmap(32).toImage().save(buffer, "PNG") db[url] = bytes(buffer.data()).decode(self.__encoding) filename = os.path.join(self.__iconDatabasePath, self.__iconsFileName) with contextlib.suppress(OSError), open(filename, "w") as f: json.dump(db, f) def saveIcon(self, view): """ Public method to save a web site icon. @param view reference to the view object @type WebBrowserView """ scheme = view.url().scheme() if scheme in ["eric", "about", "qthelp", "file", "abp", "ftp"]: return self.load() if view.mainWindow().isPrivate(): return urlStr = self.__urlToString(view.url()) self.__iconsDB[urlStr] = view.icon() self.changed.emit() def __urlToString(self, url): """ Private method to convert an URL to a string. @param url URL to be converted @type QUrl @return string representation of the URL @rtype str """ return url.toString( QUrl.ComponentFormattingOption.PrettyDecoded | QUrl.UrlFormattingOption.RemoveUserInfo | QUrl.UrlFormattingOption.RemoveFragment | QUrl.UrlFormattingOption.RemovePath ) def iconForUrl(self, url): """ Public method to get an icon for an URL. @param url URL to get icon for @type QUrl @return icon for the URL @rtype QIcon """ scheme2iconName = { "eric": "ericWeb", "about": "ericWeb", "qthelp": "qthelp", "file": "fileMisc", "abp": "adBlockPlus", "ftp": "network-server", } scheme = url.scheme() iconName = scheme2iconName.get(scheme) if iconName: return UI.PixmapCache.getIcon(iconName) self.load() urlStr = self.__urlToString(url) if urlStr in self.__iconsDB: return self.__iconsDB[urlStr] else: for iconUrlStr in self.__iconsDB: if iconUrlStr.startswith(urlStr): return self.__iconsDB[iconUrlStr] # try replacing http scheme with https scheme url = QUrl(url) if url.scheme() == "http": url.setScheme("https") urlStr = self.__urlToString(url) if urlStr in self.__iconsDB: return self.__iconsDB[urlStr] else: for iconUrlStr in self.__iconsDB: if iconUrlStr.startswith(urlStr): return self.__iconsDB[iconUrlStr] if scheme == "https": return UI.PixmapCache.getIcon("securityHigh32") else: return UI.PixmapCache.getIcon("defaultIcon") def clear(self): """ Public method to clear the icons cache. """ self.load() self.__iconsDB = {} self.changed.emit() self.__saveTimer.saveIfNeccessary() def showWebIconDialog(self): """ Public method to show a dialog to manage the Favicons. """ self.load() from .WebIconDialog import WebIconDialog dlg = WebIconDialog(self.__iconsDB) if dlg.exec() == QDialog.DialogCode.Accepted: changed = False urls = dlg.getUrls() for url in list(self.__iconsDB.keys())[:]: if url not in urls: del self.__iconsDB[url] changed = True if changed: self.changed.emit() _WebIconProvider = None def instance(): """ Global function to get a reference to the web icon provider and create it, if it hasn't been yet. @return reference to the web icon provider object @rtype WebIconProvider """ global _WebIconProvider if _WebIconProvider is None: _WebIconProvider = WebIconProvider() return _WebIconProvider