import os import uuid from datetime import datetime, timezone from werkzeug.utils import secure_filename from app import db from app.models import Photo from app.quota_utils import check_photo_count_limit, check_upload_quota from app.settings_service import get_settings from app.storage_service import save_photo_file def allowed_file(filename, allowed_extensions): return "." in filename and filename.rsplit(".", 1)[1].lower() in allowed_extensions def collect_upload_files(request_files): files = request_files.getlist("photos") if not files or all(f.filename == "" for f in files): single = request_files.get("photo") if single and single.filename: files = [single] return [f for f in files if f and f.filename] def process_uploads(request_files, user, folder, allowed_extensions): settings = get_settings() max_bulk = settings.max_bulk_upload or 100 files = collect_upload_files(request_files) if not files: return {"uploaded": 0, "errors": ["Файлы не выбраны"], "photos": []} if len(files) > max_bulk: return { "uploaded": 0, "errors": [f"Максимум {max_bulk} файлов за раз"], "photos": [], } total_size = 0 valid_files = [] errors = [] for file in files: if not allowed_file(file.filename, allowed_extensions): errors.append(f"{file.filename}: недопустимый формат") continue file.seek(0, os.SEEK_END) size = file.tell() file.seek(0) total_size += size valid_files.append((file, size)) if not valid_files: return {"uploaded": 0, "errors": errors, "photos": []} ok, photo_limit_msg = check_photo_count_limit(user, len(valid_files)) if not ok: return {"uploaded": 0, "errors": [photo_limit_msg], "photos": []} ok, quota_msg = check_upload_quota(user, total_size) if not ok: return {"uploaded": 0, "errors": [quota_msg], "photos": []} uploaded_photos = [] for file, _size in valid_files: ext = file.filename.rsplit(".", 1)[1].lower() stored_name = f"{uuid.uuid4().hex}.{ext}" safe_original = secure_filename(file.filename) or f"photo.{ext}" try: _path, file_size, storage_backend, sync_errors = save_photo_file(file, stored_name) for sync_err in sync_errors: errors.append(f"{safe_original}: {sync_err}") photo = Photo( filename=stored_name, original_name=safe_original, file_size=file_size, mime_type=file.content_type or f"image/{ext}", user_id=user.id, folder_id=folder.id if folder else None, storage_backend=storage_backend, created_at=datetime.now(timezone.utc), ) db.session.add(photo) uploaded_photos.append(photo) except Exception as exc: errors.append(f"{safe_original}: {exc}") if uploaded_photos: db.session.commit() return { "uploaded": len(uploaded_photos), "errors": errors, "photos": uploaded_photos, }