76 lines
2.6 KiB
Python
76 lines
2.6 KiB
Python
"""
|
|
HTTP 上传模块 - 将图片上传到指定服务器
|
|
"""
|
|
import os
|
|
import time
|
|
import logging
|
|
import requests
|
|
from typing import Optional
|
|
import uuid
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ImageUploader:
|
|
"""图片上传器"""
|
|
|
|
def __init__(self, upload_url: str, timeout: int = 30, max_retries: int = 3):
|
|
self.upload_url = upload_url
|
|
self.timeout = timeout
|
|
self.max_retries = max_retries
|
|
|
|
def upload(self, image_path: str, serial_number: str, photo_index: int,
|
|
photo_type: str = "front") -> Optional[str]:
|
|
"""
|
|
上传单张图片
|
|
返回: 服务器返回的消息(成功时),失败返回 None
|
|
"""
|
|
if not os.path.exists(image_path):
|
|
logger.error(f"图片文件不存在: {image_path}")
|
|
return None
|
|
|
|
for attempt in range(self.max_retries):
|
|
try:
|
|
with open(image_path, "rb") as f:
|
|
files = {"file": (os.path.basename(image_path), f, "image/jpeg")}
|
|
data = {
|
|
"serialNumber": serial_number,
|
|
"index": photo_index
|
|
}
|
|
resp = requests.post(
|
|
self.upload_url,
|
|
files=files,
|
|
data=data,
|
|
timeout=self.timeout
|
|
)
|
|
|
|
if resp.status_code == 200:
|
|
logger.info(f"图片上传成功: {serialNumber} #{photo_index} ({photo_type})")
|
|
try:
|
|
return resp.json().get("msg", "success")
|
|
except:
|
|
return resp.text
|
|
else:
|
|
logger.warning(f"上传失败 [{resp.status_code}]: {resp.text[:100]}")
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
logger.warning(f"上传异常 (尝试 {attempt+1}/{self.max_retries}): {e}")
|
|
if attempt < self.max_retries - 1:
|
|
time.sleep(2)
|
|
|
|
logger.error(f"图片上传最终失败: {image_path}")
|
|
return None
|
|
|
|
def upload_batch(self, image_paths: list, serial_number: str,
|
|
start_index: int = 0) -> dict:
|
|
"""批量上传图片"""
|
|
results = []
|
|
for i, path in enumerate(image_paths):
|
|
result = self.upload(path, serial_number, start_index + i)
|
|
results.append({
|
|
"index": start_index + i,
|
|
"path": path,
|
|
"success": result is not None,
|
|
"msg": result
|
|
})
|
|
return results |