Fetch fallback site icons from DDG
DDG provides favicons using the url format icons.duckduckgo.com/ip2/{site}.ico This can be used to fetch favicons in the event that the default "/favicon.ico" path does not work.main
parent
81b7fd1876
commit
7bda165ca3
|
@ -17,7 +17,8 @@ from app.models.config import Config
|
||||||
from app.models.endpoint import Endpoint
|
from app.models.endpoint import Endpoint
|
||||||
from app.request import Request, TorError
|
from app.request import Request, TorError
|
||||||
from app.utils.bangs import resolve_bang
|
from app.utils.bangs import resolve_bang
|
||||||
from app.utils.misc import empty_gif, placeholder_img, get_proxy_host_url
|
from app.utils.misc import empty_gif, placeholder_img, get_proxy_host_url, \
|
||||||
|
fetch_favicon
|
||||||
from app.filter import Filter
|
from app.filter import Filter
|
||||||
from app.utils.misc import read_config_bool, get_client_ip, get_request_url, \
|
from app.utils.misc import read_config_bool, get_client_ip, get_request_url, \
|
||||||
check_for_update
|
check_for_update
|
||||||
|
@ -493,7 +494,8 @@ def element():
|
||||||
# Display an empty gif if the requested element couldn't be retrieved
|
# Display an empty gif if the requested element couldn't be retrieved
|
||||||
if response.status_code != 200 or len(response.content) == 0:
|
if response.status_code != 200 or len(response.content) == 0:
|
||||||
if 'favicon' in src_url:
|
if 'favicon' in src_url:
|
||||||
return send_file(io.BytesIO(placeholder_img), mimetype='image/png')
|
favicon = fetch_favicon(src_url)
|
||||||
|
return send_file(io.BytesIO(favicon), mimetype='image/png')
|
||||||
else:
|
else:
|
||||||
return send_file(io.BytesIO(empty_gif), mimetype='image/gif')
|
return send_file(io.BytesIO(empty_gif), mimetype='image/gif')
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,14 @@ import base64
|
||||||
from bs4 import BeautifulSoup as bsoup
|
from bs4 import BeautifulSoup as bsoup
|
||||||
from flask import Request
|
from flask import Request
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import io
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from requests import exceptions, get
|
from requests import exceptions, get
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
ddg_favicon_site = 'http://icons.duckduckgo.com/ip2'
|
||||||
|
|
||||||
empty_gif = base64.b64decode(
|
empty_gif = base64.b64decode(
|
||||||
'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==')
|
'R0lGODlhAQABAIAAAP///////yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==')
|
||||||
|
|
||||||
|
@ -21,6 +24,29 @@ placeholder_img = base64.b64decode(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_favicon(url: str) -> bytes:
|
||||||
|
"""Fetches a favicon using DuckDuckGo's favicon retriever
|
||||||
|
|
||||||
|
Args:
|
||||||
|
url: The url to fetch the favicon from
|
||||||
|
Returns:
|
||||||
|
bytes - the favicon bytes, or a placeholder image if one
|
||||||
|
was not returned
|
||||||
|
"""
|
||||||
|
domain = urlparse(url).netloc
|
||||||
|
|
||||||
|
response = get(f'{ddg_favicon_site}/{domain}.ico')
|
||||||
|
|
||||||
|
if response.status_code == 200 and len(response.content) > 0:
|
||||||
|
tmp_mem = io.BytesIO()
|
||||||
|
tmp_mem.write(response.content)
|
||||||
|
tmp_mem.seek(0)
|
||||||
|
|
||||||
|
return tmp_mem.read()
|
||||||
|
else:
|
||||||
|
return placeholder_img
|
||||||
|
|
||||||
|
|
||||||
def gen_file_hash(path: str, static_file: str) -> str:
|
def gen_file_hash(path: str, static_file: str) -> str:
|
||||||
file_contents = open(os.path.join(path, static_file), 'rb').read()
|
file_contents = open(os.path.join(path, static_file), 'rb').read()
|
||||||
file_hash = hashlib.md5(file_contents).hexdigest()[:8]
|
file_hash = hashlib.md5(file_contents).hexdigest()[:8]
|
||||||
|
|
Loading…
Reference in New Issue