__filename__ = "daemon_get_favicon.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.5.0" __maintainer__ = "Bob Mottram" __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Core GET" import os import urllib.parse from fitnessFunctions import fitness_performance from httpheaders import set_headers_etag from httpcodes import write2 from httpcodes import http_304 from httpcodes import http_404 from daemon_utils import has_accept from daemon_utils import etag_exists from utils import get_config_param from utils import media_file_mime_type from utils import binary_is_image def get_favicon(self, calling_domain: str, base_dir: str, debug: bool, fav_filename: str) -> None: """Return the site favicon or default newswire favicon """ fav_type = 'image/x-icon' if has_accept(self, calling_domain): if 'image/webp' in self.headers['Accept']: fav_type = 'image/webp' fav_filename = fav_filename.split('.')[0] + '.webp' if 'image/avif' in self.headers['Accept']: fav_type = 'image/avif' fav_filename = fav_filename.split('.')[0] + '.avif' if 'image/heic' in self.headers['Accept']: fav_type = 'image/heic' fav_filename = fav_filename.split('.')[0] + '.heic' if 'image/jxl' in self.headers['Accept']: fav_type = 'image/jxl' fav_filename = fav_filename.split('.')[0] + '.jxl' if not self.server.theme_name: self.theme_name = get_config_param(base_dir, 'theme') if not self.server.theme_name: self.server.theme_name = 'default' # custom favicon favicon_filename = \ base_dir + '/theme/' + self.server.theme_name + \ '/icons/' + fav_filename if not fav_filename.endswith('.ico'): if not os.path.isfile(favicon_filename): if fav_filename.endswith('.webp'): fav_filename = fav_filename.replace('.webp', '.ico') elif fav_filename.endswith('.avif'): fav_filename = fav_filename.replace('.avif', '.ico') elif fav_filename.endswith('.heic'): fav_filename = fav_filename.replace('.heic', '.ico') elif fav_filename.endswith('.jxl'): fav_filename = fav_filename.replace('.jxl', '.ico') if not os.path.isfile(favicon_filename): # default favicon favicon_filename = \ base_dir + '/theme/default/icons/' + fav_filename if etag_exists(self, favicon_filename): # The file has not changed if debug: print('favicon icon has not changed: ' + calling_domain) http_304(self) return if self.server.iconsCache.get(fav_filename): fav_binary = self.server.iconsCache[fav_filename] set_headers_etag(self, favicon_filename, fav_type, fav_binary, None, self.server.domain_full, False, None) write2(self, fav_binary) if debug: print('Sent favicon from cache: ' + calling_domain) return if os.path.isfile(favicon_filename): fav_binary = None try: with open(favicon_filename, 'rb') as fav_file: fav_binary = fav_file.read() except OSError: print('EX: unable to read favicon ' + favicon_filename) if fav_binary: set_headers_etag(self, favicon_filename, fav_type, fav_binary, None, self.server.domain_full, False, None) write2(self, fav_binary) self.server.iconsCache[fav_filename] = fav_binary if debug: print('Sent favicon from file: ' + calling_domain) return if debug: print('favicon not sent: ' + calling_domain) http_404(self, 17) def show_cached_favicon(self, referer_domain: str, path: str, base_dir: str, getreq_start_time) -> None: """Shows a favicon image obtained from the cache """ fav_file = path.replace('/favicons/', '') fav_filename = base_dir + urllib.parse.unquote_plus(path) print('showCachedFavicon: ' + fav_filename) if self.server.favicons_cache.get(fav_file): media_binary = self.server.favicons_cache[fav_file] mime_type = media_file_mime_type(fav_filename) set_headers_etag(self, fav_filename, mime_type, media_binary, None, referer_domain, False, None) write2(self, media_binary) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_show_cached_favicon2', self.server.debug) return if not os.path.isfile(fav_filename): http_404(self, 44) return if etag_exists(self, fav_filename): # The file has not changed http_304(self) return media_binary = None try: with open(fav_filename, 'rb') as av_file: media_binary = av_file.read() except OSError: print('EX: unable to read cached favicon ' + fav_filename) if media_binary: if binary_is_image(fav_filename, media_binary): mime_type = media_file_mime_type(fav_filename) set_headers_etag(self, fav_filename, mime_type, media_binary, None, referer_domain, False, None) write2(self, media_binary) fitness_performance(getreq_start_time, self.server.fitness, '_GET', '_show_cached_favicon', self.server.debug) self.server.favicons_cache[fav_file] = media_binary return else: print('WARN: favicon is not an image ' + fav_filename) http_404(self, 45)