Files
tw2/qingjian_cs/app/auto_draw.py
codex-bot a64378956a
Some checks failed
Pre-commit / run (ubuntu-latest) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_en (ubuntu-latest, 3.10) (push) Has been cancelled
Deploy Sphinx documentation to Pages / build_zh (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (macos-15, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (ubuntu-latest, 3.12) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.10) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.11) (push) Has been cancelled
Python Unittest Coverage / test (windows-latest, 3.12) (push) Has been cancelled
chore: initialize sandbox and overwrite remote content
2026-03-02 22:32:27 +08:00

132 lines
4.5 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.
from __future__ import annotations
import asyncio
import os
import sys
import tempfile
import uuid
from pathlib import Path
from typing import Any
import requests
from dotenv import load_dotenv
from .config import AUTO_DRAW_ENDPOINT, AUTO_DRAW_TIMEOUT_SECONDS
def _add_legacy_tw_path() -> None:
root = os.getenv("LEGACY_TW_ROOT", r"D:\main\sandbox\tw_terminator").strip()
if not root:
return
p = Path(root)
# 先加载 legacy 项目的 .env确保 service_tuhui_upload 在 import 时拿到正确账号配置
legacy_env = p / ".env"
if legacy_env.exists():
load_dotenv(legacy_env, override=True)
if p.exists() and str(p) not in sys.path:
sys.path.insert(0, str(p))
async def _draw_via_legacy_tw(
image_url: str,
customer_id: str,
requirement: str = "",
) -> dict[str, Any]:
# 优先使用当前项目中拷贝过来的 service_gemini
from services.service_gemini import GeminiExtractV2Service # type: ignore
# 上传模块暂时仍走 legacy你后续可替换为新项目本地上传实现
_add_legacy_tw_path()
from services.service_tuhui_upload import upload_to_tuhui # type: ignore
prompt = requirement.strip() or "按原图做高清修复,保留主体细节,输出清晰可用版本"
# 1) 下载原图到本地临时文件
input_path = os.path.join(tempfile.gettempdir(), f"qjcs_in_{uuid.uuid4().hex}.jpg")
output_path = os.path.join(tempfile.gettempdir(), f"qjcs_out_{uuid.uuid4().hex}.jpg")
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/122.0.0.0 Safari/537.36"
),
"Referer": "https://www.taobao.com/",
"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
}
resp = requests.get(image_url, headers=headers, timeout=AUTO_DRAW_TIMEOUT_SECONDS)
if resp.status_code != 200:
return {"ok": False, "error": f"download_http_{resp.status_code}"}
with open(input_path, "wb") as f:
f.write(resp.content)
# 2) 直调你原来的 service_gemini 作图 API
service = GeminiExtractV2Service()
ok_extract, msg_extract, _ = await service.extract_pattern(
input_path=input_path,
output_path=output_path,
custom_prompt=prompt,
aspect_ratio="1:1",
)
if not ok_extract:
return {"ok": False, "error": f"extract_failed:{msg_extract}"}
if not os.path.exists(output_path):
return {"ok": False, "error": "extract_no_output_file"}
# 3) 上传图绘,返回可外发 URL
ok, link, _ = await upload_to_tuhui(
output_path,
title=f"客户{customer_id[-4:]}-预览图" if customer_id else "预览图",
description="AI自动作图预览",
price=1,
)
if not ok:
return {"ok": False, "error": str(link)}
return {"ok": True, "url": str(link)}
def _draw_via_http_endpoint(image_url: str, customer_id: str, requirement: str = "") -> dict[str, Any]:
if not AUTO_DRAW_ENDPOINT:
return {"ok": False, "error": "AUTO_DRAW_ENDPOINT not configured"}
payload = {
"image_url": image_url,
"customer_id": customer_id,
"requirement": requirement,
}
resp = requests.post(AUTO_DRAW_ENDPOINT, json=payload, timeout=AUTO_DRAW_TIMEOUT_SECONDS)
if resp.status_code != 200:
return {"ok": False, "error": f"http_{resp.status_code}:{resp.text[:200]}"}
data = resp.json() if resp.text else {}
url = str(data.get("url", "") or data.get("preview_url", "") or "")
if not url:
return {"ok": False, "error": "missing_preview_url"}
return {"ok": True, "url": url}
async def auto_draw_preview(
image_url: str,
customer_id: str,
requirement: str = "",
) -> dict[str, Any]:
"""
统一自动作图入口:
1) 优先走 tw_terminator 的 service_gemini 直调链路
2) 失败时回退 AUTO_DRAW_ENDPOINT
"""
try:
return await _draw_via_legacy_tw(image_url=image_url, customer_id=customer_id, requirement=requirement)
except Exception as e:
legacy_error = str(e)
try:
data = await asyncio.to_thread(
_draw_via_http_endpoint,
image_url,
customer_id,
requirement,
)
if data.get("ok"):
return data
return {"ok": False, "error": f"legacy:{legacy_error}; endpoint:{data.get('error','unknown')}"}
except Exception as e:
return {"ok": False, "error": f"legacy:{legacy_error}; endpoint:{e}"}