cormort's picture
Update app.py
bcbb7d9 verified
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()