카페, 식당 템플릿 적용
parent
76485ebbcc
commit
e53084ed17
|
|
@ -225,29 +225,48 @@ autotext_template_h_1 = {
|
|||
"stroke_color": "#333333",
|
||||
"stroke_width": "0.2 vmin"
|
||||
}
|
||||
DVST0001 = "75161273-0422-4771-adeb-816bd7263fb0"
|
||||
DVST0002 = "c68cf750-bc40-485a-a2c5-3f9fe301e386"
|
||||
DVST0003 = "e1fb5b00-1f02-4f63-99fa-7524b433ba47"
|
||||
DVST0001 = "fe11aeab-ff29-4bc8-9f75-c695c7e243e6"
|
||||
DVRT0001 = "3c4b74c4-82d7-4742-9b05-4b999fef4cbd"
|
||||
DVCF0001 = "ebb532ec-e49a-4a7e-b0e2-a8132f1bf1f7"
|
||||
DHST0001 = "660be601-080a-43ea-bf0f-adcf4596fa98"
|
||||
DHST0002 = "3f194cc7-464e-4581-9db2-179d42d3e40f"
|
||||
DHST0003 = "f45df555-2956-4a13-9004-ead047070b3d"
|
||||
DVST0001T = "fe11aeab-ff29-4bc8-9f75-c695c7e243e6"
|
||||
HST_LIST = [DHST0001,DHST0002,DHST0003]
|
||||
VST_LIST = [DVST0001T]
|
||||
VST_LIST = [DVST0001,DVRT0001,DVCF0001]
|
||||
|
||||
# industry → 세로형 템플릿 매핑 (신규 세로형 템플릿 추가 시 여기에만 등록)
|
||||
VERTICAL_INDUSTRY_TEMPLATE_MAP: dict[str, str] = {
|
||||
"stay": DVST0001,
|
||||
"restaurant": DVRT0001,
|
||||
"cafe": DVCF0001,
|
||||
}
|
||||
|
||||
# 매핑에 없는 업종(salon, clinic 등)의 폴백 템플릿
|
||||
DEFAULT_VERTICAL_TEMPLATE = DVST0001
|
||||
|
||||
SCENE_TRACK = 1
|
||||
AUDIO_TRACK = 2
|
||||
SUBTITLE_TRACK = 3
|
||||
KEYWORD_TRACK = 4
|
||||
|
||||
def select_template(orientation:OrientationType):
|
||||
def select_template(orientation: OrientationType, industry: str | None = None) -> str:
|
||||
"""orientation과 industry에 따라 Creatomate 템플릿 ID를 선택합니다.
|
||||
|
||||
Args:
|
||||
orientation: 영상 방향 ("horizontal" 또는 "vertical")
|
||||
industry: 업종 분류 (stay|restaurant|cafe 등).
|
||||
세로형에서만 사용되며, 매핑에 없으면 기본 템플릿으로 폴백합니다.
|
||||
|
||||
Returns:
|
||||
선택된 템플릿 ID
|
||||
"""
|
||||
if orientation == "horizontal":
|
||||
template_id = DHST0001
|
||||
elif orientation == "vertical":
|
||||
template_id = random.choice(VST_LIST)
|
||||
template_id = VERTICAL_INDUSTRY_TEMPLATE_MAP.get(industry, DEFAULT_VERTICAL_TEMPLATE)
|
||||
else:
|
||||
raise
|
||||
logger.info(f"[select_template] orientation={orientation}, template_id={template_id}")
|
||||
logger.info(f"[select_template] orientation={orientation}, industry={industry}, template_id={template_id}")
|
||||
return template_id
|
||||
|
||||
async def get_shared_client() -> httpx.AsyncClient:
|
||||
|
|
@ -296,21 +315,22 @@ class CreatomateService:
|
|||
def __init__(
|
||||
self,
|
||||
api_key: str | None = None,
|
||||
orientation: OrientationType = "vertical"
|
||||
orientation: OrientationType = "vertical",
|
||||
industry: str | None = None,
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
api_key: Creatomate API 키 (Bearer token으로 사용)
|
||||
None일 경우 config에서 자동으로 가져옴
|
||||
orientation: 영상 방향 ("horizontal" 또는 "vertical", 기본값: "vertical")
|
||||
target_duration: 목표 영상 길이 (초)
|
||||
None일 경우 orientation에 해당하는 기본값 사용
|
||||
industry: 업종 분류 (stay|restaurant|cafe 등). 세로형 템플릿 선택에 사용되며,
|
||||
매핑에 없거나 None이면 기본 세로형 템플릿으로 폴백
|
||||
"""
|
||||
self.api_key = api_key or apikey_settings.CREATOMATE_API_KEY
|
||||
self.orientation = orientation
|
||||
|
||||
# orientation에 따른 템플릿 설정 가져오기
|
||||
self.template_id = select_template(orientation)
|
||||
# orientation·industry에 따른 템플릿 설정 가져오기
|
||||
self.template_id = select_template(orientation, industry=industry)
|
||||
self.headers = {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ class NvMapPwScraper():
|
|||
_context = None
|
||||
_win_width = 1280
|
||||
_win_height = 720
|
||||
_max_retry = 3
|
||||
_timeout = 60 # place id timeout threshold seconds
|
||||
_max_retry = 3
|
||||
_timeout = 30 # place id timeout threshold seconds
|
||||
_retry_delay_ms = 1500 # 검색 실패 후 재시도 전 대기시간 (네이버 요청 밀도 완화)
|
||||
|
||||
# instance var
|
||||
page = None
|
||||
|
|
@ -422,12 +423,14 @@ patchedGetter.toString();''')
|
|||
# 2차 시도: 정제 주소 + 업체명
|
||||
refined = self._refine_address(address)
|
||||
if refined != address:
|
||||
await self.page.wait_for_timeout(self._retry_delay_ms)
|
||||
logger.info(f"[REFINE] 주소 정제: '{address}' → '{refined}'")
|
||||
result = await self._try_search(refined, title)
|
||||
if result:
|
||||
return result
|
||||
|
||||
# 3차 시도: 업체명만으로 검색
|
||||
await self.page.wait_for_timeout(self._retry_delay_ms)
|
||||
logger.info(f"[RETRY] 업체명만으로 재시도: '{title}'")
|
||||
result = await self._try_search("", title)
|
||||
if result:
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ async def generate_video(
|
|||
store_address = project.detail_region_info
|
||||
brand_name = project.store_name
|
||||
region = project.region
|
||||
industry = project.industry
|
||||
|
||||
# MarketingIntel 조회
|
||||
marketing_result = await session.execute(
|
||||
|
|
@ -357,7 +358,8 @@ async def generate_video(
|
|||
f"[generate_video] Stage 2 START - Creatomate API - task_id: {task_id}"
|
||||
)
|
||||
creatomate_service = CreatomateService(
|
||||
orientation=orientation
|
||||
orientation=orientation,
|
||||
industry=industry,
|
||||
)
|
||||
logger.debug(
|
||||
f"[generate_video] Using template_id: {creatomate_service.template_id}, (song duration: {song_duration})"
|
||||
|
|
|
|||
|
|
@ -57,10 +57,8 @@ async def generate_creative_assets_background(
|
|||
|
||||
for attempt in range(1, max_retries + 1):
|
||||
try:
|
||||
creatomate_service = CreatomateService(orientation=orientation)
|
||||
template = await creatomate_service.get_one_template_data(creatomate_service.template_id)
|
||||
|
||||
# ── 프로젝트 / 마케팅 인텔 로드 ──────────────────────────────────
|
||||
# 템플릿 선택에 project.industry가 필요하므로 서비스 생성보다 먼저 로드
|
||||
async with BackgroundSessionLocal() as session:
|
||||
project_result = await session.execute(
|
||||
select(Project)
|
||||
|
|
@ -74,6 +72,9 @@ async def generate_creative_assets_background(
|
|||
)
|
||||
marketing_intelligence = marketing_result.scalar_one_or_none()
|
||||
|
||||
creatomate_service = CreatomateService(orientation=orientation, industry=project.industry)
|
||||
template = await creatomate_service.get_one_template_data(creatomate_service.template_id)
|
||||
|
||||
store_address = project.detail_region_info
|
||||
customer_name = project.store_name
|
||||
language = project.language or "Korean"
|
||||
|
|
|
|||
Loading…
Reference in New Issue