Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
CHANGED
|
@@ -5,6 +5,7 @@ import json
|
|
| 5 |
import time
|
| 6 |
import logging
|
| 7 |
import hashlib
|
|
|
|
| 8 |
from datetime import datetime
|
| 9 |
|
| 10 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
@@ -413,12 +414,30 @@ def _count_chunks(scope):
|
|
| 413 |
|
| 414 |
# --- 原始文件管理(Supabase Storage + uploaded_files 表)---
|
| 415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 416 |
def _save_uploaded_file_to_storage(scope, uploaded_file):
|
| 417 |
"""上传原始文件到 Supabase Storage,并记录元数据。"""
|
| 418 |
-
storage_path = f"{scope}/{uploaded_file.name}"
|
| 419 |
uploaded_file.seek(0)
|
| 420 |
file_bytes = uploaded_file.read()
|
| 421 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 422 |
# 上传到 Storage(存在则覆盖)
|
| 423 |
try:
|
| 424 |
_sb().storage.from_(STORAGE_BUCKET).upload(
|
|
@@ -426,7 +445,6 @@ def _save_uploaded_file_to_storage(scope, uploaded_file):
|
|
| 426 |
file_options={"content-type": "application/octet-stream", "upsert": "true"}
|
| 427 |
)
|
| 428 |
except Exception as e:
|
| 429 |
-
# supabase-py 某些版本 upsert 需要先删再传
|
| 430 |
logger.warning(f"Storage upload fallback: {e}")
|
| 431 |
try:
|
| 432 |
_sb().storage.from_(STORAGE_BUCKET).remove([storage_path])
|
|
@@ -437,7 +455,7 @@ def _save_uploaded_file_to_storage(scope, uploaded_file):
|
|
| 437 |
file_options={"content-type": "application/octet-stream"}
|
| 438 |
)
|
| 439 |
|
| 440 |
-
# 记录元数据到 uploaded_files 表
|
| 441 |
_sb().table("uploaded_files").upsert({
|
| 442 |
"scope": scope,
|
| 443 |
"filename": uploaded_file.name,
|
|
@@ -471,9 +489,13 @@ def _list_uploaded_files_db(scope):
|
|
| 471 |
|
| 472 |
def _delete_uploaded_file_from_storage(scope, filename):
|
| 473 |
"""删除 Storage 中的文件和 uploaded_files 表记录。"""
|
| 474 |
-
storage_path = f"{scope}/{filename}"
|
| 475 |
try:
|
| 476 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 477 |
except Exception as e:
|
| 478 |
logger.warning(f"Storage 删除失败: {e}")
|
| 479 |
try:
|
|
|
|
| 5 |
import time
|
| 6 |
import logging
|
| 7 |
import hashlib
|
| 8 |
+
import uuid
|
| 9 |
from datetime import datetime
|
| 10 |
|
| 11 |
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
|
|
|
|
| 414 |
|
| 415 |
# --- 原始文件管理(Supabase Storage + uploaded_files 表)---
|
| 416 |
|
| 417 |
+
def _safe_storage_path(scope, filename):
|
| 418 |
+
"""生成 ASCII 安全的 Storage 路径(Supabase Storage 不支持中文/特殊字符)。"""
|
| 419 |
+
import os
|
| 420 |
+
ext = os.path.splitext(filename)[1].lower() # 保留扩展名
|
| 421 |
+
safe_name = uuid.uuid4().hex[:16] + ext
|
| 422 |
+
return f"{scope}/{safe_name}"
|
| 423 |
+
|
| 424 |
+
|
| 425 |
def _save_uploaded_file_to_storage(scope, uploaded_file):
|
| 426 |
"""上传原始文件到 Supabase Storage,并记录元数据。"""
|
|
|
|
| 427 |
uploaded_file.seek(0)
|
| 428 |
file_bytes = uploaded_file.read()
|
| 429 |
|
| 430 |
+
# 检查是否已有同名文件记录,复用其 storage_path
|
| 431 |
+
try:
|
| 432 |
+
existing = _sb().table("uploaded_files").select("storage_path").eq(
|
| 433 |
+
"scope", scope).eq("filename", uploaded_file.name).execute()
|
| 434 |
+
if existing.data:
|
| 435 |
+
storage_path = existing.data[0]["storage_path"]
|
| 436 |
+
else:
|
| 437 |
+
storage_path = _safe_storage_path(scope, uploaded_file.name)
|
| 438 |
+
except Exception:
|
| 439 |
+
storage_path = _safe_storage_path(scope, uploaded_file.name)
|
| 440 |
+
|
| 441 |
# 上传到 Storage(存在则覆盖)
|
| 442 |
try:
|
| 443 |
_sb().storage.from_(STORAGE_BUCKET).upload(
|
|
|
|
| 445 |
file_options={"content-type": "application/octet-stream", "upsert": "true"}
|
| 446 |
)
|
| 447 |
except Exception as e:
|
|
|
|
| 448 |
logger.warning(f"Storage upload fallback: {e}")
|
| 449 |
try:
|
| 450 |
_sb().storage.from_(STORAGE_BUCKET).remove([storage_path])
|
|
|
|
| 455 |
file_options={"content-type": "application/octet-stream"}
|
| 456 |
)
|
| 457 |
|
| 458 |
+
# 记录元数据到 uploaded_files 表(filename 保留原始中文名)
|
| 459 |
_sb().table("uploaded_files").upsert({
|
| 460 |
"scope": scope,
|
| 461 |
"filename": uploaded_file.name,
|
|
|
|
| 489 |
|
| 490 |
def _delete_uploaded_file_from_storage(scope, filename):
|
| 491 |
"""删除 Storage 中的文件和 uploaded_files 表记录。"""
|
|
|
|
| 492 |
try:
|
| 493 |
+
# 从数据库查真实 storage_path
|
| 494 |
+
resp = _sb().table("uploaded_files").select("storage_path").eq(
|
| 495 |
+
"scope", scope).eq("filename", filename).execute()
|
| 496 |
+
if resp.data:
|
| 497 |
+
storage_path = resp.data[0]["storage_path"]
|
| 498 |
+
_sb().storage.from_(STORAGE_BUCKET).remove([storage_path])
|
| 499 |
except Exception as e:
|
| 500 |
logger.warning(f"Storage 删除失败: {e}")
|
| 501 |
try:
|