WebBrowser/Network/ProtocolHandlerManager.py

changeset 6695
0a51887c13cd
diff -r c104c120e043 -r 0a51887c13cd WebBrowser/Network/ProtocolHandlerManager.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/Network/ProtocolHandlerManager.py	Sun Feb 03 16:10:39 2019 +0100
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the protocol handler manager.
+"""
+
+from __future__ import unicode_literals
+
+import os
+import json
+
+from PyQt5.QtCore import QObject, QUrl
+from PyQt5.QtWebEngineWidgets import QWebEnginePage
+
+import Utilities
+
+
+class ProtocolHandlerManager(QObject):
+    """
+    Class implementing the protocol handler manager.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        
+        @param parent reference to the parent object
+        @type QObject
+        """
+        super(ProtocolHandlerManager, self).__init__(parent)
+        
+        self.__protocolHandlers = {}
+        # dictionary of handlers with scheme as key
+        
+        self.__load()
+    
+    def protocolHandler(self, scheme):
+        """
+        Public method to get the protocol handler URL for a given scheme.
+        
+        @param scheme scheme to look for
+        @type str
+        @return protocol handler URL
+        @rtype QUrl
+        """
+        try:
+            return QUrl(self.__protocolHandlers[scheme])
+        except KeyError:
+            return QUrl()
+    
+    def protocolHandlers(self):
+        """
+        Public method to get the registered protocol handlers.
+        
+        @return dictionary containing the registered protocol handlers
+        @rtype dict
+        """
+        return {s: QUrl(u) for s, u in self.__protocolHandlers.items()}
+    
+    def addProtocolHandler(self, scheme, url):
+        """
+        Public method to add a protocol handler for a scheme.
+        
+        @param scheme scheme of the protocol handler
+        @type str
+        @param url URL of the protocol handler
+        @type QUrl
+        """
+        if bool(scheme) and not url.isEmpty():
+            self.__protocolHandlers[scheme] = url
+            self.__registerHandler(scheme, url)
+            self.__save()
+    
+    def removeProtocolHandler(self, scheme):
+        """
+        Public method to remove the protocol handler for a given scheme.
+        
+        @param scheme scheme to remove
+        @type str
+        """
+        if scheme in self.__protocolHandlers:
+            self.__unregisterHandler(scheme, self.__protocolHandlers[scheme])
+            del self.__protocolHandlers[scheme]
+            self.__save()
+    
+    def __protocolHandlersFileName(self):
+        """
+        Private method to determine the protocol handlers file name.
+        
+        @return name of the protocol handlers file
+        @rtype str
+        """
+        return os.path.join(
+            Utilities.getConfigDir(), "web_browser", "protocol_handlers.json")
+    
+    def __load(self):
+        """
+        Private method to load the registered protocol handlers.
+        """
+        try:
+            protocolHandlersFile = open(self.__protocolHandlersFileName(), "r")
+            protocolHandlersData = json.load(protocolHandlersFile)
+            protocolHandlersFile.close()
+            
+            if protocolHandlersData:
+                self.__protocolHandlers = {}
+                for scheme, urlStr in protocolHandlersData.items():
+                    url = QUrl(urlStr)
+                    self.__protocolHandlers[scheme] = url
+                    self.__registerHandler(scheme, url)
+        except (IOError, OSError):
+            # ignore issues silently
+            pass
+    
+    def __save(self):
+        """
+        Private method to save the protocol handlers.
+        """
+        protocolHandlers = {scheme: url.toString()
+                            for scheme, url in self.__protocolHandlers.items()}
+        
+        protocolHandlersFile = open(self.__protocolHandlersFileName(), "w")
+        json.dump(protocolHandlers, protocolHandlersFile, indent=2)
+        protocolHandlersFile.close()
+    
+    def __registerHandler(self, scheme, url):
+        """
+        Private method to register a protocol handler for a scheme.
+        
+        @param scheme scheme of the protocol handler
+        @type str
+        @param url URL of the protocol handler
+        @type QUrl
+        """
+        urlStr = url.toString().replace("%25s", "%s")
+        
+        page = QWebEnginePage(self)
+        page.loadFinished.connect(page.deleteLater)
+        try:
+            # Qt >= 5.11
+            page.registerProtocolHandlerRequested.connect(
+                lambda r: r.accept())
+        except AttributeError:
+            pass
+        page.setHtml(
+            "<script>navigator.registerProtocolHandler('{0}', '{1}', '')"
+            "</script>".format(scheme, urlStr),
+            url)
+    
+    def __unregisterHandler(self, scheme, url):
+        """
+        Private method to unregister a protocol handler for a scheme.
+        
+        @param scheme scheme of the protocol handler
+        @type str
+        @param url URL of the protocol handler
+        @type QUrl
+        """
+        urlStr = url.toString().replace("%25s", "%s")
+        
+        page = QWebEnginePage(self)
+        page.loadFinished.connect(page.deleteLater)
+        page.setHtml(
+            "<script>navigator.unregisterProtocolHandler('{0}', '{1}', '')"
+            "</script>".format(scheme, urlStr),
+            url)
+    
+    def showProtocolHandlerManagerDialog(self):
+        """
+        Public method to show the protocol handler manager dialog.
+        """
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        from .ProtocolHandlerManagerDialog import ProtocolHandlerManagerDialog
+        
+        dlg = ProtocolHandlerManagerDialog(self, WebBrowserWindow.getWindow())
+        dlg.open()

eric ide

mercurial