| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- # -*- coding: utf-8 -*-
- """
- C 端拍摄图 MinIO 上传 + 请求图来源解析(8020 serve_card_match_v2 专用公共模块)。
- 从 serve_card_match.py 抽出(那里模块级就加载 MATCHER,不能被 import)。
- 配置读 config.CAPP_MINIO:SDK 走本机 endpoint(127.0.0.1:9000),对外回显 public_base。
- """
- import os
- import re
- import uuid
- import hashlib
- import traceback
- from datetime import datetime
- # 上传文件名白名单(与 serve_card_match._resolve_src 一致):保留调用方原始文件名全链路统一
- _SAFE_FNAME = re.compile(r"[A-Za-z0-9._\-()()一-鿿]+")
- _IMG_EXTS = (".jpg", ".jpeg", ".png", ".webp", ".bmp")
- def upload_to_capp_minio(local_path, name_prefix="capp_front"):
- """C 端拍摄图落到 249 MinIO grading/<prefix>,返回对外 URL;失败返回 None。
- 对象名 = capp_front_<时间戳>.<ext>(与 8000 /match_fields 命名规则一致)。"""
- if not local_path or not os.path.exists(local_path):
- return None
- import config
- cfg = getattr(config, "CAPP_MINIO", None)
- if not cfg:
- return None
- try:
- from minio import Minio
- client = Minio(
- cfg["endpoint"],
- access_key=cfg["access_key"],
- secret_key=cfg["secret_key"],
- secure=bool(cfg.get("secure")),
- )
- ts = datetime.now().strftime("%Y-%m-%d_%H-%M-%S_%f")
- ext = os.path.splitext(local_path)[1].lower()
- if ext not in _IMG_EXTS:
- ext = ".jpg"
- object_name = "%s/%s_%s%s" % (cfg["prefix"], name_prefix, ts, ext)
- ctype = "image/jpeg" if ext in (".jpg", ".jpeg") else "image/%s" % ext.lstrip(".")
- client.fput_object(cfg["bucket"], object_name, local_path, content_type=ctype)
- return "%s/%s/%s" % (cfg["public_base"].rstrip("/"), cfg["bucket"], object_name)
- except Exception:
- traceback.print_exc()
- return None
- def save_upload_to_tmp(blob, filename, tmp_dir):
- """multipart 上传字节落临时文件(推理后删)。返回落盘路径。
- 磁盘名一律加 uuid 短后缀:并发同名上传互踩会导致 A 删文件 B 读 400 /
- 读到半截图 YOLO 秒回空(2026-09-03 压测实锤);缓存 key 按内容 md5,不依赖磁盘名。"""
- raw = os.path.basename((filename or "").replace("\\", "/")).strip()
- if raw and _SAFE_FNAME.fullmatch(raw) and raw.lower().endswith(_IMG_EXTS):
- stem, ext = os.path.splitext(raw)
- else:
- stem, ext = hashlib.md5(blob).hexdigest(), ".jpg"
- dst = os.path.join(tmp_dir, "%s_%s%s" % (stem, uuid.uuid4().hex[:8], ext))
- with open(dst, "wb") as fo:
- fo.write(blob)
- return dst
- def file_md5(path):
- """文件内容 md5(流式读,缓存 key 用)。"""
- h = hashlib.md5()
- with open(path, "rb") as f:
- for chunk in iter(lambda: f.read(1 << 20), b""):
- h.update(chunk)
- return h.hexdigest()
|