src/eric7/WebBrowser/Tools/WebIconProvider.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2016 - 2022 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 PyQt6.QtCore import (
15 pyqtSignal, QObject, QByteArray, QBuffer, QIODevice, QUrl
16 )
17 from PyQt6.QtGui import QIcon, QPixmap, QImage
18 from PyQt6.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.UrlFormattingOption.RemoveUserInfo |
159 QUrl.UrlFormattingOption.RemoveFragment |
160 QUrl.UrlFormattingOption.RemovePath
161 )
162
163 def iconForUrl(self, url):
164 """
165 Public method to get an icon for an URL.
166
167 @param url URL to get icon for
168 @type QUrl
169 @return icon for the URL
170 @rtype QIcon
171 """
172 scheme2iconName = {
173 "eric": "ericWeb",
174 "about": "ericWeb",
175 "qthelp": "qthelp",
176 "file": "fileMisc",
177 "abp": "adBlockPlus",
178 "ftp": "network-server",
179 }
180
181 scheme = url.scheme()
182 iconName = scheme2iconName.get(scheme)
183 if iconName:
184 return UI.PixmapCache.getIcon(iconName)
185
186 self.load()
187
188 urlStr = self.__urlToString(url)
189 if urlStr in self.__iconsDB:
190 return self.__iconsDB[urlStr]
191 else:
192 for iconUrlStr in self.__iconsDB:
193 if iconUrlStr.startswith(urlStr):
194 return self.__iconsDB[iconUrlStr]
195
196 # try replacing http scheme with https scheme
197 url = QUrl(url)
198 if url.scheme() == "http":
199 url.setScheme("https")
200 urlStr = self.__urlToString(url)
201 if urlStr in self.__iconsDB:
202 return self.__iconsDB[urlStr]
203 else:
204 for iconUrlStr in self.__iconsDB:
205 if iconUrlStr.startswith(urlStr):
206 return self.__iconsDB[iconUrlStr]
207
208 if scheme == "https":
209 return UI.PixmapCache.getIcon("securityHigh32")
210 else:
211 return UI.PixmapCache.getIcon("defaultIcon")
212
213 def clear(self):
214 """
215 Public method to clear the icons cache.
216 """
217 self.load()
218 self.__iconsDB = {}
219 self.changed.emit()
220 self.__saveTimer.saveIfNeccessary()
221
222 def showWebIconDialog(self):
223 """
224 Public method to show a dialog to manage the Favicons.
225 """
226 self.load()
227
228 from .WebIconDialog import WebIconDialog
229 dlg = WebIconDialog(self.__iconsDB)
230 if dlg.exec() == QDialog.DialogCode.Accepted:
231 changed = False
232 urls = dlg.getUrls()
233 for url in list(self.__iconsDB.keys())[:]:
234 if url not in urls:
235 del self.__iconsDB[url]
236 changed = True
237 if changed:
238 self.changed.emit()
239
240
241 _WebIconProvider = None
242
243
244 def instance():
245 """
246 Global function to get a reference to the web icon provider and create it,
247 if it hasn't been yet.
248
249 @return reference to the web icon provider object
250 @rtype WebIconProvider
251 """
252 global _WebIconProvider
253
254 if _WebIconProvider is None:
255 _WebIconProvider = WebIconProvider()
256
257 return _WebIconProvider

eric ide

mercurial