123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- ########################################################################
- # Searx-qt - Lightweight desktop application for SearX.
- # Copyright (C) 2020 CYBERDEViL
- #
- # This file is part of Searx-qt.
- #
- # Searx-qt is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # Searx-qt is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <https://www.gnu.org/licenses/>.
- #
- ########################################################################
- import requests
- from requests.exceptions import HTTPError, ConnectionError, Timeout
- import json
- class ErrorType:
- HttpError = 0
- ConnectionError = 1
- Timeout = 3
- WrongStatus = 4
- DecodeError = 5
- NoResults = 6
- NotSpecified = 7
- ErrorTypeStr = {
- ErrorType.HttpError: "HttpError",
- ErrorType.ConnectionError: "ConnectionError",
- ErrorType.Timeout: "Timeout",
- ErrorType.WrongStatus: "WrongStatus",
- ErrorType.DecodeError: "DecodeError",
- ErrorType.NoResults: "NoResults",
- ErrorType.NotSpecified: "NotSpecified"
- }
- class Result:
- def __init__(self, response, err="", errType=None, acceptCodes=None):
- self._response = response
- self._err = err
- self._errType = errType
- acceptCodes = acceptCodes
- if not acceptCodes:
- acceptCodes = [200]
- if errType is None and response.status_code not in acceptCodes:
- self._errType = ErrorType.WrongStatus
- self._err = "WrongStatus: {0}".format(self._response.status_code)
- else:
- self.verifyFurther()
- def __bool__(self):
- return not self.failed()
- def errorType(self): return self._errType
- def error(self): return self._err
- def content(self):
- """ In case json.loads failed and we want to debug.
- """
- if self._response == None:
- return b''
- return self._response.content
- def text(self):
- if self._response == None:
- return ''
- return self._response.text
- def failed(self):
- if self._errType is not None:
- return True
- return False
- def statusCode(self):
- if self._response != None:
- return self._response.status_code
- return 0
- def verifyFurther(self):
- pass
- class JsonResult(Result):
- def __init__(self, response, err="", errType=None, acceptCodes=None):
- Result.__init__(
- self,
- response,
- err=err,
- errType=errType,
- acceptCodes=acceptCodes
- )
- def verifyFurther(self):
- try:
- self.json()
- except json.JSONDecodeError as err:
- self._errType = ErrorType.DecodeError
- self._err = "DecodeError: `{0}`".format(err)
- except UnicodeDecodeError as err:
- # This could happen when the response encoding isn't plain ? (gzip)
- # Or we just have malformed data/crap.
- self._errType = ErrorType.DecodeError
- self._err = "DecodeError: `{0}`".format(err)
- def json(self):
- if self.errorType() is not None:
- return {}
- return json.loads(self._response.content)
- class RequestsHandler:
- def __init__(self, settings):
- """
- @param settings: TODO don't use Qt stuff in core.
- @type settings: searxqt.models.RequestSettingsModel
- """
- self._settings = settings
- def failSafeRequestFactory(func):
- def failSafeRequest(self, url, data=None, ResultType=None):
- response = None
- err = ""
- errType = None
- if not ResultType:
- # When 'ResultType' isn't specified, set 'JsonResult' as
- # default.
- ResultType = JsonResult
- print("<NEW Request>")
- print("# ------------------------")
- print("# ResultType : {0}".format(ResultType))
- try:
- response = func(self, url, data=data, **self._settings.kwargs)
- except HTTPError as e:
- print("Request failed! HTTPError: {0}".format(e))
- errType = ErrorType.HttpError
- err = e
- except ConnectionError as e:
- print("Request failed! ConnectionError: {0}".format(e))
- errType = ErrorType.ConnectionError
- err = e
- except Timeout as e:
- print("Request failed! Timeout: {0}".format(e))
- errType = ErrorType.Timeout
- err = e
- print("# ------------------------")
- print()
- return ResultType(response=response, err=err, errType=errType)
- return failSafeRequest
- @failSafeRequestFactory
- def get(self, url, data=None, ResultType=None, **settingsKwargs):
- print("# Type : GET")
- print("# URL : {0}".format(url))
- print("# Data : {0}".format(data))
- print("# Kwargs : {0}".format(settingsKwargs))
- return requests.get(url, data=data, **settingsKwargs)
- @failSafeRequestFactory
- def post(self, url, data=None, ResultType=None, **settingsKwargs):
- print("# Type : POST")
- print("# URL : {0}".format(url))
- print("# Data : {0}".format(data))
- print("# Kwargs : {0}".format(settingsKwargs))
- return requests.post(url, data=data, **settingsKwargs)
|