117 lines
4.5 KiB
Python
117 lines
4.5 KiB
Python
import streamlit as st
|
||
import time
|
||
from pathlib import Path
|
||
import json
|
||
|
||
from ui_fragments import tab0_data_processing,tab1_asset_generation,tab2_online_video_search,tab3_video_composition
|
||
|
||
# --- 本地模組匯入 ---
|
||
from utils.paths import get_project_paths, SHARED_ASSETS_DIR, PROJECTS_DIR,get_project_list
|
||
import callbacks
|
||
from utils.helpers import get_notion_page_titles
|
||
|
||
|
||
# --- Streamlit UI 設定 ---
|
||
st.set_page_config(layout="wide", page_title="英語影片自動化工作流程")
|
||
|
||
# --- 狀態初始化 ---
|
||
if 'show_video' not in st.session_state:
|
||
st.session_state.show_video = False
|
||
if 'operation_status' not in st.session_state:
|
||
st.session_state.operation_status = {}
|
||
if 'search_query' not in st.session_state:
|
||
st.session_state.search_query = ""
|
||
if 'search_results' not in st.session_state:
|
||
st.session_state.search_results = []
|
||
if 'selected_videos' not in st.session_state:
|
||
st.session_state.selected_videos = {}
|
||
if 'active_preview_id' not in st.session_state:
|
||
st.session_state.active_preview_id = None
|
||
|
||
if 'project' not in st.session_state:
|
||
st.session_state.project = None # 'project' 現在儲存的是 Project 物件或 None
|
||
if 'project_selector' not in st.session_state:
|
||
st.session_state.project_selector = None # 'project_selector' 用來追蹤 selectbox 的狀態
|
||
|
||
# --- UI 介面 ---
|
||
st.title("🎬 英語影片自動化工作流程")
|
||
|
||
# --- 側邊欄 ---
|
||
with st.sidebar:
|
||
st.header("API & Project Control")
|
||
notion_api_key = st.secrets.get("NOTION_API_KEY")
|
||
notion_database_id = st.secrets.get("NOTION_DATABASE_ID")
|
||
google_creds_for_translate_path = st.secrets.get("GOOGLE_CREDS_TRANSLATE_PATH")
|
||
google_creds_for_TTS_path = st.secrets.get("GOOGLE_CREDS_TTS_PATH")
|
||
st.divider()
|
||
|
||
st.header("1. 建立新專案")
|
||
try:
|
||
if notion_api_key and notion_database_id:
|
||
page_titles_map = get_notion_page_titles(notion_api_key, notion_database_id)
|
||
st.session_state.page_titles_map = page_titles_map
|
||
st.selectbox("選擇 Notion 頁面以建立新專案:",
|
||
options=[""] + sorted(list(page_titles_map.keys())),
|
||
key="selected_title")
|
||
|
||
if st.session_state.selected_title:
|
||
st.button(f"從 '{st.session_state.selected_title}' 建立專案",
|
||
on_click=callbacks.callback_create_project) # 綁定到標準回呼
|
||
else:
|
||
st.warning("請在 Streamlit secrets 中設定 Notion API 金鑰和資料庫 ID。")
|
||
except Exception as e:
|
||
st.error(f"無法載入 Notion 頁面: {e}")
|
||
|
||
st.divider()
|
||
|
||
st.header("2. 選擇現有專案")
|
||
|
||
# 1. 介面邏輯變得極簡:直接呼叫工具函式
|
||
existing_projects = sorted(get_project_list())
|
||
|
||
# 2. UI 只負責綁定 key 和 on_change 事件
|
||
st.selectbox(
|
||
"或選擇一個現有專案:",
|
||
options=[""] + existing_projects,
|
||
key="project_selector", # selectbox 的狀態由 st.session_state.project_selector 控制
|
||
on_change=callbacks.callback_set_project, # 綁定到標準回呼
|
||
help="選擇您已經建立的專案。"
|
||
)
|
||
# --- 主畫面 ---# 1. 從 session_state 中獲取 Project 物件。這是與專案互動的唯一入口。
|
||
project = st.session_state.get('project')
|
||
|
||
# 2. 判斷的依據變成了 project 物件是否存在,而不是一個字串。
|
||
if not project:
|
||
# 如果沒有專案,提示使用者。這部分的邏輯是完美的。
|
||
st.info("👈 請在側邊欄建立新專案或選擇一個現有專案以開始。")
|
||
else:
|
||
st.header(f"目前專案:`{project.name}`")
|
||
|
||
tab_names = ["1. 資料處理 & AI 加註", "2. 素材生成", " 線上素材搜尋", "3. 影片合成"]
|
||
active_tab = st.radio("選擇工作流程步驟:",
|
||
options=tab_names,
|
||
key="main_tabs_radio",
|
||
horizontal=True,
|
||
label_visibility="collapsed")
|
||
st.markdown("---")
|
||
|
||
# --- 分頁內容 ---
|
||
# 第一頁,notion及專案資料
|
||
if active_tab == tab_names[0]:
|
||
with st.container(border=True):
|
||
tab0_data_processing.render_tab(project)
|
||
|
||
# 第二頁,音訊字幕
|
||
if active_tab == tab_names[1]:
|
||
tab1_asset_generation.render_tab(project, callbacks)
|
||
|
||
# 第三頁,背景影片搜尋
|
||
if active_tab == tab_names[2]:
|
||
tab2_online_video_search.render_tab(project,callbacks)
|
||
|
||
# 第四頁,影片合成
|
||
if active_tab == tab_names[3]:
|
||
tab3_video_composition.render_tab(project, callbacks)
|
||
|
||
st.divider()
|
||
|