Demo / app.py
shiue2000's picture
Update app.py
70f1c1c verified
import gradio as gr
import shutil
import zipfile
from datetime import datetime
from pathlib import Path
from PIL import Image
import pillow_heif
import tempfile
import os
# Setup base folders
BASE_DIR = Path(tempfile.gettempdir()) / "17eMIT"
UPLOAD_FOLDER = BASE_DIR / "images"
FILES_FOLDER = BASE_DIR / "files"
UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)
FILES_FOLDER.mkdir(parents=True, exist_ok=True)
# Allowed file types
IMAGE_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.heic', '.webp', '.bmp', '.tiff']
FILE_EXTENSIONS = ['.mp3', '.m4a', '.mp4', '.pdf', '.docx', '.txt', '.xlsx', '.pptx']
def get_image_paths(limit=30):
files = sorted(UPLOAD_FOLDER.glob("*"), key=lambda x: x.stat().st_mtime, reverse=True)
return [str(f) for f in files if f.suffix.lower() in IMAGE_EXTENSIONS][:limit]
def get_file_list():
files = sorted(FILES_FOLDER.glob("*"), key=lambda x: x.stat().st_mtime, reverse=True)
return [f.name for f in files]
def save_files(file_paths):
if not file_paths:
return "❗請選擇至少一個檔案", get_image_paths(), gr.update(choices=get_file_list())
messages = []
for file_path in file_paths:
try:
ext = Path(file_path).suffix.lower()
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S%f")
filename = f"{timestamp}{ext}"
if ext in IMAGE_EXTENSIONS:
if ext == ".heic":
heif_file = pillow_heif.read_heif(file_path)
image = Image.frombytes(heif_file.mode, heif_file.size, heif_file.data, "raw")
else:
image = Image.open(file_path).convert("RGB")
filepath = UPLOAD_FOLDER / f"{timestamp}.png"
image.save(filepath, format="PNG")
elif ext in FILE_EXTENSIONS:
filepath = FILES_FOLDER / filename
shutil.copy(file_path, filepath)
else:
messages.append(f"❌ 不支援的檔案格式: {ext}")
continue
messages.append(f"✅ 檔案已上傳: {filename}")
except Exception as e:
messages.append(f"❌ 上傳失敗 ({file_path}): {str(e)}")
return "\n".join(messages), get_image_paths(), gr.update(choices=get_file_list())
def clear_images():
try:
shutil.rmtree(UPLOAD_FOLDER)
shutil.rmtree(FILES_FOLDER)
UPLOAD_FOLDER.mkdir(parents=True, exist_ok=True)
FILES_FOLDER.mkdir(parents=True, exist_ok=True)
return "🧹 所有圖片與檔案已清除", [], gr.update(choices=[])
except Exception as e:
return f"❌ 清除失敗: {str(e)}", get_image_paths(), gr.update(choices=get_file_list())
def download_all_files():
all_files = list(UPLOAD_FOLDER.glob("*")) + list(FILES_FOLDER.glob("*"))
if not all_files:
return None, "⚠️ 沒有可下載的檔案"
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
temp_zip = Path(tempfile.gettempdir()) / f"all_uploads_{timestamp}.zip"
try:
with zipfile.ZipFile(temp_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
for filepath in all_files:
zipf.write(filepath, arcname=filepath.name)
return str(temp_zip), "✅ ZIP 文件已生成"
except Exception as e:
return None, f"❌ ZIP 文件生成失敗: {str(e)}"
def cleanup_old_zips():
temp_dir = Path(tempfile.gettempdir())
for zip_file in temp_dir.glob("all_uploads_*.zip"):
try:
zip_file.unlink()
except Exception:
pass
# --- UI Starts ---
with gr.Blocks(title="📁 圖片與檔案分享平台") as demo:
with gr.Row():
file_input = gr.File(label="上傳檔案", type="filepath", file_count="multiple")
upload_button = gr.Button("📤 上傳", variant="primary")
output_msg = gr.Textbox(label="狀態", lines=4, interactive=False)
with gr.Row():
clear_button = gr.Button("🚫 清除所有", variant="stop")
download_button = gr.Button("📦 下載全部", variant="primary")
download_file = gr.File(label="點此下載 ZIP")
zip_path_display = gr.Textbox(label="ZIP 文件訊息", lines=2, interactive=False)
gr.Markdown("### 📄 上傳檔案列表")
file_list = gr.Dropdown(label="所有檔案", choices=get_file_list(), interactive=False)
gallery = gr.Gallery(label="📷 已上傳圖片", show_label=True, columns=3, object_fit="contain", height="500px")
upload_button.click(
fn=save_files,
inputs=file_input,
outputs=[output_msg, gallery, file_list]
)
clear_button.click(
fn=clear_images,
outputs=[output_msg, gallery, file_list]
)
download_button.click(
fn=download_all_files,
outputs=[download_file, zip_path_display]
)
demo.load(fn=get_image_paths, outputs=gallery)
demo.load(fn=cleanup_old_zips)
demo.launch()