File size: 4,942 Bytes
0e663a7
8fd69b6
 
 
 
0e663a7
 
c15e600
8fd69b6
0e663a7
6804051
8fd69b6
 
6804051
8fd69b6
6804051
c15e600
6804051
34dd501
6804051
34dd501
8fd69b6
6804051
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0e663a7
70f1c1c
 
 
 
 
 
 
 
 
0e663a7
6804051
 
 
 
259d510
 
6804051
259d510
0e663a7
8fd69b6
6804051
8fd69b6
822b379
0e663a7
 
 
8fd69b6
 
6804051
259d510
 
 
 
8fd69b6
6804051
 
259d510
0e663a7
70f1c1c
 
 
 
 
 
 
 
 
 
 
 
 
 
e63c659
0e663a7
6804051
0e663a7
6804051
0e663a7
6804051
0e663a7
70f1c1c
6804051
0e663a7
6804051
0e663a7
6804051
0e663a7
 
6804051
8fd69b6
259d510
0e663a7
259d510
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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()