|  |  | @@ -6,6 +6,7 @@ from urllib.parse import unquote | 
			
		
	
		
		
			
				
					
					|  |  |  | from PIL import Image |  |  |  | from PIL import Image | 
			
		
	
		
		
			
				
					
					|  |  |  | from sanic import Blueprint, raw |  |  |  | from sanic import Blueprint, raw | 
			
		
	
		
		
			
				
					
					|  |  |  | from sanic.exceptions import Forbidden, NotFound |  |  |  | from sanic.exceptions import Forbidden, NotFound | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | from sanic.log import logger | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | from cista import config |  |  |  | from cista import config | 
			
		
	
		
		
			
				
					
					|  |  |  | from cista.util.filename import sanitize |  |  |  | from cista.util.filename import sanitize | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -16,7 +17,7 @@ bp = Blueprint("preview", url_prefix="/preview") | 
			
		
	
		
		
			
				
					
					|  |  |  | @bp.get("/<path:path>") |  |  |  | @bp.get("/<path:path>") | 
			
		
	
		
		
			
				
					
					|  |  |  | async def preview(req, path): |  |  |  | async def preview(req, path): | 
			
		
	
		
		
			
				
					
					|  |  |  |     """Preview a file""" |  |  |  |     """Preview a file""" | 
			
		
	
		
		
			
				
					
					|  |  |  |     width = int(req.query_string) if req.query_string else 768 |  |  |  |     width = int(req.query_string) if req.query_string else 1024 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     rel = PurePosixPath(sanitize(unquote(path))) |  |  |  |     rel = PurePosixPath(sanitize(unquote(path))) | 
			
		
	
		
		
			
				
					
					|  |  |  |     path = config.config.path / rel |  |  |  |     path = config.config.path / rel | 
			
		
	
		
		
			
				
					
					|  |  |  |     if not path.is_file(): |  |  |  |     if not path.is_file(): | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -34,6 +35,17 @@ def process_image(path, maxsize): | 
			
		
	
		
		
			
				
					
					|  |  |  |     img = Image.open(path) |  |  |  |     img = Image.open(path) | 
			
		
	
		
		
			
				
					
					|  |  |  |     w, h = img.size |  |  |  |     w, h = img.size | 
			
		
	
		
		
			
				
					
					|  |  |  |     img.thumbnail((min(w, maxsize), min(h, maxsize))) |  |  |  |     img.thumbnail((min(w, maxsize), min(h, maxsize))) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # Fix rotation based on EXIF data | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     try: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         rotate_values = {3: 180, 6: 270, 8: 90} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         exif = img._getexif() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if exif: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             orientation = exif.get(274) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if orientation in rotate_values: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 logger.debug(f"Rotating preview {path} by {rotate_values[orientation]}") | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 img = img.rotate(rotate_values[orientation], expand=True) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     except Exception as e: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         logger.error(f"Error rotating preview image: {e}") | 
			
		
	
		
		
			
				
					
					|  |  |  |     # Save as webp |  |  |  |     # Save as webp | 
			
		
	
		
		
			
				
					
					|  |  |  |     imgdata = io.BytesIO() |  |  |  |     imgdata = io.BytesIO() | 
			
		
	
		
		
			
				
					
					|  |  |  |     img.save(imgdata, format="webp", quality=70, method=6) |  |  |  |     img.save(imgdata, format="webp", quality=70, method=6) | 
			
		
	
	
		
		
			
				
					
					|  |  |   |