diff --git a/config.py b/config.py index 4496242..562f4be 100644 --- a/config.py +++ b/config.py @@ -8,15 +8,9 @@ PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) # 保存剪映草稿的目录 DRAFT_DIR = os.path.join(PROJECT_ROOT, "output", "draft") -# 日志目录 -LOG_DIR = os.path.join(PROJECT_ROOT, "logs") - # 临时文件目录 TEMP_DIR = os.path.join(PROJECT_ROOT, "temp") -# 视频生成任务完成结果(SQLite 持久化) -VIDEO_GEN_TASK_DB_PATH = os.path.join(PROJECT_ROOT, "db", "video_gen_tasks.sqlite3") - # 视频生成任务:生成视频在 COS 上的可访问保留天数(预签名下载 URL 有效期,环境变量覆盖) VIDEO_GEN_RETENTION_DAYS = max(1, int(os.getenv("VIDEO_GEN_RETENTION_DAYS", "7"))) @@ -29,24 +23,6 @@ DOWNLOAD_URL = os.getenv("DOWNLOAD_URL", "https://capcut-mate.jcaigc.cn/") # 草稿提示URL TIP_URL = os.getenv("TIP_URL", "https://docs.jcaigc.cn/") -# 贴纸配置文件路径 -STICKER_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config", "sticker.json") - -# 花字配置文件路径 -HUAZI_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config", "huazi.json") - -# 文字模板配置文件路径 -TEXT_TEMPLATE_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config", "text_template.json") - -# 气泡配置文件路径 -BUBBLE_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config", "bubble.json") - -# 发光配置文件路径 -GLOW_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config", "glow.json") - -# 模板目录路径 -TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "template") - # 剪映草稿保存路径(下载剪映草稿保存位置)-- 云渲染必需配置 #DRAFT_SAVE_PATH = "C:/Users/Administrator/AppData/Local/JianyingPro/User Data/Projects/com.lveditor.draft" DRAFT_SAVE_PATH = "C:/Users/1/AppData/Local/JianyingPro/User Data/Projects/com.lveditor.draft" diff --git a/src/service/create_draft.py b/src/service/create_draft.py index a7d0983..0c188b3 100644 --- a/src/service/create_draft.py +++ b/src/service/create_draft.py @@ -32,7 +32,7 @@ def create_draft(width: int, height: int) -> str: # 使用模板创建草稿 try: # 复制模板到新草稿目录 - template_path = os.path.join(config.TEMPLATE_DIR, "default2") + template_path = os.path.join(config.PROJECT_ROOT, "template", "default2") draft_path = os.path.join(config.DRAFT_DIR, draft_id) if os.path.exists(draft_path): shutil.rmtree(draft_path) shutil.copytree(template_path, draft_path) diff --git a/src/service/get_text_bubbles.py b/src/service/get_text_bubbles.py index ad7ac83..f48514d 100644 --- a/src/service/get_text_bubbles.py +++ b/src/service/get_text_bubbles.py @@ -18,9 +18,13 @@ (``id`` 为 resource_id, ``effect_id`` 单独给出, 两者缺一不可)。 """ import json +import os from typing import List, Dict, Any, Optional from src.utils.logger import logger -from config import BUBBLE_CONFIG_PATH +from config import PROJECT_ROOT + +# 气泡配置文件路径(固定路径,无需外部配置) +_BUBBLE_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "bubble.json") # 进程启动时加载气泡数据到内存 @@ -63,7 +67,7 @@ def _load_bubble_data() -> None: global _BUBBLE_DATA, _BUBBLE_MAP_BY_NAME, _BUBBLE_MAP_BY_RESOURCE_ID, _BUBBLE_MAP_BY_EFFECT_ID try: - with open(BUBBLE_CONFIG_PATH, "r", encoding="utf-8") as f: + with open(_BUBBLE_CONFIG_PATH, "r", encoding="utf-8") as f: _BUBBLE_DATA = json.load(f) if not isinstance(_BUBBLE_DATA, list): @@ -100,7 +104,7 @@ def _load_bubble_data() -> None: except FileNotFoundError: logger.warning( - f"气泡配置文件不存在: {BUBBLE_CONFIG_PATH}," + f"气泡配置文件不存在: {_BUBBLE_CONFIG_PATH}," f"仅支持传入 \"effect_id:resource_id\" 显式 ID 对" ) _BUBBLE_DATA = [] diff --git a/src/service/get_text_effects.py b/src/service/get_text_effects.py index b3dfb58..bea7166 100644 --- a/src/service/get_text_effects.py +++ b/src/service/get_text_effects.py @@ -2,10 +2,14 @@ 获取花字效果列表和解析花字效果标识符的业务逻辑处理模块 """ import json +import os from typing import List, Dict, Any, Optional from src.utils.logger import logger from exceptions import CustomException, CustomError -from config import HUAZI_CONFIG_PATH +from config import PROJECT_ROOT + +# 花字配置文件路径(固定路径,无需外部配置) +_HUAZI_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "huazi.json") # 进程启动时加载花字数据到内存 @@ -19,7 +23,7 @@ def _load_huazi_data() -> None: global _HUAZI_DATA, _HUAZI_MAP_BY_NAME, _HUAZI_MAP_BY_ID try: - with open(HUAZI_CONFIG_PATH, "r", encoding="utf-8") as f: + with open(_HUAZI_CONFIG_PATH, "r", encoding="utf-8") as f: _HUAZI_DATA = json.load(f) # 构建映射表以便快速查找 diff --git a/src/service/get_text_glows.py b/src/service/get_text_glows.py index c43d2b0..94f6e88 100644 --- a/src/service/get_text_glows.py +++ b/src/service/get_text_glows.py @@ -18,10 +18,14 @@ 格式增补(``id`` 为 resource_id, ``effect_id`` 单独给出, 两者缺一不可)。 """ import json +import os from typing import List, Dict, Any, Optional from src.utils.logger import logger from src.pyJianYingDraft.text_segment import DEFAULT_BLOOM_PARAMS -from config import GLOW_CONFIG_PATH +from config import PROJECT_ROOT + +# 发光配置文件路径(固定路径,无需外部配置) +_GLOW_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "glow.json") # 进程启动时加载发光数据到内存 @@ -65,7 +69,7 @@ def _load_glow_data() -> None: global _GLOW_DATA, _GLOW_MAP_BY_NAME, _GLOW_MAP_BY_RESOURCE_ID, _GLOW_MAP_BY_EFFECT_ID try: - with open(GLOW_CONFIG_PATH, "r", encoding="utf-8") as f: + with open(_GLOW_CONFIG_PATH, "r", encoding="utf-8") as f: _GLOW_DATA = json.load(f) if not isinstance(_GLOW_DATA, list): @@ -102,7 +106,7 @@ def _load_glow_data() -> None: except FileNotFoundError: logger.warning( - f"发光配置文件不存在: {GLOW_CONFIG_PATH}," + f"发光配置文件不存在: {_GLOW_CONFIG_PATH}," f"仅支持传入 \"effect_id:resource_id\" 显式 ID 对" ) _GLOW_DATA = [] diff --git a/src/service/get_text_templates.py b/src/service/get_text_templates.py index d06d5db..1242a0c 100644 --- a/src/service/get_text_templates.py +++ b/src/service/get_text_templates.py @@ -10,9 +10,13 @@ category_name。模板素材本机缓存相关的字段(path/resources/装饰贴 的 VIP 模板在剪映侧可能无法渲染。 """ import json +import os from typing import List, Dict, Any, Optional from src.utils.logger import logger -from config import TEXT_TEMPLATE_CONFIG_PATH +from config import PROJECT_ROOT + +# 文字模板配置文件路径(固定路径,无需外部配置) +_TEXT_TEMPLATE_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "text_template.json") # 进程启动时加载文字模板数据到内存 @@ -45,7 +49,7 @@ def _load_text_template_data() -> None: global _TEXT_TEMPLATE_DATA, _TEXT_TEMPLATE_MAP_BY_NAME, _TEXT_TEMPLATE_MAP_BY_ID try: - with open(TEXT_TEMPLATE_CONFIG_PATH, "r", encoding="utf-8") as f: + with open(_TEXT_TEMPLATE_CONFIG_PATH, "r", encoding="utf-8") as f: _TEXT_TEMPLATE_DATA = json.load(f) if not isinstance(_TEXT_TEMPLATE_DATA, list): @@ -76,7 +80,7 @@ def _load_text_template_data() -> None: except FileNotFoundError: logger.warning( - f"文字模板配置文件不存在: {TEXT_TEMPLATE_CONFIG_PATH}," + f"文字模板配置文件不存在: {_TEXT_TEMPLATE_CONFIG_PATH}," f"仅支持直接传入 effect_id" ) _TEXT_TEMPLATE_DATA = [] diff --git a/src/service/search_sticker.py b/src/service/search_sticker.py index 3cf2423..1fcfa14 100644 --- a/src/service/search_sticker.py +++ b/src/service/search_sticker.py @@ -1,8 +1,12 @@ from src.utils.logger import logger from typing import List, Dict, Any import json -import config +import os import random +from config import PROJECT_ROOT + +# 贴纸配置文件路径(固定路径,无需外部配置) +_STICKER_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "sticker.json") def search_sticker(keyword: str) -> List[Dict[str, Any]]: @@ -19,10 +23,10 @@ def search_sticker(keyword: str) -> List[Dict[str, Any]]: # 从配置文件中读取贴纸数据 try: - with open(config.STICKER_CONFIG_PATH, 'r', encoding='utf-8') as f: + with open(_STICKER_CONFIG_PATH, 'r', encoding='utf-8') as f: sticker_data = json.load(f) except FileNotFoundError: - logger.error(f"Sticker config file not found: {config.STICKER_CONFIG_PATH}") + logger.error(f"Sticker config file not found: {_STICKER_CONFIG_PATH}") return [] except json.JSONDecodeError as e: logger.error(f"Failed to parse sticker config file: {e}") diff --git a/src/utils/logger.py b/src/utils/logger.py index 5f510e5..5449a96 100644 --- a/src/utils/logger.py +++ b/src/utils/logger.py @@ -6,7 +6,8 @@ import sys import config -LOG_DIR = config.LOG_DIR +# 日志目录(固定路径,无需外部配置) +LOG_DIR = os.path.join(config.PROJECT_ROOT, "logs") LOG_FILE = os.path.join(LOG_DIR, "capcut-mate.log") LOG_MAX_BYTES = 20 * 1024 * 1024 # 20MB LOG_BACKUP_COUNT = 10 diff --git a/src/utils/video_task_store.py b/src/utils/video_task_store.py index 5cd0b26..1c2a32e 100644 --- a/src/utils/video_task_store.py +++ b/src/utils/video_task_store.py @@ -14,6 +14,9 @@ from typing import Any, Dict, Optional import config from src.utils.logger import logger +# 任务结果 SQLite 文件路径(固定路径,无需外部配置) +_DB_PATH = os.path.join(config.PROJECT_ROOT, "db", "video_gen_tasks.sqlite3") + _MAX_ROWS = 100_000 _PRUNE_BATCH = 1_000 # 高并发下避免每次状态查询都跑 COUNT/竞争锁;超过间隔才真正检查是否需清理 @@ -24,7 +27,7 @@ _lock = threading.Lock() def _connect() -> sqlite3.Connection: - path = config.VIDEO_GEN_TASK_DB_PATH + path = _DB_PATH os.makedirs(os.path.dirname(path), exist_ok=True) conn = sqlite3.connect(path, check_same_thread=False) conn.row_factory = sqlite3.Row diff --git a/tests/test_add_captions_text_bubble.py b/tests/test_add_captions_text_bubble.py index e0380f0..9351c57 100644 --- a/tests/test_add_captions_text_bubble.py +++ b/tests/test_add_captions_text_bubble.py @@ -9,12 +9,15 @@ sticker_animation 之后)。与花字/文字模板不同,气泡的 effect_id from __future__ import annotations import json +import os -from config import BUBBLE_CONFIG_PATH +from config import PROJECT_ROOT from src.pyJianYingDraft import ScriptFile, TrackType from src.service.add_captions import add_caption_to_draft from src.service.get_text_bubbles import resolve_text_bubble +BUBBLE_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "bubble.json") + # 取自剪映草稿 气泡1:默认文本2 应用的气泡 BUBBLE_NAME = "背景装饰54" BUBBLE_EFFECT_ID = "716434" diff --git a/tests/test_add_captions_text_glow.py b/tests/test_add_captions_text_glow.py index 13dcc15..939e910 100644 --- a/tests/test_add_captions_text_glow.py +++ b/tests/test_add_captions_text_glow.py @@ -13,15 +13,18 @@ extra_material_refs 引用(追加在 sticker_animation 之后)。与气泡 from __future__ import annotations import json +import os import pytest -from config import GLOW_CONFIG_PATH +from config import PROJECT_ROOT from src.pyJianYingDraft import ScriptFile, TrackType from src.pyJianYingDraft.text_segment import DEFAULT_BLOOM_PARAMS from src.service.add_captions import add_caption_to_draft from src.service.get_text_glows import resolve_text_glow +GLOW_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "glow.json") + # 取自 发光 草稿实证的两个预设 OUTER_NAME = "外发光" OUTER_EFFECT_ID = "9762443" diff --git a/tests/test_add_captions_text_template.py b/tests/test_add_captions_text_template.py index e8c6913..8c7c4ea 100644 --- a/tests/test_add_captions_text_template.py +++ b/tests/test_add_captions_text_template.py @@ -8,12 +8,15 @@ text_info_resources[].text_material_id 反向关联。 from __future__ import annotations import json +import os -from config import TEXT_TEMPLATE_CONFIG_PATH +from config import PROJECT_ROOT from src.pyJianYingDraft import ScriptFile, TrackType from src.service.add_captions import add_caption_to_draft from src.service.get_text_templates import resolve_text_template +TEXT_TEMPLATE_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "text_template.json") + TEMPLATE_NAME = "嘎嘎香!红色 简约 美食 情绪表达 字幕" TEMPLATE_ID = "7383613902744980770" diff --git a/tests/test_search_sticker_simple.py b/tests/test_search_sticker_simple.py index 76463d9..2a85453 100644 --- a/tests/test_search_sticker_simple.py +++ b/tests/test_search_sticker_simple.py @@ -14,6 +14,9 @@ import config # 添加项目根目录到 Python 路径 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +# 贴纸配置文件路径(固定路径,无需外部配置) +STICKER_CONFIG_PATH = os.path.join(config.PROJECT_ROOT, "config", "sticker.json") + def search_sticker(keyword: str) -> list: """ @@ -29,10 +32,10 @@ def search_sticker(keyword: str) -> list: # 从配置文件中读取贴纸数据 try: - with open(config.STICKER_CONFIG_PATH, 'r', encoding='utf-8') as f: + with open(STICKER_CONFIG_PATH, 'r', encoding='utf-8') as f: sticker_data = json.load(f) except FileNotFoundError: - print(f"Sticker config file not found: {config.STICKER_CONFIG_PATH}") + print(f"Sticker config file not found: {STICKER_CONFIG_PATH}") return [] except json.JSONDecodeError as e: print(f"Failed to parse sticker config file: {e}")