import os import uuid from datetime import datetime, timezone from flask import ( Blueprint, current_app, flash, jsonify, redirect, render_template, request, send_from_directory, url_for, ) from werkzeug.utils import secure_filename from app import Photo, db bp = Blueprint("main", __name__) def allowed_file(filename): return ( "." in filename and filename.rsplit(".", 1)[1].lower() in current_app.config["ALLOWED_EXTENSIONS"] ) @bp.route("/") def index(): photos = Photo.query.order_by(Photo.created_at.desc()).all() total_size = sum(p.file_size for p in photos) return render_template( "index.html", photos=photos, total_photos=len(photos), total_size=total_size, max_upload_mb=current_app.config["MAX_CONTENT_LENGTH"] // (1024 * 1024), ) @bp.route("/upload", methods=["POST"]) def upload(): if "photo" not in request.files: flash("Файл не выбран", "error") return redirect(url_for("main.index")) file = request.files["photo"] if file.filename == "": flash("Файл не выбран", "error") return redirect(url_for("main.index")) if not allowed_file(file.filename): flash("Недопустимый формат. Разрешены: PNG, JPG, GIF, WEBP, BMP", "error") return redirect(url_for("main.index")) ext = file.filename.rsplit(".", 1)[1].lower() stored_name = f"{uuid.uuid4().hex}.{ext}" safe_original = secure_filename(file.filename) or f"photo.{ext}" upload_dir = current_app.config["UPLOAD_FOLDER"] filepath = os.path.join(upload_dir, stored_name) file.save(filepath) file_size = os.path.getsize(filepath) photo = Photo( filename=stored_name, original_name=safe_original, file_size=file_size, mime_type=file.content_type or f"image/{ext}", created_at=datetime.now(timezone.utc), ) db.session.add(photo) db.session.commit() flash("Фото успешно загружено", "success") return redirect(url_for("main.index")) @bp.route("/api/photos") def api_photos(): photos = Photo.query.order_by(Photo.created_at.desc()).all() return jsonify( [ { "id": p.id, "url": p.url, "original_name": p.original_name, "file_size": p.file_size, "size_human": p.size_human, "created_at": p.created_at.isoformat(), } for p in photos ] ) @bp.route("/uploads/") def uploaded_file(filename): return send_from_directory(current_app.config["UPLOAD_FOLDER"], filename) @bp.route("/delete/", methods=["POST"]) def delete_photo(photo_id): photo = Photo.query.get_or_404(photo_id) filepath = os.path.join(current_app.config["UPLOAD_FOLDER"], photo.filename) if os.path.exists(filepath): os.remove(filepath) db.session.delete(photo) db.session.commit() flash("Фото удалено", "success") return redirect(url_for("main.index"))