|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2015 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to manage the flash cookies. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QTimer |
|
13 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QApplication, QMenu, \ |
|
14 QInputDialog, QLineEdit |
|
15 |
|
16 from E5Gui import E5MessageBox |
|
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, filter): |
|
153 """ |
|
154 Private slot to filter the cookies list. |
|
155 |
|
156 @param filter filter text |
|
157 @type str |
|
158 """ |
|
159 if not filter: |
|
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 filter = filter.lower() |
|
167 for index in range(self.cookiesList.topLevelItemCount()): |
|
168 txt = "." + self.cookiesList.topLevelItem(index)\ |
|
169 .text(0).lower() |
|
170 self.cookiesList.topLevelItem(index).setHidden( |
|
171 filter not in txt) |
|
172 self.cookiesList.topLevelItem(index).setExpanded(True) |
|
173 |
|
174 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
|
175 def on_cookiesList_currentItemChanged(self, current, previous): |
|
176 """ |
|
177 Private slot handling a change of the current cookie item. |
|
178 |
|
179 @param current reference to the current item |
|
180 @type QTreeWidgetItem |
|
181 @param previous reference to the previous item |
|
182 @type QTreeWidgetItem |
|
183 """ |
|
184 if current is None: |
|
185 self.removeButton.setEnabled(False) |
|
186 return |
|
187 |
|
188 cookie = current.data(0, Qt.UserRole) |
|
189 if cookie is None: |
|
190 self.nameLabel.setText(self.tr("<no flash cookie selected>")) |
|
191 self.sizeLabel.setText(self.tr("<no flash cookie selected>")) |
|
192 self.originLabel.setText(self.tr("<no flash cookie selected>")) |
|
193 self.modifiedLabel.setText(self.tr("<no flash cookie selected>")) |
|
194 self.contentsEdit.clear() |
|
195 self.pathEdit.clear() |
|
196 self.removeButton.setText(self.tr("Remove Cookie Group")) |
|
197 else: |
|
198 suffix = "" |
|
199 if cookie.path.startswith( |
|
200 self.__manager.flashPlayerDataPath() + |
|
201 "/macromedia.com/support/flashplayer/sys"): |
|
202 suffix = self.tr(" (settings)") |
|
203 self.nameLabel.setText( |
|
204 self.tr("{0}{1}", "name and suffix") |
|
205 .format(cookie.name, suffix)) |
|
206 self.sizeLabel.setText(self.tr("{0} Byte").format(cookie.size)) |
|
207 self.originLabel.setText(cookie.origin) |
|
208 self.modifiedLabel.setText( |
|
209 cookie.lastModified.toString("yyyy-MM-dd hh:mm:ss")) |
|
210 self.contentsEdit.setPlainText(cookie.contents) |
|
211 self.pathEdit.setText(cookie.path) |
|
212 self.removeButton.setText(self.tr("Remove Cookie")) |
|
213 self.removeButton.setEnabled(True) |
|
214 |
|
215 @pyqtSlot(QPoint) |
|
216 def __cookiesListContextMenuRequested(self, pos): |
|
217 """ |
|
218 Private slot handling the cookies list context menu. |
|
219 |
|
220 @param pos position to show the menu at |
|
221 @type QPoint |
|
222 """ |
|
223 itm = self.cookiesList.itemAt(pos) |
|
224 if itm is None: |
|
225 return |
|
226 |
|
227 menu = QMenu() |
|
228 addBlacklistAct = menu.addAction(self.tr("Add to blacklist")) |
|
229 addWhitelistAct = menu.addAction(self.tr("Add to whitelist")) |
|
230 |
|
231 self.cookiesList.setCurrentItem(itm) |
|
232 |
|
233 activatedAction = menu.exec_( |
|
234 self.cookiesList.viewport().mapToGlobal(pos)) |
|
235 if itm.childCount() == 0: |
|
236 origin = itm.data(0, Qt.UserRole).origin |
|
237 else: |
|
238 origin = itm.text(0) |
|
239 |
|
240 if activatedAction == addBlacklistAct: |
|
241 self.__addBlacklist(origin) |
|
242 elif activatedAction == addWhitelistAct: |
|
243 self.__addWhitelist(origin) |
|
244 |
|
245 @pyqtSlot() |
|
246 def on_reloadButton_clicked(self): |
|
247 """ |
|
248 Private slot handling a press of the reload button. |
|
249 """ |
|
250 self.refreshView(True) |
|
251 |
|
252 @pyqtSlot() |
|
253 def on_removeAllButton_clicked(self): |
|
254 """ |
|
255 Private slot to remove all cookies. |
|
256 """ |
|
257 ok = E5MessageBox.yesNo( |
|
258 self, |
|
259 self.tr("Remove All"), |
|
260 self.tr("""Do you really want to delete all flash cookies on""" |
|
261 """ your computer?""")) |
|
262 if ok: |
|
263 cookies = self.__manager.flashCookies() |
|
264 for cookie in cookies: |
|
265 self.__manager.removeCookie(cookie) |
|
266 |
|
267 self.cookiesList.clear() |
|
268 self.__manager.clearNewOrigins() |
|
269 self.__manager.clearCache() |
|
270 |
|
271 @pyqtSlot() |
|
272 def on_removeButton_clicked(self): |
|
273 """ |
|
274 Private slot to remove one cookie or a cookie group. |
|
275 """ |
|
276 itm = self.cookiesList.currentItem() |
|
277 if itm is None: |
|
278 return |
|
279 |
|
280 cookie = itm.data(0, Qt.UserRole) |
|
281 if cookie is None: |
|
282 # remove a whole cookie group |
|
283 origin = itm.text(0) |
|
284 cookieList = self.__manager.flashCookies() |
|
285 for fcookie in cookieList: |
|
286 if fcookie.origin == origin: |
|
287 self.__manager.removeCookie(fcookie) |
|
288 |
|
289 index = self.cookiesList.indexOfTopLevelItem(itm) |
|
290 self.cookiesList.takeTopLevelItem(index) |
|
291 else: |
|
292 self.__manager.removeCookie(cookie) |
|
293 parent = itm.parent() |
|
294 index = parent.indexOfChild(itm) |
|
295 parent.takeChild(index) |
|
296 |
|
297 if parent.childCount() == 0: |
|
298 # remove origin item as well |
|
299 index = self.cookiesList.indexOfTopLevelItem(parent) |
|
300 self.cookiesList.takeTopLevelItem(index) |
|
301 del parent |
|
302 del itm |
|
303 |
|
304 def refreshView(self, forceReload=False): |
|
305 """ |
|
306 Public method to refresh the dialog view. |
|
307 |
|
308 @param forceReload flag indicating to reload the cookies |
|
309 @type bool |
|
310 """ |
|
311 blocked = self.filterEdit.blockSignals(True) |
|
312 self.filterEdit.clear() |
|
313 self.contentsEdit.clear() |
|
314 self.filterEdit.blockSignals(blocked) |
|
315 |
|
316 if forceReload: |
|
317 self.__manager.clearCache() |
|
318 self.__manager.clearNewOrigins() |
|
319 |
|
320 QTimer.singleShot(0, self.__refreshCookiesList) |
|
321 QTimer.singleShot(0, self.__refreshFilterLists) |
|
322 |
|
323 def showPage(self, index): |
|
324 """ |
|
325 Public method to display a given page. |
|
326 |
|
327 @param index index of the page to be shown |
|
328 @type int |
|
329 """ |
|
330 self.cookiesTabWidget.setCurrentIndex(index) |
|
331 |
|
332 @pyqtSlot() |
|
333 def __refreshCookiesList(self): |
|
334 """ |
|
335 Private slot to refresh the cookies list. |
|
336 """ |
|
337 QApplication.setOverrideCursor(Qt.WaitCursor) |
|
338 |
|
339 cookies = self.__manager.flashCookies() |
|
340 self.cookiesList.clear() |
|
341 |
|
342 counter = 0 |
|
343 originDict = {} |
|
344 for cookie in cookies: |
|
345 cookieOrigin = cookie.origin |
|
346 if cookieOrigin.startswith("."): |
|
347 cookieOrigin = cookieOrigin[1:] |
|
348 |
|
349 if cookieOrigin in originDict: |
|
350 itm = QTreeWidgetItem(originDict[cookieOrigin]) |
|
351 else: |
|
352 newParent = QTreeWidgetItem(self.cookiesList) |
|
353 newParent.setText(0, cookieOrigin) |
|
354 newParent.setIcon(0, UI.PixmapCache.getIcon("dirOpen.png")) |
|
355 self.cookiesList.addTopLevelItem(newParent) |
|
356 originDict[cookieOrigin] = newParent |
|
357 |
|
358 itm = QTreeWidgetItem(newParent) |
|
359 |
|
360 suffix = "" |
|
361 if cookie.path.startswith( |
|
362 self.__manager.flashPlayerDataPath() + |
|
363 "/macromedia.com/support/flashplayer/sys"): |
|
364 suffix = self.tr(" (settings)") |
|
365 |
|
366 if cookie.path + "/" + cookie.name in \ |
|
367 self.__manager.newCookiesList(): |
|
368 suffix += self.tr(" [new]") |
|
369 font = itm.font(0) |
|
370 font.setBold(True) |
|
371 itm.setFont(font) |
|
372 itm.parent().setExpanded(True) |
|
373 |
|
374 itm.setText(0, self.tr("{0}{1}", "name and suffix").format( |
|
375 cookie.name, suffix)) |
|
376 itm.setData(0, Qt.UserRole, cookie) |
|
377 |
|
378 counter += 1 |
|
379 if counter > 100: |
|
380 QApplication.processEvents() |
|
381 counter = 0 |
|
382 |
|
383 self.removeAllButton.setEnabled( |
|
384 self.cookiesList.topLevelItemCount() > 0) |
|
385 self.removeButton.setEnabled(False) |
|
386 |
|
387 QApplication.restoreOverrideCursor() |
|
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(Preferences.getHelp("FlashCookiesWhitelist")) |
|
398 self.blackList.addItems(Preferences.getHelp("FlashCookiesBlacklist")) |
|
399 |
|
400 self.on_whiteList_itemSelectionChanged() |
|
401 self.on_blackList_itemSelectionChanged() |
|
402 |
|
403 def closeEvent(self, evt): |
|
404 """ |
|
405 Protected method to handle the close event. |
|
406 |
|
407 @param evt reference to the close event |
|
408 @type QCloseEvent |
|
409 """ |
|
410 self.__manager.clearNewOrigins() |
|
411 |
|
412 whiteList = [] |
|
413 for row in range(self.whiteList.count()): |
|
414 whiteList.append(self.whiteList.item(row).text()) |
|
415 |
|
416 blackList = [] |
|
417 for row in range(self.blackList.count()): |
|
418 blackList.append(self.blackList.item(row).text()) |
|
419 |
|
420 Preferences.setHelp("FlashCookiesWhitelist", whiteList) |
|
421 Preferences.setHelp("FlashCookiesBlacklist", blackList) |
|
422 |
|
423 evt.accept() |