My_Board / app.py
Tak0000000's picture
Update app.py
1cdb011 verified
Raw
History Blame Contribute Delete
4.62 kB
import os
import json
from datetime import datetime, timedelta
import gradio as gr
import spaces
DATA_FILE = "messages.json"
UPLOAD_DIR = "uploads"
os.makedirs(UPLOAD_DIR, exist_ok=True)
# 保留留言的天數(設為 30 天)
RETENTION_DAYS = 30
def cleanup_old_messages(messages):
"""清理超過 Retention Days 的舊留言與對應圖片檔"""
now = datetime.now()
valid_messages = []
for msg in messages:
try:
# 解析留言時間 (格式: YYYY-MM-DD HH:MM)
msg_time = datetime.strptime(msg["time"], "%Y-%m-%d %H:%M")
# 判斷是否在 30 天內
if now - msg_time <= timedelta(days=RETENTION_DAYS):
valid_messages.append(msg)
else:
# 已過期,刪除相關圖片實體檔案以釋放空間
if msg.get("image") and os.path.exists(msg["image"]):
try:
os.remove(msg["image"])
except Exception as e:
print(f"刪除舊圖片失敗: {e}")
except Exception:
# 若時間解析失敗,預設留存
valid_messages.append(msg)
return valid_messages
def load_messages():
if os.path.exists(DATA_FILE):
with open(DATA_FILE, "r", encoding="utf-8") as f:
try:
messages = json.load(f)
# 載入時自動執行一次清理
cleaned_messages = cleanup_old_messages(messages)
if len(cleaned_messages) != len(messages):
save_messages(cleaned_messages)
return cleaned_messages
except Exception:
return []
return []
def save_messages(messages):
with open(DATA_FILE, "w", encoding="utf-8") as f:
json.dump(messages, f, ensure_ascii=False, indent=2)
@spaces.GPU(duration=1)
def dummy_gpu_task():
return True
def add_post(author, text, image):
author = author.strip() if author and author.strip() else "匿名成員"
img_path = None
if image is not None:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
img_path = os.path.join(UPLOAD_DIR, f"{timestamp}.png")
image.save(img_path)
# 讀取並自動清理舊資料
messages = load_messages()
messages.insert(0, {
"author": author,
"text": text,
"image": img_path,
"time": datetime.now().strftime("%Y-%m-%d %H:%M")
})
# 儲存前再次確保只留 30 天內的資料
messages = cleanup_old_messages(messages)
save_messages(messages)
return "", "", None, *get_board_data()
def get_board_data():
messages = load_messages()
text_logs = []
gallery_images = []
for msg in messages:
text_logs.append(f"📌 {msg['author']}{msg['time']})\n{msg['text']}\n" + "—"*25)
if msg.get('image') and os.path.exists(msg['image']):
gallery_images.append((msg['image'], f"{msg['author']} 的分享 ({msg['time']})"))
full_text = "\n\n".join(text_logs) if text_logs else "目前尚無留言(近 30 天)。"
return full_text, gallery_images
with gr.Blocks(title="家庭佈告欄") as demo:
gr.Markdown("# 🏡 家庭成員佈告欄")
gr.Markdown("💡 *系統將自動保留最近 30 天內的留言與照片,過期內容會自動清除以清理空間。*")
with gr.Row():
with gr.Column():
author_input = gr.Textbox(label="你的稱呼", placeholder="例如:媽媽、小明")
text_input = gr.Textbox(label="留言內容", lines=3, placeholder="想跟大家說什麼?")
image_input = gr.Image(label="上傳照片(可選)", type="pil")
submit_btn = gr.Button("發布動態", variant="primary")
with gr.Column():
init_text, init_gallery = get_board_data()
board_text = gr.Textbox(value=init_text, label="留言記錄(近30天)", lines=8, interactive=False)
board_gallery = gr.Gallery(value=init_gallery, label="照片牆")
refresh_btn = gr.Button("🔄 重新整理")
submit_btn.click(
fn=add_post,
inputs=[author_input, text_input, image_input],
outputs=[author_input, text_input, image_input, board_text, board_gallery]
)
refresh_btn.click(
fn=get_board_data,
outputs=[board_text, board_gallery]
)
demo.launch()