|
@@ -1,8 +1,13 @@
|
|
|
+import shutil
|
|
|
import pandas as pd
|
|
|
from pathlib import Path
|
|
|
import zipfile
|
|
|
from io import BytesIO
|
|
|
from chardet.universaldetector import UniversalDetector
|
|
|
+try:
|
|
|
+ from app.aianchor.config import *
|
|
|
+except ImportError:
|
|
|
+ from config import *
|
|
|
|
|
|
DEFAULT_ENCODING = "utf-8"
|
|
|
|
|
@@ -25,9 +30,8 @@ def check_zip(zip_filepath:str):
|
|
|
with zipfile.ZipFile(str(path)) as zf:
|
|
|
filenames = [x for x in zf.namelist() if not x.endswith('/')]
|
|
|
result = guess_codec(filenames)
|
|
|
- true_filenames = [x.encode('cp437').decode(result) for x in zf.namelist() if not x.endswith('/')]
|
|
|
- print(true_filenames)
|
|
|
- scenarios_files = [(x, i) for i, x in enumerate(true_filenames) if Path(x).suffix in [".xlsx", ".csv"] and not Path(x).name.startswith("._") and Path(x).stem != "style"]
|
|
|
+ true_filepaths = [x.encode('cp437').decode(result) for x in zf.namelist() if not x.endswith('/')]
|
|
|
+ scenarios_files = [(Path(x).name, i) for i, x in enumerate(true_filepaths) if Path(x).suffix in [".xlsx", ".csv"] and not Path(x).name.startswith("._") and not Path(x).name.startswith("~$") and Path(x).stem != "style"]
|
|
|
print(scenarios_files)
|
|
|
|
|
|
if len(scenarios_files) == 0:
|
|
@@ -40,31 +44,133 @@ def check_zip(zip_filepath:str):
|
|
|
elif Path(scenarios_files[0][0]).suffix == ".csv":
|
|
|
table = pd.read_csv(BytesIO(f), dtype=object)
|
|
|
table.reset_index(inplace=True)
|
|
|
- print(table)
|
|
|
|
|
|
- stems = [Path(x).stem for x in true_filenames]
|
|
|
+ true_filenames = [(Path(x).name, i) for i, x in enumerate(true_filepaths)]
|
|
|
+ true_stems = [(Path(x).stem, i) for i, x in enumerate(true_filepaths)]
|
|
|
for i in range(len(table)):
|
|
|
# excel 裡的圖檔跟zip裡的檔案要一致
|
|
|
if not table.loc[i, ['素材']].isna().item():
|
|
|
img = table.loc[i, ['素材']].item()
|
|
|
- print(img)
|
|
|
-
|
|
|
img_files = [x.strip() for x in img.split(',')]
|
|
|
for img in img_files:
|
|
|
- print(img)
|
|
|
- n = stems.count(img)
|
|
|
+ if Path(img).suffix:
|
|
|
+ n = len([x for x in true_filenames if x[0] == img])
|
|
|
+ else:
|
|
|
+ n = len([x for x in true_stems if x[0] == img])
|
|
|
if n == 0:
|
|
|
- raise VideoMakerError(f"{img}: no such media file in zip.")
|
|
|
+ raise VideoMakerError(f"{img}: no such img file in zip.")
|
|
|
elif n > 1:
|
|
|
- raise VideoMakerError(f'too many same name media files as {img} in zip')
|
|
|
-
|
|
|
+ raise VideoMakerError(f'too many same name img files as {img} in zip')
|
|
|
+
|
|
|
+ # 需要tts文字或音檔
|
|
|
+ if '字幕' in table.columns and table.loc[i, ['字幕']].isna().item():
|
|
|
+ if '音檔' in table.columns and table.loc[i, ['音檔']].isna().item():
|
|
|
+ raise VideoMakerError(f'text or voice file is needed at scene {i+1}.')
|
|
|
+ voice_file = table.loc[i, ['音檔']].item()
|
|
|
+ if Path(voice_file).suffix:
|
|
|
+ n = len([x for x in true_filenames if x[0]==voice_file])
|
|
|
+ else:
|
|
|
+ n = true_stems.count(voice_file)
|
|
|
+ if n == 0:
|
|
|
+ raise VideoMakerError(f"{voice_file}: no such voice file in zip.")
|
|
|
+ elif n > 1:
|
|
|
+ raise VideoMakerError(f'too many same name voice files as {voice_file} in zip')
|
|
|
+
|
|
|
+ return True
|
|
|
+
|
|
|
+def prepare_workingdir(work_dir_path:str):
|
|
|
+ work_dir_Path = Path(work_dir_path)
|
|
|
+ (work_dir_Path/voice_dir).mkdir(exist_ok=True)
|
|
|
+ (work_dir_Path/caption_dir).mkdir(exist_ok=True)
|
|
|
+ (work_dir_Path/input_dir).mkdir(exist_ok=True)
|
|
|
+ (work_dir_Path/output_dir).mkdir(exist_ok=True)
|
|
|
+ (work_dir_Path/srt_dir).mkdir(exist_ok=True)
|
|
|
+ (work_dir_Path/ai_character_dir).mkdir(exist_ok=True)
|
|
|
+
|
|
|
+def check_and_extract_zip(zip_filepath:str, working_dirpath:str):
|
|
|
+ working_dir_Path = Path(working_dirpath)
|
|
|
+ with zipfile.ZipFile(zip_filepath) as zf:
|
|
|
+ filenames = [x for x in zf.namelist() if not x.endswith('/')]
|
|
|
+ result = guess_codec(filenames)
|
|
|
+ true_filepaths = [x.encode('cp437').decode(result) for x in zf.namelist() if not x.endswith('/')]
|
|
|
+ scenarios_filenames = [(Path(x).name, i) for i, x in enumerate(true_filepaths) if Path(x).suffix in [".xlsx", ".csv"] and not Path(x).name.startswith("._") and not Path(x).name.startswith("~$") and Path(x).stem != "style" ]
|
|
|
+ media_filenames = [(Path(x).name, i) for i, x in enumerate(true_filepaths) if Path(x).suffix not in [".xlsx", ".csv"] and not Path(x).name.startswith("._") and not Path(x).name.startswith("~$")]
|
|
|
+
|
|
|
+ if len(scenarios_filenames) == 0:
|
|
|
+ raise VideoMakerError("no excel or csv file in zip.")
|
|
|
+ if len(scenarios_filenames) > 1:
|
|
|
+ raise VideoMakerError("too many excel or csv file in zip.")
|
|
|
+
|
|
|
+ save_filepath = working_dir_Path / input_dir / scenarios_filenames[0][0]
|
|
|
+ if not save_filepath.exists():
|
|
|
+ with open(save_filepath, 'wb') as output_file: # 建立並開啟新檔案
|
|
|
+ with zf.open(filenames[scenarios_filenames[0][1]], 'r') as origin_file: # 開啟原檔案
|
|
|
+ shutil.copyfileobj(origin_file, output_file) # 將原檔案內容複製到新檔案
|
|
|
+ else:
|
|
|
+ raise VideoMakerError(f"{scenarios_filenames[0]} already exists.")
|
|
|
+
|
|
|
+ f = zf.read(filenames[scenarios_filenames[0][1]])
|
|
|
+ if Path(scenarios_filenames[0][0]).suffix == ".xlsx":
|
|
|
+ table = pd.read_excel(BytesIO(f), dtype=object)
|
|
|
+ elif Path(scenarios_filenames[0][0]).suffix == ".csv":
|
|
|
+ table = pd.read_csv(BytesIO(f), dtype=object)
|
|
|
+ table.reset_index(inplace=True)
|
|
|
+
|
|
|
+ true_filenames = [(Path(x).name, i) for i, x in enumerate(true_filepaths)]
|
|
|
+ true_stems = [(Path(x).stem, i) for i, x in enumerate(true_filepaths)]
|
|
|
+ for i in range(len(table)):
|
|
|
+ # excel 裡的圖檔跟zip裡的檔案要一致
|
|
|
+ if not table.loc[i, ['素材']].isna().item():
|
|
|
+ img = table.loc[i, ['素材']].item()
|
|
|
+ img_files = [x.strip() for x in img.split(',')]
|
|
|
+ for img in img_files:
|
|
|
+ if Path(img).suffix:
|
|
|
+ target_filenames = [x for x in true_filenames if x[0] == img]
|
|
|
+ else:
|
|
|
+ target_filenames = [x for x in true_stems if x[0] == img]
|
|
|
+ if len(target_filenames) == 0:
|
|
|
+ raise VideoMakerError(f"{img}: no such img file in zip.")
|
|
|
+ elif len(target_filenames) > 1:
|
|
|
+ raise VideoMakerError(f'too many same name img files as {img} in zip')
|
|
|
+
|
|
|
+ save_filepath = working_dir_Path / input_dir / true_filenames[target_filenames[0][1]][0]
|
|
|
+ if not save_filepath.exists():
|
|
|
+ with open(save_filepath, 'wb') as output_file: # 建立並開啟新檔案
|
|
|
+ with zf.open(filenames[target_filenames[0][1]], 'r') as origin_file: # 開啟原檔案
|
|
|
+ shutil.copyfileobj(origin_file, output_file) # 將原檔案內容複製到新檔案
|
|
|
+ else:
|
|
|
+ raise VideoMakerError(f"{target_filenames[0][0]} already exists.")
|
|
|
+
|
|
|
# 需要tts文字或音檔
|
|
|
- if not table.loc[i, ['字幕']].isna().item():
|
|
|
- if not '音檔' in table.columns or table.loc[i, ['音檔']].isna().item():
|
|
|
+ if '字幕' in table.columns and table.loc[i, ['字幕']].isna().item():
|
|
|
+ if '音檔' in table.columns and table.loc[i, ['音檔']].isna().item():
|
|
|
raise VideoMakerError(f'text or voice file is needed at scene {i+1}.')
|
|
|
voice_file = table.loc[i, ['音檔']].item()
|
|
|
- n = stems.count(voice_file)
|
|
|
- if n != 1:
|
|
|
- raise VideoMakerError(f"voice file is can't find is zip at scene {i+1}.")
|
|
|
+ if Path(voice_file).suffix:
|
|
|
+ target_filenames = [x for x in true_filenames if x[0] == voice_file]
|
|
|
+ else:
|
|
|
+ target_filenames = [x for x in true_stems if x[0] == voice_file]
|
|
|
+ if len(target_filenames) == 0:
|
|
|
+ raise VideoMakerError(f"{voice_file}: no such voice file in zip.")
|
|
|
+ elif len(target_filenames) > 1:
|
|
|
+ raise VideoMakerError(f'too many same name voice files as {voice_file} in zip')
|
|
|
+
|
|
|
+ save_filepath = working_dir_Path / input_dir / true_filenames[target_filenames[0][1]][0]
|
|
|
+ if not save_filepath.exists():
|
|
|
+ with open(save_filepath, 'wb') as output_file: # 建立並開啟新檔案
|
|
|
+ with zf.open(filenames[target_filenames[0][1]], 'r') as origin_file: # 開啟原檔案
|
|
|
+ shutil.copyfileobj(origin_file, output_file) # 將原檔案內容複製到新檔案
|
|
|
+ else:
|
|
|
+ raise VideoMakerError(f"{target_filenames[0][0]} already exists.")
|
|
|
+
|
|
|
+if __name__ == "__main__":
|
|
|
+ from fire import Fire
|
|
|
+
|
|
|
+ def fire_check_zip(zip_filepath:str):
|
|
|
+ try:
|
|
|
+ if check_zip(zip_filepath):
|
|
|
+ print("passed check_zip")
|
|
|
+ except VideoMakerError as e:
|
|
|
+ print(e)
|
|
|
|
|
|
- return True
|
|
|
+ Fire(fire_check_zip)
|