mirror of https://gitlab.com/bashrc2/epicyon
				
				
				
			
		
			
				
	
	
		
			155 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
__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 self.server.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)
 |