diff --git a/content.py b/content.py index 80fc3211a..aaa1545a3 100644 --- a/content.py +++ b/content.py @@ -1085,6 +1085,7 @@ def save_media_in_form_post(media_bytes, debug: bool, extension_list = { 'png': 'image/png', 'jpeg': 'image/jpeg', + 'jxl': 'image/jxl', 'gif': 'image/gif', 'svg': 'image/svg+xml', 'webp': 'image/webp', diff --git a/daemon.py b/daemon.py index 27179492a..c3a19c9ea 100644 --- a/daemon.py +++ b/daemon.py @@ -6861,6 +6861,9 @@ class PubServer(BaseHTTPRequestHandler): if 'image/avif' in self.headers['Accept']: fav_type = 'image/avif' fav_filename = fav_filename.split('.')[0] + '.avif' + 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: @@ -6875,6 +6878,8 @@ class PubServer(BaseHTTPRequestHandler): fav_filename = fav_filename.replace('.webp', '.ico') elif fav_filename.endswith('.avif'): fav_filename = fav_filename.replace('.avif', '.ico') + elif fav_filename.endswith('.jxl'): + fav_filename = fav_filename.replace('.jxl', '.ico') if not os.path.isfile(favicon_filename): # default favicon favicon_filename = \ diff --git a/metadata.py b/metadata.py index a115732a7..6dbb88ff6 100644 --- a/metadata.py +++ b/metadata.py @@ -183,6 +183,7 @@ def meta_data_instance(showAccounts: bool, 'media_attachments': { 'supported_mime_types': [ 'image/jpeg', + 'image/jxl', 'image/png', 'image/gif', 'image/webp', diff --git a/newswire.py b/newswire.py index 3e04b4c45..c9734916e 100644 --- a/newswire.py +++ b/newswire.py @@ -164,6 +164,7 @@ def _download_newswire_feed_favicon(session, base_dir: str, 'ico': 'x-icon', 'png': 'png', 'jpg': 'jpeg', + 'jxl': 'jxl', 'gif': 'gif', 'avif': 'avif', 'svg': 'svg+xml', diff --git a/outbox.py b/outbox.py index 95932ebaf..db6e6a690 100644 --- a/outbox.py +++ b/outbox.py @@ -302,6 +302,7 @@ def post_message_to_outbox(session, translate: {}, extensions = { "jpeg": "jpg", + "jxl": "jxl", "gif": "gif", "svg": "svg", "webp": "webp", diff --git a/person.py b/person.py index bf3b54ea3..02f566159 100644 --- a/person.py +++ b/person.py @@ -140,6 +140,9 @@ def set_profile_image(base_dir: str, http_prefix: str, elif image_filename.endswith('.avif'): media_type = 'image/avif' icon_filename = icon_filename_base + '.avif' + elif image_filename.endswith('.jxl'): + media_type = 'image/jxl' + icon_filename = icon_filename_base + '.jxl' elif image_filename.endswith('.svg'): media_type = 'image/svg+xml' icon_filename = icon_filename_base + '.svg' diff --git a/session.py b/session.py index 2ced4f96f..e4c4aa69e 100644 --- a/session.py +++ b/session.py @@ -401,7 +401,7 @@ def post_image(session, attach_image_filename: str, federation_list: [], return None if not is_image_file(attach_image_filename): - print('Image must be png, jpg, webp, avif, gif or svg') + print('Image must be png, jpg, jxl, webp, avif, gif or svg') return None if not os.path.isfile(attach_image_filename): print('Image not found: ' + attach_image_filename) @@ -415,6 +415,8 @@ def post_image(session, attach_image_filename: str, federation_list: [], content_type = 'image/webp' elif attach_image_filename.endswith('.avif'): content_type = 'image/avif' + elif attach_image_filename.endswith('.jxl'): + content_type = 'image/jxl' elif attach_image_filename.endswith('.svg'): content_type = 'image/svg+xml' headers['Content-type'] = content_type @@ -469,6 +471,7 @@ def download_image(session, base_dir: str, url: str, 'png': 'png', 'jpg': 'jpeg', 'jpeg': 'jpeg', + 'jxl': 'jxl', 'gif': 'gif', 'svg': 'svg+xml', 'webp': 'webp', @@ -575,6 +578,7 @@ def download_image_any_mime_type(session, url: str, 'ico': 'x-icon', 'png': 'png', 'jpg': 'jpeg', + 'jxl': 'jxl', 'jpeg': 'jpeg', 'gif': 'gif', 'svg': 'svg+xml', diff --git a/utils.py b/utils.py index 5b7064ada..5def9ec8f 100644 --- a/utils.py +++ b/utils.py @@ -375,7 +375,7 @@ def get_audio_extensions() -> []: def get_image_extensions() -> []: """Returns a list of the possible image file extensions """ - return ('png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg', 'ico') + return ('png', 'jpg', 'jpeg', 'gif', 'webp', 'avif', 'svg', 'ico', 'jxl') def get_image_mime_type(image_filename: str) -> str: @@ -384,6 +384,7 @@ def get_image_mime_type(image_filename: str) -> str: extensions_to_mime = { 'png': 'png', 'jpg': 'jpeg', + 'jxl': 'jxl', 'gif': 'gif', 'avif': 'avif', 'svg': 'svg+xml', @@ -402,6 +403,7 @@ def get_image_extension_from_mime_type(content_type: str) -> str: image_media = { 'png': 'png', 'jpeg': 'jpg', + 'jxl': 'jxl', 'gif': 'gif', 'svg+xml': 'svg', 'webp': 'webp', @@ -2535,6 +2537,7 @@ def media_file_mime_type(filename: str) -> str: 'json': 'application/json', 'png': 'image/png', 'jpg': 'image/jpeg', + 'jxl': 'image/jxl', 'jpeg': 'image/jpeg', 'gif': 'image/gif', 'svg': 'image/svg+xml', diff --git a/webapp_column_right.py b/webapp_column_right.py index 51527614c..b46473e25 100644 --- a/webapp_column_right.py +++ b/webapp_column_right.py @@ -249,7 +249,8 @@ def _html_newswire(base_dir: str, newswire: {}, nickname: str, moderator: bool, favicon_url = \ cached_favicon_filename.replace(base_dir, '') else: - extensions = ('png', 'jpg', 'gif', 'avif', 'svg', 'webp') + extensions = \ + ('png', 'jpg', 'gif', 'avif', 'svg', 'webp', 'jxl') for ext in extensions: cached_favicon_filename = \ get_fav_filename_from_url(base_dir, favicon_url) diff --git a/webapp_login.py b/webapp_login.py index ddf4308cd..988d47229 100644 --- a/webapp_login.py +++ b/webapp_login.py @@ -85,6 +85,9 @@ def html_login(css_cache: {}, translate: {}, elif os.path.isfile(base_dir + '/accounts/login.avif'): login_image = 'login.avif' login_image_filename = base_dir + '/accounts/' + login_image + elif os.path.isfile(base_dir + '/accounts/login.jxl'): + login_image = 'login.jxl' + login_image_filename = base_dir + '/accounts/' + login_image if not login_image_filename: login_image_filename = base_dir + '/accounts/' + login_image diff --git a/webapp_utils.py b/webapp_utils.py index 9b884f735..3ea3d5c06 100644 --- a/webapp_utils.py +++ b/webapp_utils.py @@ -251,6 +251,7 @@ def update_avatar_image_cache(signing_priv_key_pem: str, image_formats = { 'png': 'png', 'jpg': 'jpeg', + 'jxl': 'jxl', 'jpeg': 'jpeg', 'gif': 'gif', 'svg': 'svg+xml', @@ -998,7 +999,7 @@ def _is_attached_image(attachment_filename: str) -> bool: if '.' not in attachment_filename: return False image_ext = ( - 'png', 'jpg', 'jpeg', 'webp', 'avif', 'svg', 'gif' + 'png', 'jpg', 'jpeg', 'webp', 'avif', 'svg', 'gif', 'jxl' ) ext = attachment_filename.split('.')[-1] if ext in image_ext: