summaryrefslogtreecommitdiff
path: root/searx/favicon_resolver.py
diff options
context:
space:
mode:
Diffstat (limited to 'searx/favicon_resolver.py')
-rw-r--r--searx/favicon_resolver.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/searx/favicon_resolver.py b/searx/favicon_resolver.py
new file mode 100644
index 000000000..d292d4ce7
--- /dev/null
+++ b/searx/favicon_resolver.py
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+"""This module implements functions needed for the favicon resolver.
+
+"""
+# pylint: disable=use-dict-literal
+
+from httpx import HTTPError
+
+from searx import settings
+
+from searx.network import get as http_get, post as http_post
+from searx.exceptions import SearxEngineResponseException
+
+
+def update_kwargs(**kwargs):
+ if 'timeout' not in kwargs:
+ kwargs['timeout'] = settings['outgoing']['request_timeout']
+ kwargs['raise_for_httperror'] = False
+
+
+def get(*args, **kwargs):
+ update_kwargs(**kwargs)
+ return http_get(*args, **kwargs)
+
+
+def post(*args, **kwargs):
+ update_kwargs(**kwargs)
+ return http_post(*args, **kwargs)
+
+
+def allesedv(domain):
+ """Favicon Resolver from allesedv.com"""
+
+ url = 'https://f1.allesedv.com/32/{domain}'
+
+ # will just return a 200 regardless of the favicon existing or not
+ # sometimes will be correct size, sometimes not
+ response = get(url.format(domain=domain))
+
+ # returns image/gif if the favicon does not exist
+ if response.headers['Content-Type'] == 'image/gif':
+ return []
+
+ return response.content
+
+
+def duckduckgo(domain):
+ """Favicon Resolver from duckduckgo.com"""
+
+ url = 'https://icons.duckduckgo.com/ip2/{domain}.ico'
+
+ # will return a 404 if the favicon does not exist and a 200 if it does,
+ response = get(url.format(domain=domain))
+
+ # api will respond with a 32x32 png image
+ if response.status_code == 200:
+ return response.content
+ return []
+
+
+def google(domain):
+ """Favicon Resolver from google.com"""
+
+ url = 'https://www.google.com/s2/favicons?sz=32&domain={domain}'
+
+ # will return a 404 if the favicon does not exist and a 200 if it does,
+ response = get(url.format(domain=domain))
+
+ # api will respond with a 32x32 png image
+ if response.status_code == 200:
+ return response.content
+ return []
+
+
+def yandex(domain):
+ """Favicon Resolver from yandex.com"""
+
+ url = 'https://favicon.yandex.net/favicon/{domain}'
+
+ # will always return 200
+ response = get(url.format(domain=domain))
+
+ # api will respond with a 16x16 png image, if it doesn't exist, it will be a 1x1 png image (70 bytes)
+ if response.status_code == 200:
+ if len(response.content) > 70:
+ return response.content
+ return []
+
+
+backends = {
+ 'allesedv': allesedv,
+ 'duckduckgo': duckduckgo,
+ 'google': google,
+ 'yandex': yandex,
+}
+
+
+def search_favicon(backend_name, domain):
+ backend = backends.get(backend_name)
+ if backend is None:
+ return []
+ try:
+ return backend(domain)
+ except (HTTPError, SearxEngineResponseException):
+ return []