mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2025-12-22 07:55:56 +00:00
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
"""
|
|
Preview rendering for SSIM screenshot processor.
|
|
|
|
Renders images properly in the browser instead of showing raw bytes.
|
|
"""
|
|
|
|
from loguru import logger
|
|
|
|
|
|
def get_asset(asset_name, watch, datastore, request):
|
|
"""
|
|
Get processor-specific binary assets for preview streaming.
|
|
|
|
This function supports serving images as separate HTTP responses instead
|
|
of embedding them as base64 in the HTML template, solving memory issues
|
|
with large screenshots.
|
|
|
|
Supported assets:
|
|
- 'screenshot': The screenshot for the specified version
|
|
|
|
Args:
|
|
asset_name: Name of the asset to retrieve ('screenshot')
|
|
watch: Watch object
|
|
datastore: Datastore object
|
|
request: Flask request (for version query param)
|
|
|
|
Returns:
|
|
tuple: (binary_data, content_type, cache_control_header) or None if not found
|
|
"""
|
|
if asset_name != 'screenshot':
|
|
return None
|
|
|
|
versions = list(watch.history.keys())
|
|
if len(versions) == 0:
|
|
return None
|
|
|
|
# Get the version from query string (default: latest)
|
|
preferred_version = request.args.get('version')
|
|
timestamp = versions[-1]
|
|
if preferred_version and preferred_version in versions:
|
|
timestamp = preferred_version
|
|
|
|
try:
|
|
screenshot_bytes = watch.get_history_snapshot(timestamp=timestamp)
|
|
|
|
# Convert to bytes if needed
|
|
if isinstance(screenshot_bytes, str):
|
|
screenshot_bytes = screenshot_bytes.encode('utf-8')
|
|
|
|
# Detect image format
|
|
if screenshot_bytes[:8] == b'\x89PNG\r\n\x1a\n':
|
|
mime_type = 'image/png'
|
|
elif screenshot_bytes[:3] == b'\xff\xd8\xff':
|
|
mime_type = 'image/jpeg'
|
|
elif screenshot_bytes[:6] in (b'GIF87a', b'GIF89a'):
|
|
mime_type = 'image/gif'
|
|
elif screenshot_bytes[:4] == b'RIFF' and screenshot_bytes[8:12] == b'WEBP':
|
|
mime_type = 'image/webp'
|
|
else:
|
|
mime_type = 'image/png' # Default fallback
|
|
|
|
return (screenshot_bytes, mime_type, 'public, max-age=3600')
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to load screenshot for preview asset: {e}")
|
|
return None
|
|
|
|
|
|
def render(watch, datastore, request, url_for, render_template, flash, redirect):
|
|
"""
|
|
Render the preview page for screenshot watches.
|
|
|
|
Args:
|
|
watch: Watch object
|
|
datastore: Datastore object
|
|
request: Flask request
|
|
url_for: Flask url_for function
|
|
render_template: Flask render_template function
|
|
flash: Flask flash function
|
|
redirect: Flask redirect function
|
|
|
|
Returns:
|
|
Rendered template or redirect
|
|
"""
|
|
versions = list(watch.history.keys())
|
|
|
|
if len(versions) == 0:
|
|
flash("Preview unavailable - No snapshots captured yet", "error")
|
|
return redirect(url_for('watchlist.index'))
|
|
|
|
# Get the version to display (default: latest)
|
|
preferred_version = request.args.get('version')
|
|
timestamp = versions[-1]
|
|
if preferred_version and preferred_version in versions:
|
|
timestamp = preferred_version
|
|
|
|
# Render custom template for image preview
|
|
# Screenshot is now served via separate /processor-asset/ endpoint instead of base64
|
|
# This significantly reduces memory usage by not embedding large images in HTML
|
|
return render_template(
|
|
'image_ssim_diff/preview.html',
|
|
watch=watch,
|
|
uuid=watch.get('uuid'),
|
|
versions=versions,
|
|
timestamp=timestamp,
|
|
current_diff_url=watch['url']
|
|
)
|