fix
This commit is contained in:
parent
0e12214f60
commit
cd6dcd6863
2 changed files with 149 additions and 39 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
188
app.py
188
app.py
|
|
@ -3,6 +3,7 @@ import base64
|
||||||
import uuid
|
import uuid
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
|
import shutil
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from send2trash import send2trash
|
from send2trash import send2trash
|
||||||
|
|
@ -14,6 +15,95 @@ from PIL import Image, PngImagePlugin
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
|
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
|
||||||
|
|
||||||
|
PREVIEW_MAX_DIMENSION = 1024
|
||||||
|
PREVIEW_JPEG_QUALITY = 85
|
||||||
|
|
||||||
|
try:
|
||||||
|
RESAMPLE_FILTER = Image.Resampling.LANCZOS
|
||||||
|
except AttributeError:
|
||||||
|
if hasattr(Image, 'LANCZOS'):
|
||||||
|
RESAMPLE_FILTER = Image.LANCZOS
|
||||||
|
else:
|
||||||
|
RESAMPLE_FILTER = Image.BICUBIC
|
||||||
|
|
||||||
|
FORMAT_BY_EXTENSION = {
|
||||||
|
'.jpg': 'JPEG',
|
||||||
|
'.jpeg': 'JPEG',
|
||||||
|
'.png': 'PNG',
|
||||||
|
'.webp': 'WEBP',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_extension(ext):
|
||||||
|
if not ext:
|
||||||
|
return '.png'
|
||||||
|
ext = ext.lower()
|
||||||
|
if not ext.startswith('.'):
|
||||||
|
ext = f'.{ext}'
|
||||||
|
return ext
|
||||||
|
|
||||||
|
|
||||||
|
def _format_for_extension(ext):
|
||||||
|
return FORMAT_BY_EXTENSION.get(ext, 'PNG')
|
||||||
|
|
||||||
|
|
||||||
|
def save_compressed_preview(image, filepath, extension):
|
||||||
|
extension = _normalize_extension(extension)
|
||||||
|
image_copy = image.copy()
|
||||||
|
image_copy.thumbnail((PREVIEW_MAX_DIMENSION, PREVIEW_MAX_DIMENSION), RESAMPLE_FILTER)
|
||||||
|
image_format = _format_for_extension(extension)
|
||||||
|
save_kwargs = {}
|
||||||
|
|
||||||
|
if image_format == 'JPEG':
|
||||||
|
if image_copy.mode not in ('RGB', 'RGBA'):
|
||||||
|
image_copy = image_copy.convert('RGB')
|
||||||
|
save_kwargs.update(quality=PREVIEW_JPEG_QUALITY, optimize=True, progressive=True)
|
||||||
|
elif image_format == 'WEBP':
|
||||||
|
save_kwargs.update(quality=PREVIEW_JPEG_QUALITY, method=6)
|
||||||
|
elif image_format == 'PNG':
|
||||||
|
save_kwargs.update(optimize=True)
|
||||||
|
|
||||||
|
image_copy.save(filepath, format=image_format, **save_kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def save_preview_image(preview_dir, extension='.png', source_bytes=None, source_path=None):
|
||||||
|
extension = _normalize_extension(extension)
|
||||||
|
filename = f"template_{uuid.uuid4()}{extension}"
|
||||||
|
filepath = os.path.join(preview_dir, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
image = None
|
||||||
|
if source_bytes is not None:
|
||||||
|
image = Image.open(BytesIO(source_bytes))
|
||||||
|
elif source_path is not None:
|
||||||
|
image = Image.open(source_path)
|
||||||
|
|
||||||
|
if image is not None:
|
||||||
|
save_compressed_preview(image, filepath, extension)
|
||||||
|
return filename
|
||||||
|
elif source_bytes is not None:
|
||||||
|
with open(filepath, 'wb') as f:
|
||||||
|
f.write(source_bytes)
|
||||||
|
return filename
|
||||||
|
elif source_path is not None:
|
||||||
|
shutil.copy2(source_path, filepath)
|
||||||
|
return filename
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"Error saving preview image '{filename}': {exc}")
|
||||||
|
try:
|
||||||
|
if source_bytes is not None:
|
||||||
|
with open(filepath, 'wb') as f:
|
||||||
|
f.write(source_bytes)
|
||||||
|
return filename
|
||||||
|
if source_path is not None:
|
||||||
|
shutil.copy2(source_path, filepath)
|
||||||
|
return filename
|
||||||
|
except Exception as fallback_exc:
|
||||||
|
print(f"Fallback saving preview image failed: {fallback_exc}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
FAVORITES_FILE = os.path.join(os.path.dirname(__file__), 'template_favorites.json')
|
FAVORITES_FILE = os.path.join(os.path.dirname(__file__), 'template_favorites.json')
|
||||||
|
|
||||||
def load_template_favorites():
|
def load_template_favorites():
|
||||||
|
|
@ -399,15 +489,17 @@ def save_template():
|
||||||
if 'preview' in request.files:
|
if 'preview' in request.files:
|
||||||
file = request.files['preview']
|
file = request.files['preview']
|
||||||
if file.filename:
|
if file.filename:
|
||||||
ext = os.path.splitext(file.filename)[1]
|
ext = os.path.splitext(file.filename)[1] or '.png'
|
||||||
if not ext:
|
file.stream.seek(0)
|
||||||
ext = '.png'
|
file_bytes = file.read()
|
||||||
|
preview_filename = save_preview_image(
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
preview_dir=preview_dir,
|
||||||
filepath = os.path.join(preview_dir, filename)
|
extension=ext,
|
||||||
file.save(filepath)
|
source_bytes=file_bytes
|
||||||
|
)
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
|
||||||
|
if preview_filename:
|
||||||
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
|
||||||
# If no file uploaded, check if URL/path provided
|
# If no file uploaded, check if URL/path provided
|
||||||
if not preview_path:
|
if not preview_path:
|
||||||
|
|
@ -433,13 +525,16 @@ def save_template():
|
||||||
parsed = urlparse(preview_url)
|
parsed = urlparse(preview_url)
|
||||||
ext = os.path.splitext(parsed.path)[1] or '.png'
|
ext = os.path.splitext(parsed.path)[1] or '.png'
|
||||||
|
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
preview_filename = save_preview_image(
|
||||||
filepath = os.path.join(preview_dir, filename)
|
preview_dir=preview_dir,
|
||||||
|
extension=ext,
|
||||||
with open(filepath, 'wb') as f:
|
source_bytes=response.content
|
||||||
f.write(response.content)
|
)
|
||||||
|
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
if preview_filename:
|
||||||
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
else:
|
||||||
|
preview_path = preview_url
|
||||||
|
|
||||||
elif preview_url.startswith('/static/'):
|
elif preview_url.startswith('/static/'):
|
||||||
# Local path - copy to preview folder
|
# Local path - copy to preview folder
|
||||||
|
|
@ -448,13 +543,16 @@ def save_template():
|
||||||
|
|
||||||
if os.path.exists(source_path):
|
if os.path.exists(source_path):
|
||||||
ext = os.path.splitext(source_path)[1] or '.png'
|
ext = os.path.splitext(source_path)[1] or '.png'
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
preview_filename = save_preview_image(
|
||||||
dest_path = os.path.join(preview_dir, filename)
|
preview_dir=preview_dir,
|
||||||
|
extension=ext,
|
||||||
import shutil
|
source_path=source_path
|
||||||
shutil.copy2(source_path, dest_path)
|
)
|
||||||
|
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
if preview_filename:
|
||||||
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
else:
|
||||||
|
preview_path = preview_url
|
||||||
else:
|
else:
|
||||||
# File doesn't exist, use original path
|
# File doesn't exist, use original path
|
||||||
preview_path = preview_url
|
preview_path = preview_url
|
||||||
|
|
@ -543,10 +641,16 @@ def update_template():
|
||||||
file = request.files['preview']
|
file = request.files['preview']
|
||||||
if file.filename:
|
if file.filename:
|
||||||
ext = os.path.splitext(file.filename)[1] or '.png'
|
ext = os.path.splitext(file.filename)[1] or '.png'
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
file.stream.seek(0)
|
||||||
filepath = os.path.join(preview_dir, filename)
|
file_bytes = file.read()
|
||||||
file.save(filepath)
|
preview_filename = save_preview_image(
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
preview_dir=preview_dir,
|
||||||
|
extension=ext,
|
||||||
|
source_bytes=file_bytes
|
||||||
|
)
|
||||||
|
|
||||||
|
if preview_filename:
|
||||||
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
|
||||||
if not preview_path:
|
if not preview_path:
|
||||||
preview_url = request.form.get('preview_path')
|
preview_url = request.form.get('preview_path')
|
||||||
|
|
@ -567,13 +671,16 @@ def update_template():
|
||||||
parsed = urlparse(preview_url)
|
parsed = urlparse(preview_url)
|
||||||
ext = os.path.splitext(parsed.path)[1] or '.png'
|
ext = os.path.splitext(parsed.path)[1] or '.png'
|
||||||
|
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
preview_filename = save_preview_image(
|
||||||
filepath = os.path.join(preview_dir, filename)
|
preview_dir=preview_dir,
|
||||||
|
extension=ext,
|
||||||
|
source_bytes=response.content
|
||||||
|
)
|
||||||
|
|
||||||
with open(filepath, 'wb') as f:
|
if preview_filename:
|
||||||
f.write(response.content)
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
else:
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
preview_path = preview_url
|
||||||
|
|
||||||
elif preview_url.startswith('/static/'):
|
elif preview_url.startswith('/static/'):
|
||||||
rel_path = preview_url.split('/static/')[1]
|
rel_path = preview_url.split('/static/')[1]
|
||||||
|
|
@ -581,13 +688,16 @@ def update_template():
|
||||||
|
|
||||||
if os.path.exists(source_path):
|
if os.path.exists(source_path):
|
||||||
ext = os.path.splitext(source_path)[1] or '.png'
|
ext = os.path.splitext(source_path)[1] or '.png'
|
||||||
filename = f"template_{uuid.uuid4()}{ext}"
|
preview_filename = save_preview_image(
|
||||||
dest_path = os.path.join(preview_dir, filename)
|
preview_dir=preview_dir,
|
||||||
|
extension=ext,
|
||||||
|
source_path=source_path
|
||||||
|
)
|
||||||
|
|
||||||
import shutil
|
if preview_filename:
|
||||||
shutil.copy2(source_path, dest_path)
|
preview_path = url_for('static', filename=f'preview/{preview_filename}')
|
||||||
|
else:
|
||||||
preview_path = url_for('static', filename=f'preview/{filename}')
|
preview_path = preview_url
|
||||||
else:
|
else:
|
||||||
preview_path = preview_url
|
preview_path = preview_url
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue