1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2015 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to manage the flash cookies. |
|
8 """ |
|
9 |
|
10 from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QTimer |
|
11 from PyQt5.QtWidgets import ( |
|
12 QDialog, QTreeWidgetItem, QApplication, QMenu, QInputDialog, QLineEdit |
|
13 ) |
|
14 |
|
15 from E5Gui import E5MessageBox |
|
16 from E5Gui.E5OverrideCursor import E5OverrideCursor |
|
17 |
|
18 from .Ui_FlashCookieManagerDialog import Ui_FlashCookieManagerDialog |
|
19 |
|
20 import Preferences |
|
21 import UI.PixmapCache |
|
22 |
|
23 |
|
24 class FlashCookieManagerDialog(QDialog, Ui_FlashCookieManagerDialog): |
|
25 """ |
|
26 Class implementing a dialog to manage the flash cookies. |
|
27 """ |
|
28 def __init__(self, manager, parent=None): |
|
29 """ |
|
30 Constructor |
|
31 |
|
32 @param manager reference to the Flash cookie manager object |
|
33 @type FlashCookieManager |
|
34 @param parent reference to the parent widget |
|
35 @type QWidget |
|
36 """ |
|
37 super(FlashCookieManagerDialog, self).__init__(parent) |
|
38 self.setupUi(self) |
|
39 self.setWindowFlags(Qt.Window) |
|
40 |
|
41 self.cookiesList.setContextMenuPolicy(Qt.CustomContextMenu) |
|
42 self.cookiesList.customContextMenuRequested.connect( |
|
43 self.__cookiesListContextMenuRequested) |
|
44 |
|
45 self.__manager = manager |
|
46 |
|
47 @pyqtSlot() |
|
48 def on_whiteList_itemSelectionChanged(self): |
|
49 """ |
|
50 Private slot handling the selection of items in the whitelist. |
|
51 """ |
|
52 enable = len(self.whiteList.selectedItems()) > 0 |
|
53 self.removeWhiteButton.setEnabled(enable) |
|
54 |
|
55 @pyqtSlot() |
|
56 def on_blackList_itemSelectionChanged(self): |
|
57 """ |
|
58 Private slot handling the selection of items in the blacklist. |
|
59 """ |
|
60 enable = len(self.blackList.selectedItems()) > 0 |
|
61 self.removeBlackButton.setEnabled(enable) |
|
62 |
|
63 @pyqtSlot() |
|
64 def on_removeWhiteButton_clicked(self): |
|
65 """ |
|
66 Private slot to remove a server from the whitelist. |
|
67 """ |
|
68 for itm in self.whiteList.selectedItems(): |
|
69 row = self.whiteList.row(itm) |
|
70 self.whiteList.takeItem(row) |
|
71 del itm |
|
72 |
|
73 @pyqtSlot() |
|
74 def on_addWhiteButton_clicked(self): |
|
75 """ |
|
76 Private slot to add a server to the whitelist. |
|
77 """ |
|
78 origin, ok = QInputDialog.getText( |
|
79 self, |
|
80 self.tr("Add to whitelist"), |
|
81 self.tr("Origin:"), |
|
82 QLineEdit.Normal) |
|
83 if ok and bool(origin): |
|
84 self.__addWhitelist(origin) |
|
85 |
|
86 def __addWhitelist(self, origin): |
|
87 """ |
|
88 Private method to add a cookie origin to the whitelist. |
|
89 |
|
90 @param origin origin to be added to the list |
|
91 @type str |
|
92 """ |
|
93 if not origin: |
|
94 return |
|
95 |
|
96 if len(self.blackList.findItems(origin, Qt.MatchFixedString)) > 0: |
|
97 E5MessageBox.information( |
|
98 self, |
|
99 self.tr("Add to whitelist"), |
|
100 self.tr("""The server '{0}' is already in the blacklist.""" |
|
101 """ Please remove it first.""").format(origin)) |
|
102 return |
|
103 |
|
104 if len(self.whiteList.findItems(origin, Qt.MatchFixedString)) == 0: |
|
105 self.whiteList.addItem(origin) |
|
106 |
|
107 @pyqtSlot() |
|
108 def on_removeBlackButton_clicked(self): |
|
109 """ |
|
110 Private slot to remove a server from the blacklist. |
|
111 """ |
|
112 for itm in self.blackList.selectedItems(): |
|
113 row = self.blackList.row(itm) |
|
114 self.blackList.takeItem(row) |
|
115 del itm |
|
116 |
|
117 @pyqtSlot() |
|
118 def on_addBlackButton_clicked(self): |
|
119 """ |
|
120 Private slot to add a server to the blacklist. |
|
121 """ |
|
122 origin, ok = QInputDialog.getText( |
|
123 self, |
|
124 self.tr("Add to blacklist"), |
|
125 self.tr("Origin:"), |
|
126 QLineEdit.Normal) |
|
127 if ok and bool(origin): |
|
128 self.__addBlacklist(origin) |
|
129 |
|
130 def __addBlacklist(self, origin): |
|
131 """ |
|
132 Private method to add a cookie origin to the blacklist. |
|
133 |
|
134 @param origin origin to be added to the list |
|
135 @type str |
|
136 """ |
|
137 if not origin: |
|
138 return |
|
139 |
|
140 if len(self.whiteList.findItems(origin, Qt.MatchFixedString)) > 0: |
|
141 E5MessageBox.information( |
|
142 self, |
|
143 self.tr("Add to blacklist"), |
|
144 self.tr("""The server '{0}' is already in the whitelist.""" |
|
145 """ Please remove it first.""").format(origin)) |
|
146 return |
|
147 |
|
148 if len(self.blackList.findItems(origin, Qt.MatchFixedString)) == 0: |
|
149 self.blackList.addItem(origin) |
|
150 |
|
151 @pyqtSlot(str) |
|
152 def on_filterEdit_textChanged(self, filterStr): |
|
153 """ |
|
154 Private slot to filter the cookies list. |
|
155 |
|
156 @param filterStr filter text |
|
157 @type str |
|
158 """ |
|
159 if not filterStr: |
|
160 # show all in collapsed state |
|
161 for index in range(self.cookiesList.topLevelItemCount()): |
|
162 self.cookiesList.topLevelItem(index).setHidden(False) |
|
163 self.cookiesList.topLevelItem(index).setExpanded(False) |
|
164 else: |
|
165 # show matching in expanded state |
|
166 filterStr = filterStr.lower() |
|
167 for index in range(self.cookiesList.topLevelItemCount()): |
|
168 txt = ( |
|
169 "." + |
|
170 self.cookiesList.topLevelItem(index).text(0).lower() |
|
171 ) |
|
172 self.cookiesList.topLevelItem(index).setHidden( |
|
173 filterStr not in txt) |
|
174 self.cookiesList.topLevelItem(index).setExpanded(True) |
|
175 |
|
176 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
|
177 def on_cookiesList_currentItemChanged(self, current, previous): |
|
178 """ |
|
179 Private slot handling a change of the current cookie item. |
|
180 |
|
181 @param current reference to the current item |
|
182 @type QTreeWidgetItem |
|
183 @param previous reference to the previous item |
|
184 @type QTreeWidgetItem |
|
185 """ |
|
186 if current is None: |
|
187 self.removeButton.setEnabled(False) |
|
188 return |
|
189 |
|
190 cookie = current.data(0, Qt.UserRole) |
|
191 if cookie is None: |
|
192 self.nameLabel.setText(self.tr("<no flash cookie selected>")) |
|
193 self.sizeLabel.setText(self.tr("<no flash cookie selected>")) |
|
194 self.originLabel.setText(self.tr("<no flash cookie selected>")) |
|
195 self.modifiedLabel.setText(self.tr("<no flash cookie selected>")) |
|
196 self.contentsEdit.clear() |
|
197 self.pathEdit.clear() |
|
198 self.removeButton.setText(self.tr("Remove Cookie Group")) |
|
199 else: |
|
200 suffix = "" |
|
201 if cookie.path.startswith( |
|
202 self.__manager.flashPlayerDataPath() + |
|
203 "/macromedia.com/support/flashplayer/sys"): |
|
204 suffix = self.tr(" (settings)") |
|
205 self.nameLabel.setText( |
|
206 self.tr("{0}{1}", "name and suffix") |
|
207 .format(cookie.name, suffix)) |
|
208 self.sizeLabel.setText(self.tr("{0} Byte").format(cookie.size)) |
|
209 self.originLabel.setText(cookie.origin) |
|
210 self.modifiedLabel.setText( |
|
211 cookie.lastModified.toString("yyyy-MM-dd hh:mm:ss")) |
|
212 self.contentsEdit.setPlainText(cookie.contents) |
|
213 self.pathEdit.setText(cookie.path) |
|
214 self.removeButton.setText(self.tr("Remove Cookie")) |
|
215 self.removeButton.setEnabled(True) |
|
216 |
|
217 @pyqtSlot(QPoint) |
|
218 def __cookiesListContextMenuRequested(self, pos): |
|
219 """ |
|
220 Private slot handling the cookies list context menu. |
|
221 |
|
222 @param pos position to show the menu at |
|
223 @type QPoint |
|
224 """ |
|
225 itm = self.cookiesList.itemAt(pos) |
|
226 if itm is None: |
|
227 return |
|
228 |
|
229 menu = QMenu() |
|
230 addBlacklistAct = menu.addAction(self.tr("Add to blacklist")) |
|
231 addWhitelistAct = menu.addAction(self.tr("Add to whitelist")) |
|
232 |
|
233 self.cookiesList.setCurrentItem(itm) |
|
234 |
|
235 activatedAction = menu.exec( |
|
236 self.cookiesList.viewport().mapToGlobal(pos)) |
|
237 if itm.childCount() == 0: |
|
238 origin = itm.data(0, Qt.UserRole).origin |
|
239 else: |
|
240 origin = itm.text(0) |
|
241 |
|
242 if activatedAction == addBlacklistAct: |
|
243 self.__addBlacklist(origin) |
|
244 elif activatedAction == addWhitelistAct: |
|
245 self.__addWhitelist(origin) |
|
246 |
|
247 @pyqtSlot() |
|
248 def on_reloadButton_clicked(self): |
|
249 """ |
|
250 Private slot handling a press of the reload button. |
|
251 """ |
|
252 self.refreshView(True) |
|
253 |
|
254 @pyqtSlot() |
|
255 def on_removeAllButton_clicked(self): |
|
256 """ |
|
257 Private slot to remove all cookies. |
|
258 """ |
|
259 ok = E5MessageBox.yesNo( |
|
260 self, |
|
261 self.tr("Remove All"), |
|
262 self.tr("""Do you really want to delete all flash cookies on""" |
|
263 """ your computer?""")) |
|
264 if ok: |
|
265 cookies = self.__manager.flashCookies() |
|
266 for cookie in cookies: |
|
267 self.__manager.removeCookie(cookie) |
|
268 |
|
269 self.cookiesList.clear() |
|
270 self.__manager.clearNewOrigins() |
|
271 self.__manager.clearCache() |
|
272 |
|
273 @pyqtSlot() |
|
274 def on_removeButton_clicked(self): |
|
275 """ |
|
276 Private slot to remove one cookie or a cookie group. |
|
277 """ |
|
278 itm = self.cookiesList.currentItem() |
|
279 if itm is None: |
|
280 return |
|
281 |
|
282 cookie = itm.data(0, Qt.UserRole) |
|
283 if cookie is None: |
|
284 # remove a whole cookie group |
|
285 origin = itm.text(0) |
|
286 cookieList = self.__manager.flashCookies() |
|
287 for fcookie in cookieList: |
|
288 if fcookie.origin == origin: |
|
289 self.__manager.removeCookie(fcookie) |
|
290 |
|
291 index = self.cookiesList.indexOfTopLevelItem(itm) |
|
292 self.cookiesList.takeTopLevelItem(index) |
|
293 else: |
|
294 self.__manager.removeCookie(cookie) |
|
295 parent = itm.parent() |
|
296 index = parent.indexOfChild(itm) |
|
297 parent.takeChild(index) |
|
298 |
|
299 if parent.childCount() == 0: |
|
300 # remove origin item as well |
|
301 index = self.cookiesList.indexOfTopLevelItem(parent) |
|
302 self.cookiesList.takeTopLevelItem(index) |
|
303 del parent |
|
304 del itm |
|
305 |
|
306 def refreshView(self, forceReload=False): |
|
307 """ |
|
308 Public method to refresh the dialog view. |
|
309 |
|
310 @param forceReload flag indicating to reload the cookies |
|
311 @type bool |
|
312 """ |
|
313 blocked = self.filterEdit.blockSignals(True) |
|
314 self.filterEdit.clear() |
|
315 self.contentsEdit.clear() |
|
316 self.filterEdit.blockSignals(blocked) |
|
317 |
|
318 if forceReload: |
|
319 self.__manager.clearCache() |
|
320 self.__manager.clearNewOrigins() |
|
321 |
|
322 QTimer.singleShot(0, self.__refreshCookiesList) |
|
323 QTimer.singleShot(0, self.__refreshFilterLists) |
|
324 |
|
325 def showPage(self, index): |
|
326 """ |
|
327 Public method to display a given page. |
|
328 |
|
329 @param index index of the page to be shown |
|
330 @type int |
|
331 """ |
|
332 self.cookiesTabWidget.setCurrentIndex(index) |
|
333 |
|
334 @pyqtSlot() |
|
335 def __refreshCookiesList(self): |
|
336 """ |
|
337 Private slot to refresh the cookies list. |
|
338 """ |
|
339 with E5OverrideCursor(): |
|
340 cookies = self.__manager.flashCookies() |
|
341 self.cookiesList.clear() |
|
342 |
|
343 counter = 0 |
|
344 originDict = {} |
|
345 for cookie in cookies: |
|
346 cookieOrigin = cookie.origin |
|
347 if cookieOrigin.startswith("."): |
|
348 cookieOrigin = cookieOrigin[1:] |
|
349 |
|
350 if cookieOrigin in originDict: |
|
351 itm = QTreeWidgetItem(originDict[cookieOrigin]) |
|
352 else: |
|
353 newParent = QTreeWidgetItem(self.cookiesList) |
|
354 newParent.setText(0, cookieOrigin) |
|
355 newParent.setIcon(0, UI.PixmapCache.getIcon("dirOpen")) |
|
356 self.cookiesList.addTopLevelItem(newParent) |
|
357 originDict[cookieOrigin] = newParent |
|
358 |
|
359 itm = QTreeWidgetItem(newParent) |
|
360 |
|
361 suffix = "" |
|
362 if cookie.path.startswith( |
|
363 self.__manager.flashPlayerDataPath() + |
|
364 "/macromedia.com/support/flashplayer/sys"): |
|
365 suffix = self.tr(" (settings)") |
|
366 |
|
367 if cookie.path + "/" + cookie.name in ( |
|
368 self.__manager.newCookiesList() |
|
369 ): |
|
370 suffix += self.tr(" [new]") |
|
371 font = itm.font(0) |
|
372 font.setBold(True) |
|
373 itm.setFont(font) |
|
374 itm.parent().setExpanded(True) |
|
375 |
|
376 itm.setText(0, self.tr("{0}{1}", "name and suffix").format( |
|
377 cookie.name, suffix)) |
|
378 itm.setData(0, Qt.UserRole, cookie) |
|
379 |
|
380 counter += 1 |
|
381 if counter > 100: |
|
382 QApplication.processEvents() |
|
383 counter = 0 |
|
384 |
|
385 self.removeAllButton.setEnabled( |
|
386 self.cookiesList.topLevelItemCount() > 0) |
|
387 self.removeButton.setEnabled(False) |
|
388 |
|
389 @pyqtSlot() |
|
390 def __refreshFilterLists(self): |
|
391 """ |
|
392 Private slot to refresh the white and black lists. |
|
393 """ |
|
394 self.whiteList.clear() |
|
395 self.blackList.clear() |
|
396 |
|
397 self.whiteList.addItems( |
|
398 Preferences.getWebBrowser("FlashCookiesWhitelist")) |
|
399 self.blackList.addItems( |
|
400 Preferences.getWebBrowser("FlashCookiesBlacklist")) |
|
401 |
|
402 self.on_whiteList_itemSelectionChanged() |
|
403 self.on_blackList_itemSelectionChanged() |
|
404 |
|
405 def closeEvent(self, evt): |
|
406 """ |
|
407 Protected method to handle the close event. |
|
408 |
|
409 @param evt reference to the close event |
|
410 @type QCloseEvent |
|
411 """ |
|
412 self.__manager.clearNewOrigins() |
|
413 |
|
414 whiteList = [] |
|
415 for row in range(self.whiteList.count()): |
|
416 whiteList.append(self.whiteList.item(row).text()) |
|
417 |
|
418 blackList = [] |
|
419 for row in range(self.blackList.count()): |
|
420 blackList.append(self.blackList.item(row).text()) |
|
421 |
|
422 Preferences.setWebBrowser("FlashCookiesWhitelist", whiteList) |
|
423 Preferences.setWebBrowser("FlashCookiesBlacklist", blackList) |
|
424 |
|
425 evt.accept() |
|