only_show_green_results.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 sqlite3
  20. from urllib.parse import urlparse
  21. logger = logging.getLogger(__name__)
  22. name = gettext('Only show green hosted results')
  23. description = gettext('Any results not being hosted on green infrastructure will be filtered')
  24. default_on = True
  25. preference_section = 'privacy'
  26. allow_api_connections = True
  27. database_name = "url2green.db"
  28. class GreenCheck:
  29. def __init__(self):
  30. try:
  31. self.db = bool(os.stat(database_name))
  32. logger.debug(f"Database found at {database_name}. Using it for lookups instead of the Greencheck API")
  33. except FileNotFoundError:
  34. self.db = False
  35. if allow_api_connections:
  36. logger.debug(f"No database found at {database_name}.")
  37. logger.debug(f"Falling back to the instead of the Greencheck API, as 'allow_api_connections' is set to {allow_api_connections}.")
  38. else:
  39. logger.debug(f"No database found at {database_name}. Not making any checks, because 'allow_api_connections' is set to {allow_api_connections}")
  40. def check_url(self, url=None) -> bool:
  41. """
  42. Check a url passed in, and return a true or false result,
  43. based on whether the domain is marked as a one running on
  44. green energy.
  45. """
  46. try:
  47. parsed_domain = self.get_domain_from_url(url)
  48. except Exception as e:
  49. logger.exception(f"unable to parse url: {url}")
  50. if parsed_domain:
  51. logger.debug(f"Checking {parsed_domain}, parsed from {url}")
  52. if self.db:
  53. return self.check_in_db(parsed_domain)
  54. else:
  55. if allow_api_connections:
  56. return self.check_against_api(parsed_domain)
  57. else:
  58. return False
  59. def get_domain_from_url(self, url=None):
  60. return urlparse(url).hostname
  61. def check_in_db(self, domain=None):
  62. with sqlite3.connect(database_name) as con:
  63. cur = con.cursor()
  64. cur.execute("SELECT green FROM green_presenting WHERE url=? LIMIT 1",
  65. [domain]
  66. )
  67. res = cur.fetchone()
  68. logger.debug(res)
  69. return bool(res)
  70. def check_against_api(self, domain=None):
  71. API_SERVER = "https://api.thegreenwebfoundation.org/"
  72. response = requests.get(f"{API_SERVER}/greencheck/{domain}").json()
  73. if response.get(green):
  74. return True
  75. greencheck = GreenCheck()
  76. # attach callback to the post search hook
  77. # request: flask request object
  78. # ctx: the whole local context of the pre search hook
  79. def post_search(request, search):
  80. logger.debug(search.result_container._merged_results)
  81. green_results = [
  82. entry for entry in list(search.result_container._merged_results)
  83. if get_green(entry)
  84. ]
  85. search.result_container._merged_results = green_results
  86. return True
  87. def get_green(result):
  88. logger.debug(result.get('url'))
  89. green = greencheck.check_url(result.get('url'))
  90. if green:
  91. return True