Update process generate thumbnails

This commit is contained in:
hlohaus
2025-06-15 12:48:24 +02:00
parent dbef5facb6
commit c6bfddecae
4 changed files with 45 additions and 24 deletions

View File

@@ -20,6 +20,7 @@ class PuterJS(AsyncGeneratorProvider, ProviderModelMixin):
login_url = "https://github.com/HeyPuter/puter-cli" login_url = "https://github.com/HeyPuter/puter-cli"
api_endpoint = "https://api.puter.com/drivers/call" api_endpoint = "https://api.puter.com/drivers/call"
working = True working = True
active_by_default = True
needs_auth = True needs_auth = True
default_model = 'gpt-4o' default_model = 'gpt-4o'

View File

@@ -681,25 +681,13 @@ class Api:
other_name = os.path.join(get_media_dir(), os.path.basename(quote_plus(filename))) other_name = os.path.join(get_media_dir(), os.path.basename(quote_plus(filename)))
if os.path.isfile(other_name): if os.path.isfile(other_name):
target = other_name target = other_name
if thumbnail and has_pillow: result = target
thumbnail_dir = os.path.join(get_media_dir(), "thumbnails")
thumbnail = os.path.join(thumbnail_dir, filename)
try:
if not os.path.isfile(thumbnail):
image = Image.open(target)
os.makedirs(thumbnail_dir, exist_ok=True)
image = process_image(image)
image.save(os.path.join(thumbnail_dir, filename))
except Exception as e:
logger.exception(e)
if os.path.isfile(thumbnail):
target = thumbnail
ext = os.path.splitext(filename)[1][1:] ext = os.path.splitext(filename)[1][1:]
mime_type = EXTENSIONS_MAP.get(ext) mime_type = EXTENSIONS_MAP.get(ext)
stat_result = SimpleNamespace() stat_result = SimpleNamespace()
stat_result.st_size = 0 stat_result.st_size = 0
if os.path.isfile(target): if os.path.isfile(result):
stat_result.st_size = os.stat(target).st_size stat_result.st_size = os.stat(result).st_size
stat_result.st_mtime = int(f"{filename.split('_')[0]}") if filename.startswith("1") else 0 stat_result.st_mtime = int(f"{filename.split('_')[0]}") if filename.startswith("1") else 0
headers = { headers = {
"cache-control": "public, max-age=31536000", "cache-control": "public, max-age=31536000",
@@ -742,10 +730,22 @@ class Api:
debug.error(f"Download failed: {source_url}") debug.error(f"Download failed: {source_url}")
debug.error(e) debug.error(e)
return RedirectResponse(url=source_url) return RedirectResponse(url=source_url)
if not os.path.isfile(target): if thumbnail and has_pillow:
thumbnail_dir = os.path.join(get_media_dir(), "thumbnails")
thumbnail = os.path.join(thumbnail_dir, filename)
try:
if not os.path.isfile(thumbnail):
image = Image.open(target)
os.makedirs(thumbnail_dir, exist_ok=True)
process_image(image, save=os.path.join(thumbnail_dir, filename))
except Exception as e:
logger.exception(e)
if os.path.isfile(thumbnail):
result = thumbnail
if not os.path.isfile(result):
return ErrorResponse.from_message("File not found", HTTP_404_NOT_FOUND) return ErrorResponse.from_message("File not found", HTTP_404_NOT_FOUND)
async def stream(): async def stream():
with open(target, "rb") as file: with open(result, "rb") as file:
while True: while True:
chunk = file.read(65536) chunk = file.read(65536)
if not chunk: if not chunk:

View File

@@ -383,8 +383,7 @@ class Backend_Api(Api):
image = Image.open(copyfile) image = Image.open(copyfile)
thumbnail_dir = os.path.join(bucket_dir, "thumbnail") thumbnail_dir = os.path.join(bucket_dir, "thumbnail")
os.makedirs(thumbnail_dir, exist_ok=True) os.makedirs(thumbnail_dir, exist_ok=True)
image = process_image(image) process_image(image, save=os.path.join(thumbnail_dir, filename))
image.save(os.path.join(thumbnail_dir, filename))
except Exception as e: except Exception as e:
logger.exception(e) logger.exception(e)
elif is_supported: elif is_supported:

View File

@@ -7,6 +7,8 @@ import base64
from io import BytesIO from io import BytesIO
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from collections import defaultdict
try: try:
from PIL.Image import open as open_image, new as new_image from PIL.Image import open as open_image, new as new_image
from PIL.Image import FLIP_LEFT_RIGHT, ROTATE_180, ROTATE_270, ROTATE_90 from PIL.Image import FLIP_LEFT_RIGHT, ROTATE_180, ROTATE_270, ROTATE_90
@@ -14,9 +16,15 @@ try:
has_requirements = True has_requirements = True
except ImportError: except ImportError:
has_requirements = False has_requirements = False
try:
import piexif
has_piexif = True
except ImportError:
has_piexif = False
from ..typing import ImageType, Image from ..typing import ImageType, Image
from ..errors import MissingRequirementsError from ..errors import MissingRequirementsError
from .. import debug
EXTENSIONS_MAP: dict[str, str] = { EXTENSIONS_MAP: dict[str, str] = {
# Image # Image
@@ -201,6 +209,11 @@ def extract_data_uri(data_uri: str) -> bytes:
data = base64.b64decode(data) data = base64.b64decode(data)
return data return data
def get_orientation_key() -> int:
for tag, value in ExifTags.TAGS.items():
if value == 'Orientation':
return tag
def get_orientation(image: Image) -> int: def get_orientation(image: Image) -> int:
""" """
Gets the orientation of the given image. Gets the orientation of the given image.
@@ -212,12 +225,9 @@ def get_orientation(image: Image) -> int:
int: The orientation value. int: The orientation value.
""" """
exif_data = image.getexif() if hasattr(image, 'getexif') else image._getexif() exif_data = image.getexif() if hasattr(image, 'getexif') else image._getexif()
if exif_data: return exif_data.get(get_orientation_key()) if exif_data else None
for tag, value in ExifTags.TAGS.items():
if value == 'Orientation':
return exif_data.get(tag)
def process_image(image: Image, new_width: int = 800, new_height: int = 800) -> Image: def process_image(image: Image, new_width: int = 800, new_height: int = 800, save: str = None) -> Image:
""" """
Processes the given image by adjusting its orientation and resizing it. Processes the given image by adjusting its orientation and resizing it.
@@ -232,6 +242,7 @@ def process_image(image: Image, new_width: int = 800, new_height: int = 800) ->
# Fix orientation # Fix orientation
orientation = get_orientation(image) orientation = get_orientation(image)
if orientation: if orientation:
debug.log(f"Image orientation: {orientation}")
if orientation > 4: if orientation > 4:
image = image.transpose(FLIP_LEFT_RIGHT) image = image.transpose(FLIP_LEFT_RIGHT)
if orientation in [3, 4]: if orientation in [3, 4]:
@@ -251,6 +262,16 @@ def process_image(image: Image, new_width: int = 800, new_height: int = 800) ->
# Convert to RGB for jpg format # Convert to RGB for jpg format
elif image.mode != "RGB": elif image.mode != "RGB":
image = image.convert("RGB") image = image.convert("RGB")
# Remove EXIF data
if has_piexif and save is not None:
try:
exif_dict = piexif.load(image.info["exif"])
except KeyError:
exif_dict = defaultdict(dict)
if exif_dict['Exif']:
exif_dict['Exif'] = {}
elif save is not None:
image.save(save)
return image return image
def to_bytes(image: ImageType) -> bytes: def to_bytes(image: ImageType) -> bytes: