Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import zipfile | |
| import py7zr | |
| import os | |
| import tempfile | |
| import shutil | |
| from datetime import datetime | |
| def process_archives(uploaded_files, position, options, custom_text, pack_mode): | |
| if not uploaded_files: | |
| return [] | |
| processed_files = [] | |
| temp_dir = tempfile.mkdtemp() | |
| current_time_str = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| # 如果是一鍵打包,建立一個共用的資料夾來存放所有重新命名的檔案 | |
| if pack_mode == "一鍵打包": | |
| master_renamed_dir = os.path.join(temp_dir, "master_renamed") | |
| os.makedirs(master_renamed_dir, exist_ok=True) | |
| for file_path in uploaded_files: | |
| filename = os.path.basename(file_path) | |
| ext = os.path.splitext(filename)[1].lower() | |
| # 確保是 zip 或 7z 檔 | |
| if ext not in ['.zip', '.7z']: | |
| continue | |
| archive_basename = os.path.splitext(filename)[0] | |
| extract_dir = os.path.join(temp_dir, f"extracted_{archive_basename}") | |
| os.makedirs(extract_dir, exist_ok=True) | |
| # 根據副檔名選擇解壓縮方式 | |
| try: | |
| if ext == '.zip': | |
| with zipfile.ZipFile(file_path, 'r') as zip_ref: | |
| zip_ref.extractall(extract_dir) | |
| elif ext == '.7z': | |
| with py7zr.SevenZipFile(file_path, mode='r') as z_ref: | |
| z_ref.extractall(path=extract_dir) | |
| except Exception as e: | |
| print(f"無法讀取壓縮檔 {filename}: {e}") | |
| continue | |
| # 決定重新命名後的檔案要放哪裡 | |
| if pack_mode == "個別打包": | |
| renamed_dir = os.path.join(temp_dir, f"{archive_basename}_renamed") | |
| os.makedirs(renamed_dir, exist_ok=True) | |
| else: | |
| renamed_dir = master_renamed_dir | |
| # 組合要增加的文字 | |
| components = [] | |
| if "壓縮檔名" in options: | |
| components.append(archive_basename) | |
| if "日期時間" in options: | |
| components.append(current_time_str) | |
| if "自訂文字" in options and custom_text.strip(): | |
| components.append(custom_text.strip()) | |
| add_str = "_".join(components) | |
| # 重新命名檔案並攤平放到新資料夾 | |
| for root, dirs, files in os.walk(extract_dir): | |
| for f in files: | |
| old_path = os.path.join(root, f) | |
| if not add_str: | |
| new_filename = f | |
| else: | |
| if position == "前綴": | |
| new_filename = f"{add_str}_{f}" | |
| else: | |
| name, file_ext = os.path.splitext(f) | |
| new_filename = f"{name}_{add_str}{file_ext}" | |
| # 防呆機制:避免同名檔案覆蓋 (特別是在一鍵打包時) | |
| new_path = os.path.join(renamed_dir, new_filename) | |
| if os.path.exists(new_path): | |
| name, file_ext = os.path.splitext(new_filename) | |
| counter = 1 | |
| while os.path.exists(os.path.join(renamed_dir, f"{name}_{counter}{file_ext}")): | |
| counter += 1 | |
| new_filename = f"{name}_{counter}{file_ext}" | |
| new_path = os.path.join(renamed_dir, new_filename) | |
| shutil.copy2(old_path, new_path) | |
| # 如果是個別打包,處理完一個壓縮檔就立刻打包 | |
| if pack_mode == "個別打包": | |
| output_archive_name = f"processed_{filename}" | |
| output_archive_path = os.path.join(temp_dir, output_archive_name) | |
| if ext == '.zip': | |
| with zipfile.ZipFile(output_archive_path, 'w', zipfile.ZIP_DEFLATED) as out_zip: | |
| for root, dirs, files in os.walk(renamed_dir): | |
| for f in files: | |
| file_to_zip = os.path.join(root, f) | |
| out_zip.write(file_to_zip, arcname=f) | |
| elif ext == '.7z': | |
| with py7zr.SevenZipFile(output_archive_path, 'w') as out_7z: | |
| for root, dirs, files in os.walk(renamed_dir): | |
| for f in files: | |
| file_to_7z = os.path.join(root, f) | |
| out_7z.write(file_to_7z, arcname=f) | |
| processed_files.append(output_archive_path) | |
| # 如果是一鍵打包,等全部檔案處理完後,統一打包成一個 ZIP | |
| if pack_mode == "一鍵打包": | |
| output_archive_path = os.path.join(temp_dir, "all_processed_files.zip") | |
| with zipfile.ZipFile(output_archive_path, 'w', zipfile.ZIP_DEFLATED) as out_zip: | |
| for root, dirs, files in os.walk(master_renamed_dir): | |
| for f in files: | |
| file_to_zip = os.path.join(root, f) | |
| out_zip.write(file_to_zip, arcname=f) | |
| processed_files.append(output_archive_path) | |
| return processed_files | |
| # 建立 Gradio 網頁介面 | |
| with gr.Blocks(title="壓縮檔內容批次重新命名工具", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("## 📦 壓縮檔內容批次重新命名工具 (支援 ZIP 與 7Z)") | |
| gr.Markdown("上傳 `.zip` 或 `.7z` 檔案後,自訂你想增加的文字與位置,並選擇個別下載或是一鍵打包下載。") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("### ⚙️ 命名規則設定") | |
| position_radio = gr.Radio( | |
| choices=["前綴", "後綴"], | |
| value="前綴", | |
| label="1. 附加位置", | |
| info="前綴:加在檔名最前方 / 後綴:加在副檔名之前" | |
| ) | |
| options_checkbox = gr.CheckboxGroup( | |
| choices=["壓縮檔名", "日期時間", "自訂文字"], | |
| value=["壓縮檔名"], | |
| label="2. 要增加的內容 (可複選)", | |
| info="勾選多項時,會自動以底線「_」連接" | |
| ) | |
| custom_text_input = gr.Textbox( | |
| label="3. 輸入自訂文字", | |
| placeholder="例如:v2", | |
| info="需在上方勾選「自訂文字」才會生效" | |
| ) | |
| pack_mode_radio = gr.Radio( | |
| choices=["個別打包", "一鍵打包"], | |
| value="個別打包", | |
| label="4. 打包方式", | |
| info="個別打包:維持原本的壓縮檔數量 / 一鍵打包:將所有檔案統合成一個 ZIP 檔" | |
| ) | |
| with gr.Column(scale=1): | |
| gr.Markdown("### 📂 檔案上傳與下載") | |
| file_input = gr.File(label="上傳壓縮檔 (可多選 ZIP 或 7Z)", file_count="multiple", type="filepath", file_types=[".zip", ".7z"]) | |
| submit_btn = gr.Button("🚀 開始處理", variant="primary") | |
| file_output = gr.File(label="下載處理後的新壓縮檔") | |
| # 綁定按鈕點擊事件,傳入所有設定值 | |
| submit_btn.click( | |
| fn=process_archives, | |
| inputs=[file_input, position_radio, options_checkbox, custom_text_input, pack_mode_radio], | |
| outputs=file_output | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |