Files
ViGent2/backend/app/modules/tools/router.py
Kevin Wong b289006844 更新
2026-03-05 17:23:22 +08:00

127 lines
4.6 KiB
Python
Raw Permalink 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 fastapi import APIRouter, Depends, UploadFile, File, Form, HTTPException
from typing import Optional
from urllib.parse import urlparse
import traceback
from loguru import logger
from pydantic import BaseModel, Field, field_validator
from app.core.deps import get_current_user
from app.core.response import success_response
from app.modules.tools import service
from app.services import creator_scraper
from app.services.creator_scraper import ALLOWED_INPUT_DOMAINS
from app.services.glm_service import glm_service
router = APIRouter()
class AnalyzeCreatorRequest(BaseModel):
url: str = Field(..., description="博主主页链接(仅支持抖音/B站 https 链接)")
@field_validator("url")
@classmethod
def validate_url_format(cls, value: str) -> str:
candidate = value.strip()
if len(candidate) > 500:
raise ValueError("链接过长")
parsed = urlparse(candidate)
if parsed.scheme != "https":
raise ValueError("仅支持 https 链接")
hostname = (parsed.hostname or "").lower()
if hostname not in ALLOWED_INPUT_DOMAINS:
raise ValueError(f"不支持的域名: {hostname}仅支持抖音和B站")
return candidate
class GenerateTopicScriptRequest(BaseModel):
analysis_id: str = Field(..., min_length=8, max_length=80, description="分析结果ID")
topic: str = Field(..., min_length=2, max_length=30, description="选中的话题2-30字")
word_count: int = Field(..., ge=80, le=1000, description="目标字数80-1000")
@router.post("/extract-script")
async def extract_script_tool(
file: Optional[UploadFile] = File(None),
url: Optional[str] = Form(None),
rewrite: bool = Form(True),
custom_prompt: Optional[str] = Form(None),
current_user: dict = Depends(get_current_user),
):
"""独立文案提取工具"""
try:
result = await service.extract_script(file=file, url=url, rewrite=rewrite, custom_prompt=custom_prompt)
return success_response(result)
except ValueError as e:
raise HTTPException(400, str(e))
except HTTPException:
raise
except Exception as e:
logger.error(f"Tool extract failed: {e}")
logger.error(traceback.format_exc())
msg = str(e)
if "Fresh cookies" in msg:
raise HTTPException(500, "下载失败:目标平台开启了反爬验证,请过段时间重试或直接上传视频文件。")
raise HTTPException(500, "文案提取失败,请稍后重试")
@router.post("/analyze-creator")
async def analyze_creator(
req: AnalyzeCreatorRequest,
current_user: dict = Depends(get_current_user),
):
"""分析博主内容并返回热门话题"""
try:
user_id = str(current_user.get("id") or "").strip()
if not user_id:
raise HTTPException(401, "登录状态无效,请重新登录")
creator_result = await creator_scraper.scrape_creator_titles(req.url, user_id=user_id)
titles = creator_result.get("titles") or []
topics = await glm_service.analyze_topics(titles)
analysis_id = creator_scraper.cache_titles(titles, user_id)
return success_response({
"platform": creator_result.get("platform", ""),
"creator_name": creator_result.get("creator_name", ""),
"topics": topics,
"analysis_id": analysis_id,
"fetched_count": creator_result.get("fetched_count", len(titles)),
})
except ValueError as e:
raise HTTPException(400, str(e))
except HTTPException:
raise
except Exception as e:
logger.error(f"Analyze creator failed: {e}")
logger.error(traceback.format_exc())
raise HTTPException(500, "博主内容分析失败,请稍后重试")
@router.post("/generate-topic-script")
async def generate_topic_script(
req: GenerateTopicScriptRequest,
current_user: dict = Depends(get_current_user),
):
"""根据话题生成文案"""
try:
user_id = str(current_user.get("id") or "").strip()
if not user_id:
raise HTTPException(401, "登录状态无效,请重新登录")
titles = creator_scraper.get_cached_titles(req.analysis_id, user_id)
script = await glm_service.generate_script_from_topic(req.topic, req.word_count, titles)
return success_response({"script": script})
except ValueError as e:
raise HTTPException(400, str(e))
except HTTPException:
raise
except Exception as e:
logger.error(f"Generate topic script failed: {e}")
logger.error(traceback.format_exc())
raise HTTPException(500, "文案生成失败,请稍后重试")