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) |