only_show_green_results.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. '''
  2. searx is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU Affero General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. searx is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU Affero General Public License for more details.
  10. You should have received a copy of the GNU Affero General Public License
  11. along with searx. If not, see < http://www.gnu.org/licenses/ >.
  12. (C) 2015 by Adam Tauber, <asciimoo@gmail.com>
  13. '''
  14. from flask_babel import gettext
  15. import re
  16. from searx.url_utils import urlunparse, parse_qsl, urlencode
  17. import requests
  18. import logging
  19. import os
  20. import sqlite3
  21. from urllib.parse import urlparse
  22. logger = logging.getLogger(__name__)
  23. name = gettext('Only show green hosted results')
  24. description = gettext('Any results not being hosted on green infrastructure will be filtered')
  25. default_on = True
  26. preference_section = 'privacy'
  27. allow_api_connections = True
  28. database_name = "url2green.db"
  29. class GreenCheck:
  30. def __init__(self):
  31. try:
  32. self.db = bool(os.stat(database_name))
  33. logger.debug(f"Database found at {database_name}. Using it for lookups instead of the Greencheck API")
  34. except FileNotFoundError:
  35. self.db = False
  36. if allow_api_connections:
  37. logger.debug(f"No database found at {database_name}.")
  38. logger.debug(f"Falling back to the instead of the Greencheck API, as 'allow_api_connections' is set to {allow_api_connections}.")
  39. else:
  40. logger.debug(f"No database found at {database_name}. Not making any checks, because 'allow_api_connections' is set to {allow_api_connections}")
  41. def check_url(self, url=None) -> bool:
  42. """
  43. Check a url passed in, and return a true or false result,
  44. based on whether the domain is marked as a one running on
  45. green energy.
  46. """
  47. try:
  48. parsed_domain = self.get_domain_from_url(url)
  49. except Exception as e:
  50. logger.exception(f"unable to parse url: {url}")
  51. if parsed_domain:
  52. logger.debug(f"Checking {parsed_domain}, parsed from {url}")
  53. if self.db:
  54. return self.check_in_db(parsed_domain)
  55. else:
  56. if allow_api_connections:
  57. return self.check_against_api(parsed_domain)
  58. else:
  59. return False
  60. def get_domain_from_url(self, url=None):
  61. return urlparse(url).hostname
  62. def check_in_db(self, domain=None):
  63. with sqlite3.connect(database_name) as con:
  64. cur = con.cursor()
  65. cur.execute("SELECT green FROM green_presenting WHERE url=? LIMIT 1",
  66. [domain]
  67. )
  68. res = cur.fetchone()
  69. logger.debug(res)
  70. return bool(res)
  71. def check_against_api(self, domain=None):
  72. api_server = "https://api.thegreenwebfoundation.org"
  73. api_url = f"{api_server}/greencheck/{domain}"
  74. logger.debug(api_url)
  75. response = requests.get(api_url).json()
  76. if response.get("green"):
  77. return True
  78. greencheck = GreenCheck()
  79. # attach callback to the post search hook
  80. # request: flask request object
  81. # ctx: the whole local context of the pre search hook
  82. def post_search(request, search):
  83. green_results = [
  84. entry for entry in list(search.result_container._merged_results)
  85. if get_green(entry)
  86. ]
  87. search.result_container._merged_results = green_results
  88. return True
  89. def get_green(result):
  90. logger.debug(result.get('url'))
  91. green = greencheck.check_url(result.get('url'))
  92. if green:
  93. return True