Helpviewer/FlashCookieManager/FlashCookieManager.py

changeset 4359
ac1dda9f3f19
child 4361
9eec3a532d59
diff -r 815d1f3116ff -r ac1dda9f3f19 Helpviewer/FlashCookieManager/FlashCookieManager.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Helpviewer/FlashCookieManager/FlashCookieManager.py	Sun Aug 09 17:18:21 2015 +0200
@@ -0,0 +1,348 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2015 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Flash cookie manager.
+"""
+
+from __future__ import unicode_literals
+
+try:
+    str = unicode       # __IGNORE_EXCEPTION__
+except NameError:
+    pass
+
+import shutil
+
+from PyQt5.QtCore import QObject, QTimer, QDir, QFileInfo, QFile
+
+from .FlashCookie import FlashCookie
+
+import Helpviewer.HelpWindow
+
+import Preferences
+
+
+class FlashCookieManager(QObject):
+    """
+    Class implementing the Flash cookie manager object.
+    """
+    RefreshInterval = 60 * 1000
+    
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent object
+        @type QObject
+        """
+        super(FlashCookieManager, self).__init__(parent)
+        
+        self.__flashCookieManagerDialog = None
+        self.__flashCookies = []    # list of FlashCookie
+        self.__newCookiesList = []  # list of str
+        self.__whitelist = []       # list of str
+        self.__blacklist = []       # list of str
+        
+        self.__timer = QTimer(self)
+        self.__timer.setInterval(FlashCookieManager.RefreshInterval)
+        self.__timer.timeout.connect(self.__autoRefresh)
+        
+        # start the timer if needed
+        self.__startStopTimer()
+        
+        if Preferences.getHelp("FlashCookiesDeleteOnStartExit"):
+            self.__loadFlashCookies()
+            self.__removeAllButWhitelisted()
+    
+    def shutdown(self):
+        """
+        Public method to perform shutdown actions.
+        """
+        if self.__flashCookieManagerDialog is not None:
+            self.__flashCookieManagerDialog.close()
+        
+        if Preferences.getHelp("FlashCookiesDeleteOnStartExit"):
+            self.__removeAllButWhitelisted()
+    
+    def setFlashCookies(self, cookies):
+        """
+        Public method to set the list of cached Flash cookies.
+        
+        @param cookies list of Flash cookies to store
+        @type list of FlashCookie
+        """
+        self.__flashCookies = cookies[:]
+    
+    def flashCookies(self):
+        """
+        Public method to get the list of cached Flash cookies.
+        
+        @return list of Flash cookies
+        @rtype list of FlashCookie
+        """
+        if not self.__flashCookies:
+            self.__loadFlashCookies()
+        
+        return self.__flashCookies[:]
+    
+    def newCookiesList(self):
+        """
+        Public method to get the list of newly detected Flash cookies.
+        
+        @return list of newly detected Flash cookies
+        @rtype list of str
+        """
+        return self.__newCookiesList[:]
+    
+    def clearNewOrigins(self):
+        """
+        Public method to clear the list of newly detected Flash cookies.
+        """
+        self.__newCookiesList = []
+    
+    def clearCache(self):
+        """
+        Public method to clear the list of cached Flash cookies.
+        """
+        self.__flashCookies = []
+    
+    def __isBlacklisted(self, cookie):
+        """
+        Private method to check for a blacklisted cookie.
+        
+        @param cookie Flash cookie to be tested
+        @type FlashCookie
+        """
+        return cookie.origin in Preferences.getHelp("FlashCookiesBlacklist")
+    
+    def __isWhitelisted(self, cookie):
+        """
+        Private method to check for a whitelisted cookie.
+        
+        @param cookie Flash cookie to be tested
+        @type FlashCookie
+        """
+        return cookie.origin in Preferences.getHelp("FlashCookiesWhitelist")
+    
+    def __removeAllButWhitelisted(self):
+        """
+        Private method to remove all non-whitelisted cookies.
+        """
+        for cookie in self.__flashCookies[:]:
+            if not self.__isWhitelisted(cookie):
+                self.removeCookie(cookie)
+    
+    def __sharedObjectDirName(self):
+        """
+        Private slot to determine the path of the shared data objects.
+        
+        @return path of the shared data objects
+        @rtype str
+        """
+        if "macromedia" in self.flashPlayerDataPath().lower() or \
+                "/.gnash" not in self.flashPlayerDataPath().lower():
+            return "/#SharedObjects/"
+        else:
+            return "/SharedObjects/"
+    
+    def flashPlayerDataPath(self):
+        """
+        Public method to get the Flash Player data path.
+        
+        @return Flash Player data path
+        @rtype str
+        """
+        return Preferences.getHelp("FlashCookiesDataPath")
+    
+    def preferencesChanged(self):
+        """
+        Public slot to handle a change of preferences.
+        """
+        self.__startStopTimer()
+    
+    def removeCookie(self, cookie):
+        """
+        Public method to remove a cookie of the list of cached cookies.
+        
+        @param cookie Flash cookie to be removed
+        @type FlashCookie
+        """
+        if cookie in self.__flashCookies:
+            self.__flashCookies.remove(cookie)
+            shutil.rmtree(cookie.path, True)
+    
+    def __autoRefresh(self):
+        """
+        Private slot to refresh the list of cookies.
+        """
+        if self.__flashCookieManagerDialog and \
+                self.__flashCookieManagerDialog.isVisible():
+            return
+        
+        oldFlashCookies = self.__flashCookies[:]
+        self.__loadFlashCookies()
+        newCookieList = []
+        
+        for cookie in self.__flashCookies[:]:
+            if self.__isBlacklisted(cookie):
+                self.removeCookie(cookie)
+                continue
+            
+            if self.__isWhitelisted(cookie):
+                continue
+            
+            newCookie = True
+            for oldCookie in oldFlashCookies:
+                if (oldCookie.path + oldCookie.name ==
+                    cookie.path + cookie.name):
+                    newCookie = False
+                    break
+            
+            if newCookie:
+                newCookieList.append(cookie.path + "/" + cookie.name)
+        
+        if newCookieList and Preferences.getHelp("FlashCookieNotify"):
+            self.__newCookiesList.extend(newCookieList)
+            win = Helpviewer.HelpWindow.HelpWindow.mainWindow()
+            if win is None:
+                return
+            
+            view = win.currentBrowser()
+            if view is None:
+                return
+            
+            from .FlashCookieNotification import FlashCookieNotification
+            notification = FlashCookieNotification(
+                view, self, len(newCookieList))
+            notification.show()
+    
+    def showFlashCookieManagerDialog(self):
+        """
+        Public method to show the Flash cookies management dialog.
+        """
+        if self.__flashCookieManagerDialog is None:
+            from .FlashCookieManagerDialog import FlashCookieManagerDialog
+            self.__flashCookieManagerDialog = FlashCookieManagerDialog(self)
+        
+        self.__flashCookieManagerDialog.refreshView()
+        self.__flashCookieManagerDialog.showPage(0)
+        self.__flashCookieManagerDialog.show()
+        self.__flashCookieManagerDialog.raise_()
+    
+    def __startStopTimer(self):
+        """
+        Private slot to start or stop the auto refresh timer.
+        """
+        if Preferences.getHelp("FlashCookieAutoRefresh"):
+            if not self.__timer.isActive():
+                if not bool(self.__flashCookies):
+                    self.__loadFlashCookies()
+                
+                self.__timer.start()
+        else:
+            self.__timer.stop()
+    
+    def __loadFlashCookies(self):
+        """
+        Private slot to load the Flash cookies to be cached.
+        """
+        self.__flashCookies = []
+        self.__loadFlashCookiesFromPath(self.flashPlayerDataPath())
+    
+    def __loadFlashCookiesFromPath(self, path):
+        """
+        Private slot to load the Flash cookies from a path.
+        
+        @param path Flash cookies path
+        @type str
+        """
+        if path.endswith(("#SharedObjects", "#AppContainer")):
+            # specific to IE and Windows
+            return
+        
+        path = path.replace("\\", "/")
+        solDir = QDir(path)
+        entryList = solDir.entryList()
+        for entry in entryList:
+            if entry == "." or entry == "..":
+                continue
+            entryInfo = QFileInfo(path + "/" + entry)
+            if entryInfo.isDir():
+                self.__loadFlashCookiesFromPath(entryInfo.filePath())
+            else:
+                self.__insertFlashCookie(entryInfo.filePath())
+    
+    def __insertFlashCookie(self, path):
+        """
+        Private method to insert a Flash cookie into the cache.
+        
+        @param path Flash cookies path
+        @type str
+        """
+        solFile = QFile(path)
+        if not solFile.open(QFile.ReadOnly):
+            return
+        
+        # TODO: dissect the flash cookie (see gnash s2x.py for example)
+        data = bytearray(solFile.readAll())
+        for i in range(len(data)):
+            if not ((data[i] >= ord("a") and data[i] <= ord("z")) or
+                    (data[i] >= ord("A") and data[i] <= ord("Z")) or
+                    (data[i] >= ord("0") and data[i] <= ord("9"))):
+                data[i] = 32
+        dataStr = str(data, "utf-8", "replace")
+        dataStr = "\n".join([s for s in dataStr.split(".") if s])
+        
+        solFileInfo = QFileInfo(solFile)
+        
+        cookie = FlashCookie()
+        cookie.contents = dataStr
+        cookie.name = solFileInfo.fileName()
+        cookie.path = solFileInfo.canonicalPath()
+        cookie.size = int(solFile.size())
+        cookie.lastModified = solFileInfo.lastModified()
+        cookie.origin = self.__extractOriginFrom(path)
+        
+        self.__flashCookies.append(cookie)
+    
+    def __extractOriginFrom(self, path):
+        """
+        Private method to extract the cookie origin given its file name.
+        
+        @param path file name of the cookie file
+        @type str
+        @return cookie origin
+        @rtype str
+        """
+        origin = path
+        if path.startswith(
+                self.flashPlayerDataPath() + self.__sharedObjectDirName()):
+            origin = origin.replace(
+                self.flashPlayerDataPath() + self.__sharedObjectDirName(), "")
+            if "/" in origin:
+                origin = origin.split("/", 1)[1]
+        elif path.startswith(
+            self.flashPlayerDataPath() + 
+                "/macromedia.com/support/flashplayer/sys/"):
+            origin = origin.replace(
+                self.flashPlayerDataPath() + 
+                "/macromedia.com/support/flashplayer/sys/", "")
+            if origin == "settings.sol":
+                return self.tr("!default")
+            elif origin.startswith("#"):
+                origin = origin[1:]
+        else:
+            origin = ""
+        
+        index = origin.find("/")
+        if index == -1:
+            return self.tr("!other")
+        
+        origin = origin[:index]
+        if origin in ["localhost", "local"]:
+            origin = "!localhost"
+        
+        return origin

eric ide

mercurial