instances.py 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. ########################################################################
  2. # Searx-qt - Lightweight desktop application for SearX.
  3. # Copyright (C) 2020 CYBERDEViL
  4. #
  5. # This file is part of Searx-qt.
  6. #
  7. # Searx-qt is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # Searx-qt is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. ########################################################################
  21. import time
  22. from searxqt.core.handler import HandlerProto, NetworkTypes
  23. from searxqt.core.instanceVersions import parseVersionString
  24. class SearchEngine:
  25. def __init__(self, name, data):
  26. """Model for a search engine data.
  27. @param name: Name of the search engine
  28. @type name: str
  29. @param data: Data of the search engine
  30. @type data: dict
  31. """
  32. self._name = name
  33. self._data = data
  34. def __repr__(self): return self._name
  35. @property
  36. def name(self):
  37. """
  38. @return: returns the name of this search engine.
  39. @rtype: str
  40. """
  41. return self._name
  42. @property
  43. def stats(self):
  44. """ TODO this is unused.
  45. @return:
  46. @rtype: bool
  47. """
  48. return self._data.get('stats', False)
  49. class TLS:
  50. def __init__(self, data):
  51. """Model for a instance it's TLS data.
  52. @param data: dict with the instance it's TLS data.
  53. @type data: dict
  54. """
  55. self._data = data
  56. @property
  57. def data(self): return self._data
  58. @property
  59. def version(self):
  60. """Returns the TLS version used.
  61. @return:
  62. @rtype: str
  63. """
  64. return self.data.get('version', "")
  65. @property
  66. def certificate(self):
  67. """Returns a TLSCertificate object.
  68. @return:
  69. @rtype: TLSCertificate
  70. """
  71. return TLSCertificate(self.data.get('certificate', {}))
  72. class TLSCertificate:
  73. def __init__(self, data):
  74. """Model for a instance it's TLS certificate-data.
  75. @param data: dict with the instance it's TLS certificate-data.
  76. @type data: dict
  77. """
  78. self._data = data
  79. @property
  80. def data(self): return self._data
  81. @property
  82. def version(self):
  83. """
  84. @return:
  85. @rtype: int
  86. """
  87. return self.data.get('version', 0)
  88. @property
  89. def issuer(self):
  90. """
  91. @return:
  92. @rtype: TLSCertificateIssuer
  93. """
  94. return TLSCertificateIssuer(self.data.get('issuer', {}))
  95. class TLSCertificateIssuer:
  96. def __init__(self, data):
  97. """Model for a instance it's TLS certificate-issuer-data.
  98. @param data: dict with the instance it's
  99. TLS certificate-issuer-data.
  100. @type data: dict
  101. """
  102. self._data = data
  103. @property
  104. def data(self): return self._data
  105. @property
  106. def commonName(self):
  107. """
  108. @rtype: str
  109. """
  110. return self.data.get('commonName', "")
  111. @property
  112. def countryName(self):
  113. """
  114. @rtype: str
  115. """
  116. return self.data.get('countryName', "")
  117. @property
  118. def organizationName(self):
  119. """
  120. @rtype: str
  121. """
  122. return self.data.get('organizationName', "")
  123. class Network:
  124. def __init__(self, data):
  125. """Model for a instance it's network data.
  126. @param data: dict with the instance it's network data.
  127. @type data: dict
  128. """
  129. self._data = data
  130. @property
  131. def data(self): return self._data
  132. @property
  133. def ipv6(self):
  134. """
  135. @return: If ipv6 is enabled on this instance.
  136. @rtype: bool
  137. """
  138. return self.data.get('ipv6', False)
  139. @property
  140. def ips(self):
  141. """
  142. @return: A list with NetworkIP objects
  143. @rtype: list
  144. """
  145. return [NetworkIP(ip, data)
  146. for ip, data in self.data.get('ips', {}).items()]
  147. @property
  148. def asnPrivacy(self):
  149. """
  150. @return: -1 no asn privacy, 0 asn privacy, -2 unknown.
  151. @rtype: int
  152. """
  153. return self.data.get('asn_privacy', -2)
  154. class NetworkIP:
  155. def __init__(self, ip, data):
  156. """Model for a network ip data.
  157. @param ip: ip address
  158. @type ip: str
  159. @param data: dict with a network ip data.
  160. @type data: dict
  161. """
  162. self._ip = ip
  163. self._data = data
  164. def __repr__(self):
  165. return (
  166. "IP: {0} Reverse: {1} FieldType: {2} asnCidr: {3}"
  167. .format(self.ip, self.reverse, self.fieldType, self.asnCidr)
  168. )
  169. def __str__(self): return repr(self)
  170. @property
  171. def ip(self):
  172. """
  173. @return: ip address
  174. @rtype: str
  175. """
  176. return self._ip
  177. @property
  178. def data(self): return self._data
  179. @property
  180. def reverse(self):
  181. """
  182. @return:
  183. @rtype: str
  184. """
  185. return self.data.get('reverse', None)
  186. @property
  187. def fieldType(self):
  188. """
  189. @return: Record type
  190. @rtype: str
  191. """
  192. return self.data.get('field_type', None)
  193. @property
  194. def asnCidr(self):
  195. """
  196. @return:
  197. @rtype: str
  198. """
  199. return self.data.get('asn_cidr', None)
  200. @property
  201. def httpsPort(self):
  202. """
  203. @return:
  204. @rtype: bool
  205. """
  206. return self.data.get('https_port', None)
  207. class Instance:
  208. def __init__(self, url, data):
  209. """Model for a SearX instance.
  210. @param url: Url of the instance
  211. @type url: str
  212. @param data: Data of the instance
  213. @type data: dict
  214. """
  215. self._url = url
  216. self._data = data
  217. def __str__(self): return self.url
  218. def __repr__(self): return str(self)
  219. @property
  220. def data(self): return self._data
  221. @property
  222. def url(self):
  223. """
  224. @return: returns the url of this instance.
  225. @rtype: str
  226. """
  227. return self._url
  228. @property
  229. def main(self):
  230. """Returns False when not set.
  231. @return: ?
  232. @rtype: bool
  233. """
  234. return self._data.get('main', False)
  235. @property
  236. def networkType(self):
  237. """ Network type; see core/handler.py:NetworkTypes
  238. @return: Network protocol used (Web, Tor, I2P from NetworkTypes)
  239. @rtype: int
  240. """
  241. return self._data.get('network_type', 0)
  242. @property
  243. def version(self):
  244. """Returns a empty string when none found.
  245. @return: Returns the instance it's version.
  246. @rtype: InstanceVersion
  247. """
  248. return parseVersionString(self._data.get('version', ''))
  249. @property
  250. def engines(self):
  251. """
  252. Returns a empty string when none found.
  253. @return: Returns a list with SearchEngine objects
  254. @rtype: list
  255. """
  256. return [SearchEngine(name, data) for name, data in self._data.get(
  257. 'engines', {}).items()]
  258. @property
  259. def tls(self):
  260. """
  261. @rtype: TLS
  262. """
  263. return TLS(self._data.get('tls', {}))
  264. @property
  265. def network(self):
  266. """
  267. @rtype: Network
  268. """
  269. return Network(self._data.get('network', {}))
  270. class Stats2(HandlerProto):
  271. """ This class holds the instances.json data and will be passed
  272. to other classes (Instances, Engines)
  273. """
  274. URL = "https://searx.space/"
  275. def __init__(self, requestsHandler):
  276. HandlerProto.__init__(self, requestsHandler)
  277. def updateInstances(self):
  278. """Fetches instances.json from a searx-stats2 instance.
  279. @param requestKwargs: Kwargs to pass to requests.get
  280. @type requestKwargs: dict
  281. @return: A tuple (bool Success/Failed, str Message)
  282. @rtype: tuple
  283. """
  284. url = Stats2.URL.rstrip('/') + '/data/instances.json'
  285. result = self.requestsHandler.get(url)
  286. if result:
  287. self.setData(result.json())
  288. self._lastUpdated = time.time()
  289. # Processing (use our own definition of network types
  290. for url, data in self.instances.items():
  291. data.update({"network_type": NetworkTypes.netTypeFromUrl(url)})
  292. return True
  293. return False