#!/usr/bin/env python3
from pathlib import Path
import json, shutil, subprocess, re
BASE=Path('/data/video-pipeline/Channel-Loi-Co-Nhan/project')
TEMPLATE=BASE/'13062026-070-Anh-Em-Ben-Nho-Biet-Nhuong-Phan-Hon'
SAFE=['#loiconhan','#xuhuong','#daolycuocsong','#trietlycuocsong','#songtute','#phucduc','#shorts']
BGM_MAIN='/data/video-pipeline/Channel-Loi-Co-Nhan/data/bgm/paulyudin-sentimental-story-182512.mp3'
BGM_YT='/data/video-pipeline/Channel-Loi-Co-Nhan/data/bgm/Borderless-Aakash-Gandhi.mp3'
PROMPT="vertical 9:16, co phong giay vang, aged yellow parchment, ink-wash cinematic historical illustration, muted ochre brown charcoal palette, antique paper grain. Ancient Vietnamese moral story scene: {beat}. Clear mobile composition, warm dignified mood. Negative exclusions: no modern objects, no modern clothing, no modern house, no cars, no motorbikes, no phones, no electric lights, no plastic, no Western/European faces, no medieval European armor, no Chinese opera costume, no Japanese samurai, no fantasy armor, no sci-fi, no neon, no glossy fantasy poster, no photorealistic modern scene, no 3D/game render, no anime, no cartoon, no text, no logo, no watermark."
def run(cmd):
 print('RUN',' '.join(map(str,cmd)), flush=True); subprocess.check_call(list(map(str,cmd)), cwd='/data/video-pipeline/Channel-Loi-Co-Nhan')
def setup(pid,slug,title,desc,topic,scenes):
 dst=BASE/f'{pid}-{slug}'
 if not dst.exists():
  def ignore(d,names): return [n for n in names if n in {'output','audio','images','logs','subtitles','render_onepass','__pycache__'} or n.endswith('.pyc')]
  shutil.copytree(TEMPLATE,dst,ignore=ignore)
 old=str(TEMPLATE); new=str(dst); oldid=TEMPLATE.name; newid=dst.name
 for p in dst.rglob('*'):
  if p.is_file() and p.suffix in {'.py','.json','.txt','.md'}:
   try: s=p.read_text(encoding='utf-8')
   except UnicodeDecodeError: continue
   s=s.replace(old,new).replace(oldid,newid).replace(BGM_YT,BGM_MAIN).replace('/data/video-pipeline/Channel-Loi-Co-Nhan/data/bgm/Alegend-Peace.mp3',BGM_MAIN).replace("'#loicongday'","'#xuhuong'")
   s=re.sub(r"hashtags = \['#loiconhan', '#xuhuong'\] \+ \[\('#' \+ w\) for w in slug_words\(topic_clean\)\[:4\]\] \+ \['#trietlycuocsong', '#daolycuocsong', '#songcham', '#shorts', '#tiktokvietnam'\]", "hashtags = ['#loiconhan', '#xuhuong', '#daolycuocsong', '#trietlycuocsong', '#songtute', '#phucduc', '#shorts']", s)
   p.write_text(s,encoding='utf-8')
 data={'project_id':dst.name,'title':title,'target_duration_sec':{'min':160,'max':180},'style':'cổ phong, giấy vàng','metadata':{'youtube_title':title,'description':desc,'hashtags':SAFE,'topic_sentence':topic,'word_count_estimate':600},'total_scenes':14,'scenes':[]}
 for i,(summary,narr,beat) in enumerate(scenes,1):
  data['scenes'].append({'scene_id':f'scene_{i:03d}','type':'visual_beat','summary':summary,'narration':narr,'visual_beat':beat,'estimated_seconds':10 if i==14 else 9,'visual_prompt':PROMPT.format(beat=beat)})
 (dst/'script/scenes.json').write_text(json.dumps(data,ensure_ascii=False,indent=2),encoding='utf-8')
 src=dst/'scripts_worker_rebuild_strict.py'; yt=dst/'scripts_worker_rebuild_yt.py'
 yt.write_text(src.read_text(encoding='utf-8').replace(BGM_MAIN,BGM_YT).replace("FINAL = PROJECT / 'output/final/final_video.mp4'", "FINAL = PROJECT / 'output/final/final_video-yt.mp4'"),encoding='utf-8')
 return dst
def fix_info(p):
 info=p/'output/info.json'; data=json.loads(info.read_text(encoding='utf-8'))
 topic=(data.get('title') or data.get('upload_title') or p.name).split('|')[0].strip().rstrip('.'); desc=data.get('description') or ''
 data['hashtags']=SAFE[:]; data['caption']=topic+'. '+' '.join(SAFE)
 sm=data.setdefault('social_meta',{}); y=sm.setdefault('youtube',{}); y.setdefault('title',data.get('upload_title') or data.get('title') or topic); y['description']=(desc+'\n\n' if desc else '')+' '.join(SAFE); y['category']=y.get('category','Education')
 if isinstance(data.get('tags'),list): y['tags']=data['tags'][:7]
 sm['tiktok']={'caption':data['caption']}; sm['facebook_reels']={'caption':f'Cổ nhân dạy: {topic}.\n\n'+' '.join(SAFE)}; sm['instagram_reels']={'caption':f'{topic}.\n\n'+' '.join(SAFE)}
 data['final_video']=str(p/'output/final/final_video.mp4'); data['final_video_yt']=str(p/'output/final/final_video-yt.mp4')
 data['public_link']=f'https://mediareel.pain.io.vn/Channel-Loi-Co-Nhan/project/{p.name}/output/final/final_video.mp4'; data['public_url']=data['public_link']
 data['public_link_yt']=f'https://mediareel.pain.io.vn/Channel-Loi-Co-Nhan/project/{p.name}/output/final/final_video-yt.mp4'; data['public_url_yt']=data['public_link_yt']; data['bgm_main']=BGM_MAIN; data['bgm_yt']=BGM_YT
 info.write_text(json.dumps(data,ensure_ascii=False,indent=2),encoding='utf-8')
def produce(p):
 run(['python3',p/'scripts_complete_short_project.py']); run(['python3',p/'scripts_run_asr_and_build_subtitles.py']); run(['python3',p/'scripts_worker_rebuild_strict.py']); run(['python3',p/'scripts_worker_rebuild_yt.py']); fix_info(p); print('DONE_PROJECT',p,flush=True)
S71=[('Đừng để tiền bạc ngồi trên tình nghĩa','Cổ nhân dạy, tiền bạc là vật cần dùng, nhưng nếu đặt cao hơn tình nghĩa thì lòng người sẽ lạnh. Có người vì một món nợ nhỏ mà quên ân sâu, vì một phần lợi mỏng mà mất đi người thân.','ancient family table with coins pushed aside from warm hands'),('Tiền rõ ràng thì tình bớt rạn','Trong nhà hay ngoài đời, tiền bạc càng thân càng cần rõ. Vay thì nhớ trả, hứa thì ghi lòng, giúp thì nói cho minh bạch. Rõ ràng không làm tình xa, mà giúp tình khỏi bị nghi ngờ ăn mòn.','old ledger and tea on wooden table, relatives speaking calmly'),('Đừng lấy ơn nghĩa để ép người','Giúp ai một lần rồi đem ra nhắc mãi, ơn ấy sẽ thành dây trói. Người tử tế giúp trong khả năng, không dùng món tiền cũ để bắt người khác cúi đầu. Ơn nghĩa chỉ đẹp khi còn có tự trọng.','helping hand releasing rope of old debt in village courtyard'),('Vay mượn phải giữ chữ tín','Một đồng vay cũng mang theo lòng tin của người cho mượn. Trả đúng hẹn là giữ mặt mình, trả chậm phải nói thật là giữ lòng người. Im lặng khi mắc nợ là cách nhanh nhất làm tình nghĩa sứt mẻ.','villager returning coin pouch respectfully under lantern'),('Người cho vay cũng nên giữ lòng mềm','Có lúc người thân gặp khó thật sự. Đòi tiền là quyền, nhưng đòi bằng lời cay nghiệt sẽ làm tình thân khó trở lại. Người có phúc biết giữ công bằng mà không đánh rơi lòng nhân.','elder speaking gently beside small debt scroll'),('Đừng khoe tiền để làm người khác tủi','Trong họ hàng, trong xóm làng, người có của càng nên khiêm. Khoe một chút có thể làm người nghèo thấy tủi, làm trẻ nhỏ học thói so đo. Của cải biết giấu bớt thì phúc biết ở lâu.','wealthy villager covering fine cloth modestly near humble neighbors'),('Của cho không bằng cách cho','Cho người thân ít tiền mà lời nói khinh bạc thì như cho thêm vết thương. Cho vừa sức, nói mềm, giữ thể diện cho người nhận, món giúp đỡ mới thành phúc chứ không thành gánh nặng.','hand offering rice and coins respectfully without looking down'),('Đừng bán rẻ nghĩa thân vì lợi trước mắt','Có những mối quan hệ mất rồi không mua lại được. Một lần tham lợi, một lần lật lời, một lần tính toán quá tay có thể làm cánh cửa tình nghĩa đóng rất lâu. Lợi nhỏ trước mắt đừng đổi lấy đường về.','closed ancestral gate with scattered coins on path'),('Làm ăn chung cần phân minh','Anh em bạn bè làm ăn chung, ban đầu quý nhau nên ngại nói rõ. Nhưng càng ngại, sau này càng dễ oán. Phần vốn, phần công, phần lời, phần lỗ phải nói từ đầu. Minh bạch là hàng rào giữ tình.','two partners measuring grain sacks and writing fair agreement'),('Giàu nghèo đều cần nhân hậu','Người giàu đừng cậy của mà xem nhẹ người nghèo. Người nghèo cũng đừng vì thiếu mà sinh lòng đố kỵ. Giàu nghèo là cảnh, nhân hậu mới là nết. Giữ được nết thì lúc nào cũng còn phúc.','rich and poor villagers bowing equally beside temple steps'),('Đừng để con trẻ học thói trọng tiền','Nếu người lớn trong nhà câu nào cũng nói tiền, việc gì cũng cân tiền, trẻ nhỏ sẽ tưởng giá trị con người nằm trong túi bạc. Hãy dạy con biết quý lao động, quý chữ tín, quý tình nghĩa hơn món lợi.','children watching elder place book and rice above coins'),('Tiêu tiền cũng là nhìn nết người','Có người có tiền liền hoang phí, có người có ít vẫn biết lo trước sau. Tiền vào tay ai sẽ lộ nết người ấy. Người biết tiêu đúng, giúp đúng, giữ đúng, thì tiền mới không làm hỏng tâm mình.','balanced scale with coin pouch and simple rice bowl'),('Còn nghĩa thì còn đường làm lại','Tiền mất có thể kiếm lại, nhưng lòng tin mất thì khó hồi sinh. Khi gặp chuyện tiền bạc, hãy chừa cho nhau một con đường tử tế. Còn giữ được nghĩa, ngày sau còn có thể nhìn mặt nhau.','two old friends repairing broken bridge over stream'),('Đặt nghĩa trên tiền thì phúc ở lại','Tiền bạc đến rồi đi, của cải tụ rồi tan. Chỉ có lòng tử tế, chữ tín và cách đối đãi đàng hoàng mới theo người ta lâu. Đừng để tiền bạc làm lạnh tình nghĩa, vì giữ được nghĩa là giữ được phúc.','warm ancestral home lit by lanterns while coins rest quietly outside')]
S72=[('Đừng để sĩ diện che mất đường sửa','Cổ nhân dạy, người giữ sĩ diện quá nặng thường khó sửa mình. Một lời góp ý nhỏ cũng thấy như bị làm nhục, một lỗi nhỏ cũng cố che cho kín. Nhưng càng che lỗi, lỗi càng lớn.','ancient scholar hiding cracked mirror behind sleeve'),('Biết nhận sai là mở cửa phúc','Nhận sai không làm con người thấp đi. Trái lại, đó là lúc tâm mình có đường sáng. Người dám nói ta chưa đúng, ta xin sửa, thường được người khác nể hơn kẻ cố thắng bằng lời quanh co.','person bowing before open gate with morning light'),('Sĩ diện làm lời xin lỗi nghẹn lại','Có những mối quan hệ chỉ cần một câu xin lỗi là ấm lại, nhưng vì sĩ diện, người ta im lặng đến mức xa nhau. Cái tôi được giữ, tình nghĩa thì mất. Đó là cái giá rất đắt.','two relatives separated by thin wall, unsaid apology like dim lantern'),('Lỗi nhỏ sửa sớm thì nhẹ','Một vết nứt trên chum nếu vá sớm còn dùng được. Một lỗi nhỏ nếu nhận sớm còn dễ thương lượng. Đợi đến khi mọi chuyện vỡ ra, lời xin lỗi cũng khó đủ sức gom lại.','old clay jar with small crack being repaired carefully'),('Đừng sợ mất mặt trước người thân','Trước người thân, điều quý nhất không phải là lúc nào cũng đúng, mà là còn thật lòng với nhau. Cha mẹ, vợ chồng, anh em cần sự chân thành hơn cần vẻ ngoài hoàn hảo.','family sitting in honest conversation under ancestral lamp'),('Người góp ý cũng phải giữ lòng mềm','Muốn người khác sửa, lời góp ý phải có tình. Nói đúng mà cay nghiệt sẽ làm người nghe dựng tường. Nói mềm mà rõ, người có lỗi mới còn đường bước xuống.','elder giving gentle advice beside bamboo courtyard'),('Càng có tuổi càng cần biết sửa','Có người lớn tuổi rồi nghĩ mình không cần nghe ai. Nhưng tuổi tác chỉ đáng kính khi đi cùng lòng khiêm. Người già còn biết sửa mình sẽ để lại gia phong sáng hơn mọi lời răn dạy.','elder placing old cane down and listening humbly'),('Con trẻ kính người biết nhận lỗi','Trẻ nhỏ không mất lòng kính trọng khi thấy người lớn xin lỗi. Chúng chỉ học được rằng ai cũng có thể sai và ai cũng nên sửa. Một câu xin lỗi của cha mẹ có khi dạy con sâu hơn trăm câu đạo lý.','parent apologizing to child in warm old home'),('Cái tôi càng lớn lòng càng chật','Người luôn sợ thua một câu thường sống rất mệt. Ai góp ý cũng chống, ai nhắc cũng giận, ai đúng hơn cũng ghét. Cái tôi càng lớn thì lòng càng chật, phúc khí khó vào.','large shadow of ego blocking small doorway of light'),('Lùi một bước để nhìn rõ mình','Khi bị nhắc lỗi, đừng vội phản bác. Lùi lại một bước, hỏi mình có phần nào đúng không. Người biết tự xét sẽ biến lời khó nghe thành thuốc, người chỉ biết giận sẽ biến thuốc thành độc.','traveler stepping back to see reflection in calm water'),('Sửa mình trong im lặng cũng quý','Không phải lỗi nào cũng cần nói nhiều. Có khi điều cần nhất là âm thầm đổi cách làm, đổi giọng nói, đổi thói quen. Người nhà sẽ cảm được sự thay đổi thật hơn lời hứa dài.','quiet person sweeping courtyard at dawn as sign of change'),('Đừng dùng quá khứ tốt để che hiện tại sai','Từng làm nhiều điều tốt không có nghĩa hiện tại không thể sai. Công lao cũ đáng nhớ, nhưng không nên dùng để bịt miệng người góp ý. Người có phúc biết giữ công cũ bằng cách sửa lỗi mới.','old merit scroll beside fresh footprint corrected on path'),('Khi sửa được mình, oán khí tự tan','Nhiều chuyện trong nhà không cần tranh ai thắng. Chỉ cần một người chịu hạ cái tôi, chịu sửa một thói xấu, không khí đã khác. Sửa mình là cách lặng lẽ dập tắt nhiều cơn sóng.','storm clouds clearing over peaceful family courtyard'),('Bỏ sĩ diện để giữ phúc','Sĩ diện giữ được một khoảnh khắc, nhưng khiêm nhường giữ được cả đường dài. Đừng vì sợ mất mặt mà mất người, mất nghĩa, mất cơ hội sửa mình. Người bỏ được sĩ diện, phúc mới có chỗ trở về.','humble figure opening both hands as lanterns return to ancestral home')]
projects=[('13062026-071','Dung-De-Tien-Bac-Lam-Lanh-Tinh-Nghia','Đừng để tiền bạc làm lạnh tình nghĩa | Lời cổ nhân dạy','Cổ nhân dạy: tiền bạc cần rõ ràng, nhưng tình nghĩa cần được giữ ấm. Đừng vì một phần lợi nhỏ mà làm lạnh lòng người và hao tổn phúc phần.','Đừng để tiền bạc làm lạnh tình nghĩa',S71),('13062026-072','Bo-Duoc-Si-Dien-Phuc-Moi-Tro-Ve','Bỏ được sĩ diện, phúc mới trở về | Lời cổ nhân dạy','Cổ nhân dạy: người biết bỏ sĩ diện để nhận sai và sửa mình thì phúc mới có đường trở về. Giữ mặt mũi nhất thời đừng để mất tình nghĩa lâu dài.','Bỏ được sĩ diện, phúc mới trở về',S72)]
for spec in projects:
 p=setup(*spec); produce(p)
print('ALL_DONE')
