Spaces:
Running
Running
Upload 4 files
Browse files
app.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
import os
|
| 2 |
-
import os
|
| 3 |
import json
|
|
|
|
| 4 |
|
| 5 |
from fastapi import FastAPI, Request
|
| 6 |
from fastapi.responses import Response, StreamingResponse, FileResponse
|
|
@@ -12,6 +12,8 @@ UPSTREAM = f"http://127.0.0.1:{os.environ.get('TELEGRAM_UPSTREAM_PORT', '8081')}
|
|
| 12 |
app = FastAPI()
|
| 13 |
|
| 14 |
WORK_DIR = os.environ.get("TELEGRAM_WORK_DIR", "/tmp/telegram-bot-api-data")
|
|
|
|
|
|
|
| 15 |
|
| 16 |
def _normalize_bot_api_file_path(raw_fp: str | None, token_enc: str | None) -> str:
|
| 17 |
if not raw_fp:
|
|
@@ -92,6 +94,48 @@ async def proxy(path: str, request: Request):
|
|
| 92 |
except Exception:
|
| 93 |
pass
|
| 94 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
url = f"{UPSTREAM}/{path_for_upstream}"
|
| 96 |
|
| 97 |
params = list(request.query_params.multi_items())
|
|
|
|
| 1 |
import os
|
|
|
|
| 2 |
import json
|
| 3 |
+
import asyncio
|
| 4 |
|
| 5 |
from fastapi import FastAPI, Request
|
| 6 |
from fastapi.responses import Response, StreamingResponse, FileResponse
|
|
|
|
| 12 |
app = FastAPI()
|
| 13 |
|
| 14 |
WORK_DIR = os.environ.get("TELEGRAM_WORK_DIR", "/tmp/telegram-bot-api-data")
|
| 15 |
+
DOWNLOAD_WAIT_SECONDS = float(os.environ.get("TELEGRAM_DOWNLOAD_WAIT_SECONDS", "8"))
|
| 16 |
+
DOWNLOAD_POLL_INTERVAL_MS = int(os.environ.get("TELEGRAM_DOWNLOAD_POLL_INTERVAL_MS", "200"))
|
| 17 |
|
| 18 |
def _normalize_bot_api_file_path(raw_fp: str | None, token_enc: str | None) -> str:
|
| 19 |
if not raw_fp:
|
|
|
|
| 94 |
except Exception:
|
| 95 |
pass
|
| 96 |
|
| 97 |
+
# 如果本地没有这个文件(HF 不持久化常见),允许 CloudPaste 通过 query 传入 file_id 来触发回源下载:
|
| 98 |
+
# - 不新增新的路径接口,仍然是 /tg/file/bot<TOKEN>/<file_path>
|
| 99 |
+
# - 只是在 query 上多带一个 file_id(例如 ?file_id=xxx)
|
| 100 |
+
file_id = request.query_params.get("file_id") or request.query_params.get("fid")
|
| 101 |
+
if token_enc and file_id:
|
| 102 |
+
async with httpx.AsyncClient(timeout=None, follow_redirects=True) as client:
|
| 103 |
+
r = await client.get(f"{UPSTREAM}/bot{token_enc}/getFile", params={"file_id": file_id})
|
| 104 |
+
payload = None
|
| 105 |
+
try:
|
| 106 |
+
payload = r.json()
|
| 107 |
+
except Exception:
|
| 108 |
+
payload = None
|
| 109 |
+
|
| 110 |
+
if r.status_code == 200 and isinstance(payload, dict) and payload.get("ok") is True:
|
| 111 |
+
fp = None
|
| 112 |
+
try:
|
| 113 |
+
fp = (payload.get("result") or {}).get("file_path")
|
| 114 |
+
except Exception:
|
| 115 |
+
fp = None
|
| 116 |
+
|
| 117 |
+
rel2 = _normalize_bot_api_file_path(fp if isinstance(fp, str) else None, token_enc)
|
| 118 |
+
if rel2:
|
| 119 |
+
candidates2 = [
|
| 120 |
+
os.path.join(WORK_DIR, token_enc, rel2),
|
| 121 |
+
os.path.join(WORK_DIR, rel2),
|
| 122 |
+
]
|
| 123 |
+
|
| 124 |
+
waited = 0.0
|
| 125 |
+
interval = max(0.05, DOWNLOAD_POLL_INTERVAL_MS / 1000.0)
|
| 126 |
+
max_wait = max(0.0, DOWNLOAD_WAIT_SECONDS)
|
| 127 |
+
while waited <= max_wait:
|
| 128 |
+
for p2 in candidates2:
|
| 129 |
+
try:
|
| 130 |
+
if p2 and os.path.isfile(p2):
|
| 131 |
+
return FileResponse(p2)
|
| 132 |
+
except Exception:
|
| 133 |
+
pass
|
| 134 |
+
if waited >= max_wait:
|
| 135 |
+
break
|
| 136 |
+
await asyncio.sleep(interval)
|
| 137 |
+
waited += interval
|
| 138 |
+
|
| 139 |
url = f"{UPSTREAM}/{path_for_upstream}"
|
| 140 |
|
| 141 |
params = list(request.query_params.multi_items())
|