Files
upload-platform/upload/backend/upload_refs/blueprint.py
T

79 lines
3.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Blueprint слоя закачки ссылок через ВМ-буфер."""
import logging
import requests
from flask import Blueprint, jsonify, request
from ..session import (MAX_FILE_BYTES, add_file, configure, create_session,
file_count, get_files)
from .config import PULL_RETRIES, PULL_RETRY_DELAY, VM_UPLOAD_PREFIX
from .pull_file import pull_file
from .safe_name import safe_name
log = logging.getLogger("upload.upload_refs")
def create_upload_refs_blueprint(cfg: dict) -> Blueprint:
"""Создать Blueprint с POST ``/upload_refs``."""
cfg = cfg or {}
prefix = cfg.get("apiPrefix", "/api")
vm_prefix = cfg.get("vmUploadUrl", VM_UPLOAD_PREFIX)
max_file_bytes = cfg.get("maxFileBytes", MAX_FILE_BYTES)
pull_retries = cfg.get("pullRetries", PULL_RETRIES)
pull_delay = cfg.get("pullRetryDelay", PULL_RETRY_DELAY)
pull_timeout = cfg.get("pullTimeout", 120)
configure(max_session_bytes=cfg.get("maxSessionBytes"))
blueprint = Blueprint("upload_refs", __name__, url_prefix=prefix)
@blueprint.route("/upload_refs", methods=["POST"])
def upload_refs():
data = request.get_json(silent=True) or {}
sid = data.get("session") or create_session()
refs = data.get("files") or []
if not isinstance(refs, list) or not refs:
return jsonify({"ok": False, "error": "No files"}), 400
added = 0
try:
with requests.Session() as client:
for ref in refs:
if not isinstance(ref, dict):
continue
name = safe_name(ref.get("name", ""))
url = ref.get("url")
if not name or not isinstance(url, str) or not url.startswith(vm_prefix):
continue
if (ref.get("size") or 0) > max_file_bytes:
_delete(client, url)
continue
content = pull_file(
client, url, max_file_bytes, pull_retries, pull_delay,
pull_timeout, sid=sid, name=name,
)
if not add_file(sid, name, content):
if get_files(sid) is None:
return jsonify({"ok": False, "error": "Session not found"}), 404
_delete(client, url)
continue
_delete(client, url)
added += 1
except Exception as error:
log.error("upload_refs: pull error sid=%s: %r", sid, error)
return jsonify({"ok": False, "error": "Pull failed: %s" % error}), 502
return jsonify({"ok": True, "session": sid, "count": file_count(sid)})
return blueprint
def _delete(client, url: str):
"""Удалить временный объект на ВМ, не ломая основной запрос при сбое."""
try:
client.delete(url, timeout=10)
except Exception:
log.warning("upload_refs: could not delete VM object url=%r", url)