eric7/WebBrowser/Tools/WebIconProvider.py

branch
eric7
changeset 8312
800c432b34c8
parent 8240
93b8a353c4bf
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2016 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module containing a web site icon storage object.
8 """
9
10 import json
11 import os
12 import contextlib
13
14 from PyQt5.QtCore import (
15 pyqtSignal, QObject, QByteArray, QBuffer, QIODevice, QUrl
16 )
17 from PyQt5.QtGui import QIcon, QPixmap, QImage
18 from PyQt5.QtWidgets import QDialog
19
20 from Utilities.AutoSaver import AutoSaver
21
22 import UI.PixmapCache
23
24
25 class WebIconProvider(QObject):
26 """
27 Class implementing a web site icon storage.
28
29 @signal changed() emitted to indicate a change of the icons database
30 """
31 changed = pyqtSignal()
32
33 def __init__(self, parent=None):
34 """
35 Constructor
36
37 @param parent reference to the parent object (QObject)
38 """
39 super().__init__(parent)
40
41 self.__encoding = "iso-8859-1"
42 self.__iconsFileName = "web_site_icons.json"
43 self.__iconDatabasePath = "" # saving of icons disabled
44
45 self.__iconsDB = {}
46 self.__loaded = False
47
48 self.__saveTimer = AutoSaver(self, self.save)
49
50 self.changed.connect(self.__saveTimer.changeOccurred)
51
52 def setIconDatabasePath(self, path):
53 """
54 Public method to set the path for the web site icons store.
55
56 @param path path to store the icons file to
57 @type str
58 """
59 if path != self.__iconDatabasePath:
60 self.close()
61
62 self.__iconDatabasePath = path
63
64 def iconDatabasePath(self):
65 """
66 Public method o get the path for the web site icons store.
67
68 @return path to store the icons file to
69 @rtype str
70 """
71 return self.__iconDatabasePath
72
73 def close(self):
74 """
75 Public method to close the web icon provider.
76 """
77 self.__saveTimer.saveIfNeccessary()
78 self.__loaded = False
79 self.__iconsDB = {}
80
81 def load(self):
82 """
83 Public method to load the web site icons.
84 """
85 if self.__loaded:
86 return
87
88 if self.__iconDatabasePath:
89 filename = os.path.join(self.__iconDatabasePath,
90 self.__iconsFileName)
91 try:
92 with open(filename, "r") as f:
93 db = json.load(f)
94 except OSError:
95 # ignore silentyl
96 db = {}
97
98 self.__iconsDB = {}
99 for url, data in db.items():
100 self.__iconsDB[url] = QIcon(QPixmap.fromImage(QImage.fromData(
101 QByteArray(data.encode(self.__encoding)))))
102
103 self.__loaded = True
104
105 def save(self):
106 """
107 Public method to save the web site icons.
108 """
109 if not self.__loaded:
110 return
111
112 from WebBrowser.WebBrowserWindow import WebBrowserWindow
113 if not WebBrowserWindow.isPrivate() and bool(self.__iconDatabasePath):
114 db = {}
115 for url, icon in self.__iconsDB.items():
116 ba = QByteArray()
117 buffer = QBuffer(ba)
118 buffer.open(QIODevice.OpenModeFlag.WriteOnly)
119 icon.pixmap(32).toImage().save(buffer, "PNG")
120 db[url] = bytes(buffer.data()).decode(self.__encoding)
121
122 filename = os.path.join(self.__iconDatabasePath,
123 self.__iconsFileName)
124 with contextlib.suppress(OSError), open(filename, "w") as f:
125 json.dump(db, f)
126
127 def saveIcon(self, view):
128 """
129 Public method to save a web site icon.
130
131 @param view reference to the view object
132 @type WebBrowserView
133 """
134 scheme = view.url().scheme()
135 if scheme in ["eric", "about", "qthelp", "file", "abp", "ftp"]:
136 return
137
138 self.load()
139
140 if view.mainWindow().isPrivate():
141 return
142
143 urlStr = self.__urlToString(view.url())
144 self.__iconsDB[urlStr] = view.icon()
145
146 self.changed.emit()
147
148 def __urlToString(self, url):
149 """
150 Private method to convert an URL to a string.
151
152 @param url URL to be converted
153 @type QUrl
154 @return string representation of the URL
155 @rtype str
156 """
157 return url.toString(
158 QUrl.ComponentFormattingOption.PrettyDecoded |
159 QUrl.UrlFormattingOption.RemoveUserInfo |
160 QUrl.UrlFormattingOption.RemoveFragment |
161 QUrl.UrlFormattingOption.RemovePath
162 )
163
164 def iconForUrl(self, url):
165 """
166 Public method to get an icon for an URL.
167
168 @param url URL to get icon for
169 @type QUrl
170 @return icon for the URL
171 @rtype QIcon
172 """
173 scheme2iconName = {
174 "eric": "ericWeb",
175 "about": "ericWeb",
176 "qthelp": "qthelp",
177 "file": "fileMisc",
178 "abp": "adBlockPlus",
179 "ftp": "network-server",
180 }
181
182 scheme = url.scheme()
183 iconName = scheme2iconName.get(scheme)
184 if iconName:
185 return UI.PixmapCache.getIcon(iconName)
186
187 self.load()
188
189 urlStr = self.__urlToString(url)
190 if urlStr in self.__iconsDB:
191 return self.__iconsDB[urlStr]
192 else:
193 for iconUrlStr in self.__iconsDB:
194 if iconUrlStr.startswith(urlStr):
195 return self.__iconsDB[iconUrlStr]
196
197 # try replacing http scheme with https scheme
198 url = QUrl(url)
199 if url.scheme() == "http":
200 url.setScheme("https")
201 urlStr = self.__urlToString(url)
202 if urlStr in self.__iconsDB:
203 return self.__iconsDB[urlStr]
204 else:
205 for iconUrlStr in self.__iconsDB:
206 if iconUrlStr.startswith(urlStr):
207 return self.__iconsDB[iconUrlStr]
208
209 if scheme == "https":
210 return UI.PixmapCache.getIcon("securityHigh32")
211 else:
212 return UI.PixmapCache.getIcon("defaultIcon")
213
214 def clear(self):
215 """
216 Public method to clear the icons cache.
217 """
218 self.load()
219 self.__iconsDB = {}
220 self.changed.emit()
221 self.__saveTimer.saveIfNeccessary()
222
223 def showWebIconDialog(self):
224 """
225 Public method to show a dialog to manage the Favicons.
226 """
227 self.load()
228
229 from .WebIconDialog import WebIconDialog
230 dlg = WebIconDialog(self.__iconsDB)
231 if dlg.exec() == QDialog.DialogCode.Accepted:
232 changed = False
233 urls = dlg.getUrls()
234 for url in list(self.__iconsDB.keys())[:]:
235 if url not in urls:
236 del self.__iconsDB[url]
237 changed = True
238 if changed:
239 self.changed.emit()
240
241
242 _WebIconProvider = None
243
244
245 def instance():
246 """
247 Global function to get a reference to the web icon provider and create it,
248 if it hasn't been yet.
249
250 @return reference to the web icon provider object
251 @rtype WebIconProvider
252 """
253 global _WebIconProvider
254
255 if _WebIconProvider is None:
256 _WebIconProvider = WebIconProvider()
257
258 return _WebIconProvider

eric ide

mercurial