Files
InfernoXuaI 928f54e923 自身群监控
自身群监控
2026-05-28 22:21:19 +08:00

104 lines
5.1 KiB
Plaintext

document.getElementById('addModal').addEventListener('click', function(e) { if (e.target === this) this.style.display='none'; });
</script>"""
@app.get("/channel-media", response_class=HTMLResponse)
async def channel_media_page(_: str = Depends(panel_auth)) -> str:
return layout("频道媒体", channel_media_page_html())
@app.get("/api/groups")
async def api_groups(_: str = Depends(panel_auth), q: str = "", limit: int = 500) -> dict[str, Any]:
if not user_session_ready():
return {"groups": [], "error": "TG user session not configured"}
if q.strip():
groups = await telethon_search_dialogs(q.strip(), limit=min(limit, 200))
else:
groups = await telethon_list_dialogs(limit=min(limit, 500))
groups = [g for g in groups if g.get("type") in ("group", "channel")]
return {"groups": groups}
@app.post("/api/monitors/create")
async def api_monitor_create(
_: str = Depends(panel_auth),
channel_id: str = Form(...),
channel_title: str = Form(""),
channel_username: str = Form(""),
media_types: str = Form("video,document"),
keywords: str = Form(""),
max_file_size_mb: int = Form(2000),
download_dir: str = Form(""),
notify_telegram: str | None = Form(None),
proxy: str = Form(""),
date_from: str = Form(""),
date_to: str = Form(""),
max_concurrent: int = Form(3),
forward_mode: str | None = Form(None),
forward_to: str = Form("admin"),
) -> RedirectResponse:
try:
cid = int(channel_id.strip())
except (ValueError, TypeError):
raise HTTPException(400, "invalid channel_id")
channel_media_monitor_create(
cid,
channel_title.strip() or str(cid),
channel_username.strip(),
media_types.strip() or "video,document",
keywords.strip(),
max(1, max_file_size_mb),
download_dir.strip(),
bool(notify_telegram),
proxy.strip(),
date_from.strip(),
date_to.strip(),
max(1, min(10, max_concurrent)),
bool(forward_mode),
forward_to.strip() or "admin",
)
return RedirectResponse("/channel-media", status_code=303)
@app.get("/channel-media/{monitor_id}/pause")
async def channel_media_pause(monitor_id: int, _: str = Depends(panel_auth)) -> RedirectResponse:
channel_media_monitor_update(monitor_id, status="paused")
return RedirectResponse("/channel-media", status_code=303)
@app.get("/channel-media/{monitor_id}/resume")
async def channel_media_resume(monitor_id: int, _: str = Depends(panel_auth)) -> RedirectResponse:
channel_media_monitor_update(monitor_id, status="active")
return RedirectResponse("/channel-media", status_code=303)
@app.get("/channel-media/{monitor_id}/delete")
async def channel_media_delete_route(monitor_id: int, _: str = Depends(panel_auth)) -> RedirectResponse:
channel_media_monitor_delete(monitor_id)
return RedirectResponse("/channel-media", status_code=303)
@app.get("/channel-media/{monitor_id}/check", response_class=HTMLResponse)
async def channel_media_check(monitor_id: int, _: str = Depends(panel_auth)) -> str:
count = await telethon_download_from_channel(monitor_id)
monitor = channel_media_monitor_get(monitor_id)
name = monitor.get("channel_title", "") if monitor else ""
return layout("检查完成", f"<div class=msg>已检查频道 {html_escape(name)},新增 {count} 个文件。</div><p><a class=btn href='/channel-media'>返回</a></p>")
@app.get("/channel-media/{monitor_id}/download", response_class=HTMLResponse)
async def channel_media_download_history(monitor_id: int, _: str = Depends(panel_auth)) -> str:
monitor = channel_media_monitor_get(monitor_id)
if not monitor:
raise HTTPException(404)
downloads = channel_media_downloads_list(monitor_id, limit=200)
rows = ""
for d in downloads:
size_mb = f"{(d.get('file_size', 0) or 0) / 1024 / 1024:.1f} MB"
rows += f"<tr><td>{d.get('id')}</td><td>{html_escape(d.get('media_type',''))}</td>"
rows += f"<td>{html_escape(d.get('file_name',''))}<br><small class=muted>{html_escape(d.get('caption','')[:100])}</small></td>"
rows += f"<td>{size_mb}</td><td><small>{html_escape(d.get('created_at',''))}</small></td></tr>"
total = monitor.get("total_downloaded", 0)
size_mb = (monitor.get("total_size_bytes", 0) or 0) // 1024 // 1024
body = f"""<div class=card><h2>下载记录 - {html_escape(monitor.get('channel_title',''))}</h2>
<p class=muted>累计:{total} 个文件,{size_mb} MB</p>
<div class=actions style='margin-bottom:16px'>
<a class='btn ok' href='/channel-media/{monitor_id}/check'>立即下载新内容</a>
<a class='btn' href='/channel-media'>返回列表</a></div>
<table><tr><th>ID</th><th>类型</th><th>文件名/说明</th><th>大小</th><th>时间</th></tr>{rows}</table></div>"""
return layout("下载记录", body)
return app