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

eric ide

mercurial