src/eric7/WebBrowser/SafeBrowsing/SafeBrowsingDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
6 """ 6 """
7 Module implementing a dialog to configure safe browsing support. 7 Module implementing a dialog to configure safe browsing support.
8 """ 8 """
9 9
10 from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QDateTime 10 from PyQt6.QtCore import pyqtSlot, Qt, QUrl, QDateTime
11 from PyQt6.QtWidgets import ( 11 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton
12 QDialog, QDialogButtonBox, QAbstractButton
13 )
14 12
15 from EricWidgets import EricMessageBox 13 from EricWidgets import EricMessageBox
16 from EricGui.EricOverrideCursor import EricOverrideCursor 14 from EricGui.EricOverrideCursor import EricOverrideCursor
17 15
18 from .Ui_SafeBrowsingDialog import Ui_SafeBrowsingDialog 16 from .Ui_SafeBrowsingDialog import Ui_SafeBrowsingDialog
23 21
24 class SafeBrowsingDialog(QDialog, Ui_SafeBrowsingDialog): 22 class SafeBrowsingDialog(QDialog, Ui_SafeBrowsingDialog):
25 """ 23 """
26 Class implementing a dialog to configure safe browsing support. 24 Class implementing a dialog to configure safe browsing support.
27 """ 25 """
26
28 def __init__(self, manager, parent=None): 27 def __init__(self, manager, parent=None):
29 """ 28 """
30 Constructor 29 Constructor
31 30
32 @param manager reference to the safe browsing manager 31 @param manager reference to the safe browsing manager
33 @type SafeBrowsingManager 32 @type SafeBrowsingManager
34 @param parent reference to the parent widget 33 @param parent reference to the parent widget
35 @type QWidget 34 @type QWidget
36 """ 35 """
37 super().__init__(parent) 36 super().__init__(parent)
38 self.setupUi(self) 37 self.setupUi(self)
39 self.setWindowFlags(Qt.WindowType.Window) 38 self.setWindowFlags(Qt.WindowType.Window)
40 39
41 self.__manager = manager 40 self.__manager = manager
42 self.__manager.progressMessage.connect(self.__setProgressMessage) 41 self.__manager.progressMessage.connect(self.__setProgressMessage)
43 self.__manager.progress.connect(self.__setProgress) 42 self.__manager.progress.connect(self.__setProgress)
44 43
45 self.iconLabel.setPixmap( 44 self.iconLabel.setPixmap(UI.PixmapCache.getPixmap("safeBrowsing48"))
46 UI.PixmapCache.getPixmap("safeBrowsing48")) 45
47
48 self.__gsbHelpDialog = None 46 self.__gsbHelpDialog = None
49 47
50 self.__enabled = Preferences.getWebBrowser("SafeBrowsingEnabled") 48 self.__enabled = Preferences.getWebBrowser("SafeBrowsingEnabled")
51 self.__apiKey = Preferences.getWebBrowser("SafeBrowsingApiKey") 49 self.__apiKey = Preferences.getWebBrowser("SafeBrowsingApiKey")
52 self.__filterPlatform = Preferences.getWebBrowser( 50 self.__filterPlatform = Preferences.getWebBrowser("SafeBrowsingFilterPlatform")
53 "SafeBrowsingFilterPlatform") 51 self.__automaticUpdate = Preferences.getWebBrowser("SafeBrowsingAutoUpdate")
54 self.__automaticUpdate = Preferences.getWebBrowser( 52 self.__useLookupApi = Preferences.getWebBrowser("SafeBrowsingUseLookupApi")
55 "SafeBrowsingAutoUpdate") 53
56 self.__useLookupApi = Preferences.getWebBrowser(
57 "SafeBrowsingUseLookupApi")
58
59 self.buttonBox.setFocus() 54 self.buttonBox.setFocus()
60 55
61 msh = self.minimumSizeHint() 56 msh = self.minimumSizeHint()
62 self.resize(max(self.width(), msh.width()), msh.height()) 57 self.resize(max(self.width(), msh.width()), msh.height())
63 58
64 def show(self): 59 def show(self):
65 """ 60 """
66 Public slot to show the dialog. 61 Public slot to show the dialog.
67 """ 62 """
68 self.gsbGroupBox.setChecked(self.__enabled) 63 self.gsbGroupBox.setChecked(self.__enabled)
69 self.gsbApiKeyEdit.setText(self.__apiKey) 64 self.gsbApiKeyEdit.setText(self.__apiKey)
70 self.gsbFilterPlatformCheckBox.setChecked(self.__filterPlatform) 65 self.gsbFilterPlatformCheckBox.setChecked(self.__filterPlatform)
71 self.gsbAutoUpdateCheckBox.setChecked(self.__automaticUpdate) 66 self.gsbAutoUpdateCheckBox.setChecked(self.__automaticUpdate)
72 self.gsbLookupCheckBox.setChecked(self.__useLookupApi) 67 self.gsbLookupCheckBox.setChecked(self.__useLookupApi)
73 68
74 self.__updateCacheButtons() 69 self.__updateCacheButtons()
75 70
76 super().show() 71 super().show()
77 72
78 @pyqtSlot() 73 @pyqtSlot()
79 def on_gsbHelpButton_clicked(self): 74 def on_gsbHelpButton_clicked(self):
80 """ 75 """
81 Private slot to show some help text "How to create a safe 76 Private slot to show some help text "How to create a safe
82 browsing API key.". 77 browsing API key.".
83 """ 78 """
84 if self.__gsbHelpDialog is None: 79 if self.__gsbHelpDialog is None:
85 from EricWidgets.EricSimpleHelpDialog import EricSimpleHelpDialog 80 from EricWidgets.EricSimpleHelpDialog import EricSimpleHelpDialog
86 from . import SafeBrowsingHelp 81 from . import SafeBrowsingHelp
87 82
88 helpStr = SafeBrowsingHelp() 83 helpStr = SafeBrowsingHelp()
89 self.__gsbHelpDialog = EricSimpleHelpDialog( 84 self.__gsbHelpDialog = EricSimpleHelpDialog(
90 title=self.tr("Google Safe Browsing API Help"), 85 title=self.tr("Google Safe Browsing API Help"),
91 helpStr=helpStr, parent=self) 86 helpStr=helpStr,
92 87 parent=self,
88 )
89
93 self.__gsbHelpDialog.show() 90 self.__gsbHelpDialog.show()
94 91
95 @pyqtSlot(QAbstractButton) 92 @pyqtSlot(QAbstractButton)
96 def on_buttonBox_clicked(self, button): 93 def on_buttonBox_clicked(self, button):
97 """ 94 """
98 Private slot called by a button of the button box clicked. 95 Private slot called by a button of the button box clicked.
99 96
100 @param button button that was clicked (QAbstractButton) 97 @param button button that was clicked (QAbstractButton)
101 """ 98 """
102 if button == self.buttonBox.button( 99 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
103 QDialogButtonBox.StandardButton.Close
104 ):
105 self.close() 100 self.close()
106 101
107 @pyqtSlot() 102 @pyqtSlot()
108 def __save(self): 103 def __save(self):
109 """ 104 """
110 Private slot to save the configuration. 105 Private slot to save the configuration.
111 106
112 @return flag indicating success 107 @return flag indicating success
113 @rtype bool 108 @rtype bool
114 """ 109 """
115 self.__enabled = self.gsbGroupBox.isChecked() 110 self.__enabled = self.gsbGroupBox.isChecked()
116 self.__apiKey = self.gsbApiKeyEdit.text() 111 self.__apiKey = self.gsbApiKeyEdit.text()
117 self.__filterPlatform = self.gsbFilterPlatformCheckBox.isChecked() 112 self.__filterPlatform = self.gsbFilterPlatformCheckBox.isChecked()
118 self.__automaticUpdate = self.gsbAutoUpdateCheckBox.isChecked() 113 self.__automaticUpdate = self.gsbAutoUpdateCheckBox.isChecked()
119 self.__useLookupApi = self.gsbLookupCheckBox.isChecked() 114 self.__useLookupApi = self.gsbLookupCheckBox.isChecked()
120 115
121 Preferences.setWebBrowser("SafeBrowsingEnabled", self.__enabled) 116 Preferences.setWebBrowser("SafeBrowsingEnabled", self.__enabled)
122 Preferences.setWebBrowser("SafeBrowsingApiKey", self.__apiKey) 117 Preferences.setWebBrowser("SafeBrowsingApiKey", self.__apiKey)
123 Preferences.setWebBrowser("SafeBrowsingFilterPlatform", 118 Preferences.setWebBrowser("SafeBrowsingFilterPlatform", self.__filterPlatform)
124 self.__filterPlatform) 119 Preferences.setWebBrowser("SafeBrowsingAutoUpdate", self.__automaticUpdate)
125 Preferences.setWebBrowser("SafeBrowsingAutoUpdate", 120 Preferences.setWebBrowser("SafeBrowsingUseLookupApi", self.__useLookupApi)
126 self.__automaticUpdate) 121
127 Preferences.setWebBrowser("SafeBrowsingUseLookupApi",
128 self.__useLookupApi)
129
130 self.__manager.configurationChanged() 122 self.__manager.configurationChanged()
131 123
132 self.__updateCacheButtons() 124 self.__updateCacheButtons()
133 125
134 return True 126 return True
135 127
136 def closeEvent(self, evt): 128 def closeEvent(self, evt):
137 """ 129 """
138 Protected method to handle close events. 130 Protected method to handle close events.
139 131
140 @param evt reference to the close event 132 @param evt reference to the close event
141 @type QCloseEvent 133 @type QCloseEvent
142 """ 134 """
143 if self.__okToClose(): 135 if self.__okToClose():
144 evt.accept() 136 evt.accept()
145 else: 137 else:
146 evt.ignore() 138 evt.ignore()
147 139
148 def __isModified(self): 140 def __isModified(self):
149 """ 141 """
150 Private method to check, if the dialog contains modified data. 142 Private method to check, if the dialog contains modified data.
151 143
152 @return flag indicating the presence of modified data 144 @return flag indicating the presence of modified data
153 @rtype bool 145 @rtype bool
154 """ 146 """
155 return ( 147 return (
156 (self.__enabled != self.gsbGroupBox.isChecked()) or 148 (self.__enabled != self.gsbGroupBox.isChecked())
157 (self.__apiKey != self.gsbApiKeyEdit.text()) or 149 or (self.__apiKey != self.gsbApiKeyEdit.text())
158 (self.__filterPlatform != 150 or (self.__filterPlatform != self.gsbFilterPlatformCheckBox.isChecked())
159 self.gsbFilterPlatformCheckBox.isChecked()) or 151 or (self.__automaticUpdate != self.gsbAutoUpdateCheckBox.isChecked())
160 (self.__automaticUpdate != 152 or (self.__useLookupApi != self.gsbLookupCheckBox.isChecked())
161 self.gsbAutoUpdateCheckBox.isChecked()) or 153 )
162 (self.__useLookupApi != self.gsbLookupCheckBox.isChecked()) 154
163 )
164
165 def __okToClose(self): 155 def __okToClose(self):
166 """ 156 """
167 Private method to check, if it is safe to close the dialog. 157 Private method to check, if it is safe to close the dialog.
168 158
169 @return flag indicating safe to close 159 @return flag indicating safe to close
170 @rtype bool 160 @rtype bool
171 """ 161 """
172 if self.__isModified(): 162 if self.__isModified():
173 res = EricMessageBox.okToClearData( 163 res = EricMessageBox.okToClearData(
174 self, 164 self,
175 self.tr("Safe Browsing Management"), 165 self.tr("Safe Browsing Management"),
176 self.tr("""The dialog contains unsaved changes."""), 166 self.tr("""The dialog contains unsaved changes."""),
177 self.__save) 167 self.__save,
168 )
178 if not res: 169 if not res:
179 return False 170 return False
180 return True 171 return True
181 172
182 def __updateCacheButtons(self): 173 def __updateCacheButtons(self):
183 """ 174 """
184 Private method to set enabled state of the cache buttons. 175 Private method to set enabled state of the cache buttons.
185 """ 176 """
186 enable = self.__enabled and bool(self.__apiKey) 177 enable = self.__enabled and bool(self.__apiKey)
187 178
188 self.updateCacheButton.setEnabled(enable) 179 self.updateCacheButton.setEnabled(enable)
189 self.clearCacheButton.setEnabled(enable) 180 self.clearCacheButton.setEnabled(enable)
190 181
191 self.showUpdateTimeButton.setEnabled(enable and self.__automaticUpdate) 182 self.showUpdateTimeButton.setEnabled(enable and self.__automaticUpdate)
192 183
193 @pyqtSlot() 184 @pyqtSlot()
194 def on_updateCacheButton_clicked(self): 185 def on_updateCacheButton_clicked(self):
195 """ 186 """
196 Private slot to update the local cache database. 187 Private slot to update the local cache database.
197 """ 188 """
198 EricMessageBox.information( 189 EricMessageBox.information(
199 self, 190 self,
200 self.tr("Update Safe Browsing Cache"), 191 self.tr("Update Safe Browsing Cache"),
201 self.tr("""Updating the Safe Browsing cache might be a lengthy""" 192 self.tr(
202 """ operation. Please be patient!""")) 193 """Updating the Safe Browsing cache might be a lengthy"""
203 194 """ operation. Please be patient!"""
195 ),
196 )
197
204 with EricOverrideCursor(): 198 with EricOverrideCursor():
205 ok, error = self.__manager.updateHashPrefixCache() 199 ok, error = self.__manager.updateHashPrefixCache()
206 self.__resetProgress() 200 self.__resetProgress()
207 if not ok: 201 if not ok:
208 if error: 202 if error:
209 EricMessageBox.critical( 203 EricMessageBox.critical(
210 self, 204 self,
211 self.tr("Update Safe Browsing Cache"), 205 self.tr("Update Safe Browsing Cache"),
212 self.tr("""<p>Updating the Safe Browsing cache failed.""" 206 self.tr(
213 """</p><p>Reason: {0}</p>""").format(error)) 207 """<p>Updating the Safe Browsing cache failed."""
208 """</p><p>Reason: {0}</p>"""
209 ).format(error),
210 )
214 else: 211 else:
215 EricMessageBox.critical( 212 EricMessageBox.critical(
216 self, 213 self,
217 self.tr("Update Safe Browsing Cache"), 214 self.tr("Update Safe Browsing Cache"),
218 self.tr("""<p>Updating the Safe Browsing cache failed.""" 215 self.tr(
219 """</p>""")) 216 """<p>Updating the Safe Browsing cache failed.""" """</p>"""
220 217 ),
218 )
219
221 @pyqtSlot() 220 @pyqtSlot()
222 def on_clearCacheButton_clicked(self): 221 def on_clearCacheButton_clicked(self):
223 """ 222 """
224 Private slot to clear the local cache database. 223 Private slot to clear the local cache database.
225 """ 224 """
226 res = EricMessageBox.yesNo( 225 res = EricMessageBox.yesNo(
227 self, 226 self,
228 self.tr("Clear Safe Browsing Cache"), 227 self.tr("Clear Safe Browsing Cache"),
229 self.tr("""Do you really want to clear the Safe Browsing cache?""" 228 self.tr(
230 """ Re-populating it might take some time.""")) 229 """Do you really want to clear the Safe Browsing cache?"""
230 """ Re-populating it might take some time."""
231 ),
232 )
231 if res: 233 if res:
232 with EricOverrideCursor(): 234 with EricOverrideCursor():
233 self.__manager.fullCacheCleanup() 235 self.__manager.fullCacheCleanup()
234 236
235 @pyqtSlot(str, int) 237 @pyqtSlot(str, int)
236 def __setProgressMessage(self, message, maximum): 238 def __setProgressMessage(self, message, maximum):
237 """ 239 """
238 Private slot to set the progress message and the maximum value. 240 Private slot to set the progress message and the maximum value.
239 241
240 @param message progress message to be set 242 @param message progress message to be set
241 @type str 243 @type str
242 @param maximum maximum value to be set 244 @param maximum maximum value to be set
243 @type int 245 @type int
244 """ 246 """
245 self.progressLabel.setText(message) 247 self.progressLabel.setText(message)
246 self.progressBar.setMaximum(maximum) 248 self.progressBar.setMaximum(maximum)
247 self.progressBar.setValue(0) 249 self.progressBar.setValue(0)
248 250
249 @pyqtSlot(int) 251 @pyqtSlot(int)
250 def __setProgress(self, value): 252 def __setProgress(self, value):
251 """ 253 """
252 Private slot to set the progress value. 254 Private slot to set the progress value.
253 255
254 @param value progress value to be set 256 @param value progress value to be set
255 @type int 257 @type int
256 """ 258 """
257 if bool(self.progressLabel.text()): 259 if bool(self.progressLabel.text()):
258 self.progressBar.setValue(value) 260 self.progressBar.setValue(value)
259 261
260 def __resetProgress(self): 262 def __resetProgress(self):
261 """ 263 """
262 Private method to reset the progress info. 264 Private method to reset the progress info.
263 """ 265 """
264 self.progressLabel.clear() 266 self.progressLabel.clear()
265 self.progressBar.setMaximum(100) 267 self.progressBar.setMaximum(100)
266 self.progressBar.setValue(0) 268 self.progressBar.setValue(0)
267 269
268 @pyqtSlot(str) 270 @pyqtSlot(str)
269 def on_urlEdit_textChanged(self, text): 271 def on_urlEdit_textChanged(self, text):
270 """ 272 """
271 Private slot to handle changes of the entered URL text. 273 Private slot to handle changes of the entered URL text.
272 274
273 @param text entered URL text 275 @param text entered URL text
274 @type str 276 @type str
275 """ 277 """
276 url = QUrl.fromUserInput(text) 278 url = QUrl.fromUserInput(text)
277 enable = ( 279 enable = (
278 url.isValid() and 280 url.isValid()
279 bool(url.scheme()) and 281 and bool(url.scheme())
280 url.scheme() not in self.__manager.getIgnoreSchemes() 282 and url.scheme() not in self.__manager.getIgnoreSchemes()
281 ) 283 )
282 self.urlCheckButton.setEnabled(enable) 284 self.urlCheckButton.setEnabled(enable)
283 285
284 @pyqtSlot() 286 @pyqtSlot()
285 def on_urlCheckButton_clicked(self): 287 def on_urlCheckButton_clicked(self):
286 """ 288 """
287 Private slot to check the entered URL. 289 Private slot to check the entered URL.
288 """ 290 """
291 # http://ianfette.org 293 # http://ianfette.org
292 # 294 #
293 urlStr = self.urlEdit.text() 295 urlStr = self.urlEdit.text()
294 url = QUrl.fromUserInput(urlStr) 296 url = QUrl.fromUserInput(urlStr)
295 threatLists, error = self.__manager.lookupUrl(url) 297 threatLists, error = self.__manager.lookupUrl(url)
296 298
297 if error: 299 if error:
298 EricMessageBox.warning( 300 EricMessageBox.warning(
299 self, 301 self,
300 self.tr("Check URL"), 302 self.tr("Check URL"),
301 self.tr("<p>The Google Safe Browsing Server reported an" 303 self.tr(
302 " error.</p><p>{0}</p>").format(error) 304 "<p>The Google Safe Browsing Server reported an"
305 " error.</p><p>{0}</p>"
306 ).format(error),
303 ) 307 )
304 elif threatLists: 308 elif threatLists:
305 threatMessages = self.__manager.getThreatMessages(threatLists) 309 threatMessages = self.__manager.getThreatMessages(threatLists)
306 EricMessageBox.warning( 310 EricMessageBox.warning(
307 self, 311 self,
308 self.tr("Check URL"), 312 self.tr("Check URL"),
309 self.tr("<p>The URL <b>{0}</b> was found in the Safe" 313 self.tr(
310 " Browsing Database.</p>{1}").format( 314 "<p>The URL <b>{0}</b> was found in the Safe"
311 urlStr, "".join(threatMessages)) 315 " Browsing Database.</p>{1}"
316 ).format(urlStr, "".join(threatMessages)),
312 ) 317 )
313 else: 318 else:
314 EricMessageBox.information( 319 EricMessageBox.information(
315 self, 320 self,
316 self.tr("Check URL"), 321 self.tr("Check URL"),
317 self.tr("<p>The URL <b>{0}</b> was not found in the Safe" 322 self.tr(
318 " Browsing Database and may be considered safe." 323 "<p>The URL <b>{0}</b> was not found in the Safe"
319 "</p>") 324 " Browsing Database and may be considered safe."
320 .format(urlStr) 325 "</p>"
321 ) 326 ).format(urlStr),
322 327 )
328
323 @pyqtSlot() 329 @pyqtSlot()
324 def on_saveButton_clicked(self): 330 def on_saveButton_clicked(self):
325 """ 331 """
326 Private slot to save the configuration data. 332 Private slot to save the configuration data.
327 """ 333 """
328 self.__save() 334 self.__save()
329 335
330 @pyqtSlot() 336 @pyqtSlot()
331 def on_showUpdateTimeButton_clicked(self): 337 def on_showUpdateTimeButton_clicked(self):
332 """ 338 """
333 Private slot to show the time of the next automatic threat list update. 339 Private slot to show the time of the next automatic threat list update.
334 """ 340 """
335 nextUpdateDateTime = Preferences.getWebBrowser( 341 nextUpdateDateTime = Preferences.getWebBrowser("SafeBrowsingUpdateDateTime")
336 "SafeBrowsingUpdateDateTime")
337 message = ( 342 message = (
338 self.tr("The next automatic threat list update will be done now.") 343 self.tr("The next automatic threat list update will be done now.")
339 if (not nextUpdateDateTime.isValid() or 344 if (
340 nextUpdateDateTime <= QDateTime.currentDateTime()) else 345 not nextUpdateDateTime.isValid()
341 self.tr("<p>The next automatic threat list update will be done at" 346 or nextUpdateDateTime <= QDateTime.currentDateTime()
342 " <b>{0}</b>.</p>").format( 347 )
343 nextUpdateDateTime.toString("yyyy-MM-dd, HH:mm:ss")) 348 else self.tr(
344 ) 349 "<p>The next automatic threat list update will be done at"
345 350 " <b>{0}</b>.</p>"
346 EricMessageBox.information( 351 ).format(nextUpdateDateTime.toString("yyyy-MM-dd, HH:mm:ss"))
347 self, 352 )
348 self.tr("Update Time"), 353
349 message) 354 EricMessageBox.information(self, self.tr("Update Time"), message)

eric ide

mercurial