eric6/Helpviewer/OpenSearch/OpenSearchEngine.py

changeset 7220
5cf645f6daab
parent 7218
eaf2cf171f3a
parent 7211
1c97f3142fa8
child 7221
0485ccdf7877
diff -r eaf2cf171f3a -r 5cf645f6daab eric6/Helpviewer/OpenSearch/OpenSearchEngine.py
--- a/eric6/Helpviewer/OpenSearch/OpenSearchEngine.py	Sat Sep 07 14:45:27 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,537 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2009 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing the open search engine.
-"""
-
-from __future__ import unicode_literals
-
-import re
-import json
-
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QLocale, QUrl, QByteArray, \
-    QBuffer, QIODevice, QObject
-from PyQt5.QtGui import QImage
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager, \
-    QNetworkReply
-
-from UI.Info import Program
-
-import Preferences
-import Utilities
-from Globals import qVersionTuple
-
-
-class OpenSearchEngine(QObject):
-    """
-    Class implementing the open search engine.
-    
-    @signal imageChanged() emitted after the icon has been changed
-    @signal suggestions(list of strings) emitted after the suggestions have
-            been received
-    """
-    imageChanged = pyqtSignal()
-    suggestions = pyqtSignal(list)
-    
-    def __init__(self, parent=None):
-        """
-        Constructor
-        
-        @param parent reference to the parent object (QObject)
-        """
-        super(OpenSearchEngine, self).__init__(parent)
-        
-        self.__suggestionsReply = None
-        self.__networkAccessManager = None
-        self._name = ""
-        self._description = ""
-        self._searchUrlTemplate = ""
-        self._suggestionsUrlTemplate = ""
-        self._searchParameters = []            # list of two tuples
-        self._suggestionsParameters = []       # list of two tuples
-        self._imageUrl = ""
-        self.__image = QImage()
-        self.__iconMoved = False
-        self.__searchMethod = "get"
-        self.__suggestionsMethod = "get"
-        self.__requestMethods = {
-            "get": QNetworkAccessManager.GetOperation,
-            "post": QNetworkAccessManager.PostOperation,
-        }
-        
-        self.__replies = []
-    
-    @classmethod
-    def parseTemplate(cls, searchTerm, searchTemplate):
-        """
-        Class method to parse a search template.
-        
-        @param searchTerm term to search for (string)
-        @param searchTemplate template to be parsed (string)
-        @return parsed template (string)
-        """
-        locale = QLocale(Preferences.getHelp("SearchLanguage"))
-        language = locale.name().split("_")[0]
-        country = language.lower()
-        
-        result = searchTemplate
-        result = result.replace("{count}", "20")
-        result = result.replace("{startIndex}", "0")
-        result = result.replace("{startPage}", "0")
-        result = result.replace("{language}", language)
-        result = result.replace("{country}", country)
-        result = result.replace("{inputEncoding}", "UTF-8")
-        result = result.replace("{outputEncoding}", "UTF-8")
-        result = result.replace(
-            "{searchTerms}",
-            bytes(QUrl.toPercentEncoding(searchTerm)).decode())
-        result = re.sub(r"""\{([^\}]*:|)source\??\}""", Program, result)
-
-        return result
-    
-    @pyqtSlot(result=str)
-    def name(self):
-        """
-        Public method to get the name of the engine.
-        
-        @return name of the engine (string)
-        """
-        return self._name
-    
-    def setName(self, name):
-        """
-        Public method to set the engine name.
-        
-        @param name name of the engine (string)
-        """
-        self._name = name
-    
-    def description(self):
-        """
-        Public method to get the description of the engine.
-        
-        @return description of the engine (string)
-        """
-        return self._description
-    
-    def setDescription(self, description):
-        """
-        Public method to set the engine description.
-        
-        @param description description of the engine (string)
-        """
-        self._description = description
-    
-    def searchUrlTemplate(self):
-        """
-        Public method to get the search URL template of the engine.
-        
-        @return search URL template of the engine (string)
-        """
-        return self._searchUrlTemplate
-    
-    def setSearchUrlTemplate(self, searchUrlTemplate):
-        """
-        Public method to set the engine search URL template.
-        
-        The URL template is processed according to the specification:
-        <a
-          href="http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax">
-        http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax</a>
-
-        A list of template parameters currently supported and what they are
-        replaced with:
-        <table>
-        <tr><td><b>Parameter</b></td><td><b>Value</b></td></tr>
-        <tr><td>{count}</td><td>20</td></tr>
-        <tr><td>{startIndex}</td><td>0</td></tr>
-        <tr><td>{startPage}</td><td>0</td></tr>
-        <tr><td>{language}</td>
-          <td>the default language code (RFC 3066)</td></tr>
-        <tr><td>{country}</td>
-          <td>the default language code (RFC 3066) converted to lower
-              case</td></tr>
-        <tr><td>{inputEncoding}</td><td>UTF-8</td></tr>
-        <tr><td>{outputEncoding}</td><td>UTF-8</td></tr>
-        <tr><td>{searchTerms}</td><td>the string supplied by the user</td></tr>
-        <tr><td>{*:source}</td>
-          <td>application name, QCoreApplication::applicationName()</td></tr>
-        </table>
-        
-        @param searchUrlTemplate search URL template of the engine (string)
-        """
-        self._searchUrlTemplate = searchUrlTemplate
-    
-    def searchUrl(self, searchTerm):
-        """
-        Public method to get a URL ready for searching.
-        
-        @param searchTerm term to search for (string)
-        @return URL (QUrl)
-        """
-        if not self._searchUrlTemplate:
-            return QUrl()
-        
-        ret = QUrl.fromEncoded(
-            self.parseTemplate(searchTerm, self._searchUrlTemplate)
-            .encode("utf-8"))
-        
-        if self.__searchMethod != "post":
-            if qVersionTuple() >= (5, 0, 0):
-                from PyQt5.QtCore import QUrlQuery
-                urlQuery = QUrlQuery(ret)
-                for parameter in self._searchParameters:
-                    urlQuery.addQueryItem(
-                        parameter[0],
-                        self.parseTemplate(searchTerm, parameter[1]))
-                ret.setQuery(urlQuery)
-            else:
-                for parameter in self._searchParameters:
-                    ret.addQueryItem(
-                        parameter[0],
-                        self.parseTemplate(searchTerm, parameter[1]))
-        
-        return ret
-    
-    def providesSuggestions(self):
-        """
-        Public method to check, if the engine provides suggestions.
-        
-        @return flag indicating suggestions are provided (boolean)
-        """
-        return self._suggestionsUrlTemplate != ""
-    
-    def suggestionsUrlTemplate(self):
-        """
-        Public method to get the search URL template of the engine.
-        
-        @return search URL template of the engine (string)
-        """
-        return self._suggestionsUrlTemplate
-    
-    def setSuggestionsUrlTemplate(self, suggestionsUrlTemplate):
-        """
-        Public method to set the engine suggestions URL template.
-        
-        @param suggestionsUrlTemplate suggestions URL template of the
-            engine (string)
-        """
-        self._suggestionsUrlTemplate = suggestionsUrlTemplate
-    
-    def suggestionsUrl(self, searchTerm):
-        """
-        Public method to get a URL ready for suggestions.
-        
-        @param searchTerm term to search for (string)
-        @return URL (QUrl)
-        """
-        if not self._suggestionsUrlTemplate:
-            return QUrl()
-        
-        ret = QUrl.fromEncoded(QByteArray(self.parseTemplate(
-            searchTerm, self._suggestionsUrlTemplate).encode("utf-8")))
-        
-        if self.__searchMethod != "post":
-            if qVersionTuple() >= (5, 0, 0):
-                from PyQt5.QtCore import QUrlQuery
-                urlQuery = QUrlQuery(ret)
-                for parameter in self._suggestionsParameters:
-                    urlQuery.addQueryItem(
-                        parameter[0],
-                        self.parseTemplate(searchTerm, parameter[1]))
-                ret.setQuery(urlQuery)
-            else:
-                for parameter in self._suggestionsParameters:
-                    ret.addQueryItem(
-                        parameter[0],
-                        self.parseTemplate(searchTerm, parameter[1]))
-        
-        return ret
-    
-    def searchParameters(self):
-        """
-        Public method to get the search parameters of the engine.
-        
-        @return search parameters of the engine (list of two tuples)
-        """
-        return self._searchParameters[:]
-    
-    def setSearchParameters(self, searchParameters):
-        """
-        Public method to set the engine search parameters.
-        
-        @param searchParameters search parameters of the engine
-            (list of two tuples)
-        """
-        self._searchParameters = searchParameters[:]
-    
-    def suggestionsParameters(self):
-        """
-        Public method to get the suggestions parameters of the engine.
-        
-        @return suggestions parameters of the engine (list of two tuples)
-        """
-        return self._suggestionsParameters[:]
-    
-    def setSuggestionsParameters(self, suggestionsParameters):
-        """
-        Public method to set the engine suggestions parameters.
-        
-        @param suggestionsParameters suggestions parameters of the
-            engine (list of two tuples)
-        """
-        self._suggestionsParameters = suggestionsParameters[:]
-    
-    def searchMethod(self):
-        """
-        Public method to get the HTTP request method used to perform search
-        requests.
-        
-        @return HTTP request method (string)
-        """
-        return self.__searchMethod
-    
-    def setSearchMethod(self, method):
-        """
-        Public method to set the HTTP request method used to perform search
-        requests.
-        
-        @param method HTTP request method (string)
-        """
-        requestMethod = method.lower()
-        if requestMethod not in self.__requestMethods:
-            return
-        
-        self.__searchMethod = requestMethod
-    
-    def suggestionsMethod(self):
-        """
-        Public method to get the HTTP request method used to perform
-        suggestions requests.
-        
-        @return HTTP request method (string)
-        """
-        return self.__suggestionsMethod
-    
-    def setSuggestionsMethod(self, method):
-        """
-        Public method to set the HTTP request method used to perform
-        suggestions requests.
-        
-        @param method HTTP request method (string)
-        """
-        requestMethod = method.lower()
-        if requestMethod not in self.__requestMethods:
-            return
-        
-        self.__suggestionsMethod = requestMethod
-    
-    def imageUrl(self):
-        """
-        Public method to get the image URL of the engine.
-        
-        @return image URL of the engine (string)
-        """
-        return self._imageUrl
-    
-    def setImageUrl(self, imageUrl):
-        """
-        Public method to set the engine image URL.
-        
-        @param imageUrl image URL of the engine (string)
-        """
-        self._imageUrl = imageUrl
-    
-    def setImageUrlAndLoad(self, imageUrl):
-        """
-        Public method to set the engine image URL.
-        
-        @param imageUrl image URL of the engine (string)
-        """
-        self.setImageUrl(imageUrl)
-        self.__iconMoved = False
-        self.loadImage()
-    
-    def loadImage(self):
-        """
-        Public method to load the image of the engine.
-        """
-        if self.__networkAccessManager is None or not self._imageUrl:
-            return
-        
-        reply = self.__networkAccessManager.get(
-            QNetworkRequest(QUrl.fromEncoded(self._imageUrl.encode("utf-8"))))
-        reply.finished.connect(lambda: self.__imageObtained(reply))
-        self.__replies.append(reply)
-    
-    def __imageObtained(self, reply):
-        """
-        Private slot to receive the image of the engine.
-        
-        @param reply reference to the network reply
-        @type QNetworkReply
-        """
-        response = reply.readAll()
-        
-        reply.close()
-        if reply in self.__replies:
-            self.__replies.remove(reply)
-        reply.deleteLater()
-        
-        if response.isEmpty():
-            return
-        
-        if response.startsWith(b"<html>") or response.startsWith(b"HTML"):
-            self.__iconMoved = True
-            self.__image = QImage()
-        else:
-            self.__image.loadFromData(response)
-        self.imageChanged.emit()
-    
-    def image(self):
-        """
-        Public method to get the image of the engine.
-        
-        @return image of the engine (QImage)
-        """
-        if not self.__iconMoved and self.__image.isNull():
-            self.loadImage()
-        
-        return self.__image
-    
-    def setImage(self, image):
-        """
-        Public method to set the image of the engine.
-        
-        @param image image to be set (QImage)
-        """
-        if not self._imageUrl:
-            imageBuffer = QBuffer()
-            imageBuffer.open(QIODevice.ReadWrite)
-            if image.save(imageBuffer, "PNG"):
-                self._imageUrl = "data:image/png;base64,{0}".format(
-                    bytes(imageBuffer.buffer().toBase64()).decode())
-        
-        self.__image = QImage(image)
-        self.imageChanged.emit()
-    
-    def isValid(self):
-        """
-        Public method to check, if the engine is valid.
-        
-        @return flag indicating validity (boolean)
-        """
-        return self._name and self._searchUrlTemplate
-    
-    def __eq__(self, other):
-        """
-        Special method implementing the == operator.
-        
-        @param other reference to an open search engine (OpenSearchEngine)
-        @return flag indicating equality (boolean)
-        """
-        if not isinstance(other, OpenSearchEngine):
-            return NotImplemented
-        
-        return self._name == other._name and \
-            self._description == other._description and \
-            self._imageUrl == other._imageUrl and \
-            self._searchUrlTemplate == other._searchUrlTemplate and \
-            self._suggestionsUrlTemplate == other._suggestionsUrlTemplate and \
-            self._searchParameters == other._searchParameters and \
-            self._suggestionsParameters == other._suggestionsParameters
-    
-    def __lt__(self, other):
-        """
-        Special method implementing the < operator.
-        
-        @param other reference to an open search engine (OpenSearchEngine)
-        @return flag indicating less than (boolean)
-        """
-        if not isinstance(other, OpenSearchEngine):
-            return NotImplemented
-        
-        return self._name < other._name
-    
-    def requestSuggestions(self, searchTerm):
-        """
-        Public method to request suggestions.
-        
-        @param searchTerm term to get suggestions for (string)
-        """
-        if not searchTerm or not self.providesSuggestions():
-            return
-        
-        if self.__networkAccessManager is None:
-            return
-        
-        if self.__suggestionsReply is not None:
-            self.__suggestionsReply.abort()
-            self.__suggestionsReply.deleteLater()
-            self.__suggestionsReply = None
-        
-        if self.__suggestionsMethod not in self.__requestMethods:
-            # ignore
-            return
-        
-        if self.__suggestionsMethod == "get":
-            self.__suggestionsReply = self.networkAccessManager().get(
-                QNetworkRequest(self.suggestionsUrl(searchTerm)))
-        else:
-            parameters = []
-            for parameter in self._suggestionsParameters:
-                parameters.append(parameter[0] + "=" + parameter[1])
-            data = "&".join(parameters)
-            self.__suggestionsReply = self.networkAccessManager().post(
-                QNetworkRequest(self.suggestionsUrl(searchTerm)), data)
-        self.__suggestionsReply.finished.connect(
-            self.__suggestionsObtained)
-    
-    def __suggestionsObtained(self):
-        """
-        Private slot to receive the suggestions.
-        """
-        if self.__suggestionsReply.error() == QNetworkReply.NoError:
-            buffer = bytes(self.__suggestionsReply.readAll())
-            response = Utilities.decodeBytes(buffer)
-            response = response.strip()
-            
-            self.__suggestionsReply.close()
-            self.__suggestionsReply.deleteLater()
-            self.__suggestionsReply = None
-            
-            if len(response) == 0:
-                return
-            
-            try:
-                result = json.loads(response)
-            except ValueError:
-                return
-            
-            try:
-                suggestions = result[1]
-            except IndexError:
-                return
-            
-            self.suggestions.emit(suggestions)
-    
-    def networkAccessManager(self):
-        """
-        Public method to get a reference to the network access manager object.
-        
-        @return reference to the network access manager object
-            (QNetworkAccessManager)
-        """
-        return self.__networkAccessManager
-    
-    def setNetworkAccessManager(self, networkAccessManager):
-        """
-        Public method to set the reference to the network access manager.
-        
-        @param networkAccessManager reference to the network access manager
-            object (QNetworkAccessManager)
-        """
-        self.__networkAccessManager = networkAccessManager

eric ide

mercurial