diff --git a/infra/uploader.py b/infra/uploader.py index d127081..0d81916 100644 --- a/infra/uploader.py +++ b/infra/uploader.py @@ -1,15 +1,14 @@ #!/usr/bin/env python3 -import os, tempfile +import os, tempfile, re from flask import Flask, request, jsonify import boto3 from botocore.client import Config -from botocore.exceptions import ClientError import pillow_heif from PIL import Image pillow_heif.register_heif_opener() app = Flask(__name__) -app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50MB +app.config['MAX_CONTENT_LENGTH'] = 100 * 1024 * 1024 S3_CONFIG = dict( endpoint_url='https://s3.regru.cloud', @@ -19,148 +18,344 @@ S3_CONFIG = dict( config=Config(signature_version='s3v4') ) BUCKET = 'sleeptrip-dev' -PREFIX = 'images/' -ALLOWED = {'jpg', 'jpeg', 'png', 'gif', 'webp', 'mp4', 'mov', 'heic', 'heif'} MIME = { - 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', - 'gif': 'image/gif', 'webp': 'image/webp', - 'mp4': 'video/mp4', 'mov': 'video/quicktime', - 'heic': 'image/jpeg', 'heif': 'image/jpeg' + 'jpg':'image/jpeg','jpeg':'image/jpeg','png':'image/png', + 'gif':'image/gif','webp':'image/webp','mp4':'video/mp4','mov':'video/quicktime', + 'heic':'image/jpeg','heif':'image/jpeg' } +ALLOWED = set(MIME.keys()) -PAGE = """ +PAGE = r""" -Upload to S3 +PTP Post Wizard -
-

Upload → S3

-

sleeptrip-dev · s3.regru.cloud/images/

-
- -
-
Перетащи или выбери файл
-
-
-
-
Загружаем...
-
-
-
-
-
Нажми чтобы скопировать
- -
-
-

История

-
+
+
+

PTP Post Wizard

+
Загрузка фото → готовый пост для Sveltia CMS
+ +
+ + +
+
1. Информация о посте
+
+
+ + +
Название места — как на сайте
+
+
+ + +
+
+
+
+
+ + +
+
+
+ + +
+
+ + +
Следующий свободный: 134
+
+
+
+ + +
+
2. Фотографии
+
Фото автоматически называются slug-YYYYMMDD-N.jpg и загружаются в S3. Первое фото = обложка.
+
+ +
+
Перетащи фото сюда или выбери файлы
+
+
+
+
+
+ + + + +
+ -""" + +""" @app.route('/upload/') @@ -174,6 +369,8 @@ def upload_file(): return jsonify({'error': 'Нет файла'}), 400 f = request.files['file'] + custom_filename = request.form.get('filename', '').strip() + if not f.filename: return jsonify({'error': 'Пустое имя файла'}), 400 @@ -181,22 +378,27 @@ def upload_file(): if ext not in ALLOWED: return jsonify({'error': 'Формат .{} не поддерживается'.format(ext)}), 400 - original_name = os.path.splitext(f.filename)[0] - - # HEIC/HEIF → конвертируем в JPG - is_heic = ext in ('heic', 'heif') - out_ext = 'jpg' if is_heic else ext - s3_key = '{}{}.{}'.format(PREFIX, original_name, out_ext) + # Use custom filename from wizard if provided + if custom_filename: + out_name = custom_filename + out_ext = out_name.rsplit('.', 1)[-1].lower() + else: + original = os.path.splitext(f.filename)[0] + out_ext = 'jpg' if ext in ('heic', 'heif') else ext + out_name = '{}.{}'.format(original, out_ext) + s3_key = 'images/{}'.format(out_name) tmp_path = None + try: with tempfile.NamedTemporaryFile(delete=False, suffix='.{}'.format(ext)) as tmp: f.save(tmp.name) tmp_path = tmp.name - if is_heic: + # HEIC → JPG conversion + if ext in ('heic', 'heif'): img = Image.open(tmp_path) - converted = tmp_path.replace('.{}'.format(ext), '.jpg') + converted = tmp_path.rsplit('.', 1)[0] + '.jpg' img.convert('RGB').save(converted, 'JPEG', quality=92) os.unlink(tmp_path) tmp_path = converted @@ -208,14 +410,13 @@ def upload_file(): s3.upload_file( tmp_path, BUCKET, s3_key, ExtraArgs={ - 'ContentType': MIME.get(ext, 'application/octet-stream'), + 'ContentType': MIME.get(out_ext, 'application/octet-stream'), 'CacheControl': 'max-age=31536000' } ) url = 'https://s3.regru.cloud/{}/{}'.format(BUCKET, s3_key) - # hint: HEIC was converted to JPG - return jsonify({'url': url}) + return jsonify({'url': url, 'filename': out_name}) except Exception as e: return jsonify({'error': str(e)}), 500