Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbdb257079 |
@@ -1069,6 +1069,20 @@ async def admin_yt_add(request: Request, url: str = Form(""), playlist: str = Fo
|
|||||||
return RedirectResponse("/admin/yt?saved=Lagt i kø — hentningen er i gang", status_code=303)
|
return RedirectResponse("/admin/yt?saved=Lagt i kø — hentningen er i gang", status_code=303)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/admin/yt/slet")
|
||||||
|
async def admin_yt_delete(request: Request):
|
||||||
|
require_admin(request)
|
||||||
|
f = await request.form()
|
||||||
|
res = yt.delete_video(f.get("path") or "")
|
||||||
|
if not res["ok"]:
|
||||||
|
return RedirectResponse(f"/admin/yt?saved={urllib.parse.quote(res['error'])}", status_code=303)
|
||||||
|
cache.clear("yt:")
|
||||||
|
await yt.refresh_library()
|
||||||
|
return RedirectResponse(
|
||||||
|
"/admin/yt?saved=" + urllib.parse.quote(f"Slettet: {res['title']} ({yt._human(res['size'])})"),
|
||||||
|
status_code=303)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/admin/yt/settings")
|
@app.post("/admin/yt/settings")
|
||||||
async def admin_yt_settings(request: Request):
|
async def admin_yt_settings(request: Request):
|
||||||
require_admin(request)
|
require_admin(request)
|
||||||
|
|||||||
@@ -126,7 +126,7 @@
|
|||||||
<h2 style="margin-top:2rem">Hentede videoer</h2>
|
<h2 style="margin-top:2rem">Hentede videoer</h2>
|
||||||
{% if not ours %}<p class="muted">Ingen endnu — indsæt en URL ovenfor.</p>{% else %}
|
{% if not ours %}<p class="muted">Ingen endnu — indsæt en URL ovenfor.</p>{% else %}
|
||||||
<table class="wt-table" style="margin-top:.8rem">
|
<table class="wt-table" style="margin-top:.8rem">
|
||||||
<thead><tr><th>Titel</th><th style="width:7rem">Størrelse</th><th style="width:9rem">Status</th><th style="width:11rem">Slettes</th></tr></thead>
|
<thead><tr><th>Titel</th><th style="width:7rem">Størrelse</th><th style="width:9rem">Status</th><th style="width:11rem">Slettes</th><th style="width:5.5rem"></th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for v in ours %}
|
{% for v in ours %}
|
||||||
<tr>
|
<tr>
|
||||||
@@ -142,6 +142,13 @@
|
|||||||
{% elif v.delete_after %}om {{ ((v.delete_after - now) / 86400) | round(0, 'ceil') | int }} dage
|
{% elif v.delete_after %}om {{ ((v.delete_after - now) / 86400) | round(0, 'ceil') | int }} dage
|
||||||
{% else %}—{% endif %}
|
{% else %}—{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<form method="post" action="/admin/yt/slet" style="margin:0"
|
||||||
|
onsubmit="return confirm({{ ('Slet „' ~ v.name ~ '“ nu?' ~ (' Den er markeret som favorit.' if v.favorite else '')) | tojson | forceescape }})">
|
||||||
|
<input type="hidden" name="path" value="{{ v.path }}">
|
||||||
|
<button class="wt-btn" type="submit">Slet</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -488,6 +488,44 @@ async def enforce_cycles() -> dict:
|
|||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def delete_video(path: str) -> dict:
|
||||||
|
"""Slet én video manuelt (knappen på /admin/yt), med samme sikkerhedsnet som
|
||||||
|
oprydningen: KUN filer portalen selv har hentet, og sidecars med.
|
||||||
|
|
||||||
|
Video-id'et bliver stående i abonnementets `seen`, så en overvåget kanal ikke
|
||||||
|
henter den igen. Er det jobbets sidste fil, markeres jobbet som slettet.
|
||||||
|
"""
|
||||||
|
real = os.path.realpath(path or "")
|
||||||
|
if real not in owned_paths():
|
||||||
|
return {"ok": False, "error": "Den video har portalen ikke selv hentet, så den røres ikke"}
|
||||||
|
st = get_state()
|
||||||
|
try:
|
||||||
|
size = file_size(real)
|
||||||
|
for side in _sidecars(real):
|
||||||
|
os.remove(side)
|
||||||
|
if os.path.exists(real):
|
||||||
|
os.remove(real)
|
||||||
|
except OSError as e:
|
||||||
|
return {"ok": False, "error": f"Kunne ikke slette: {e}"}
|
||||||
|
st["leaving"].pop(real, None)
|
||||||
|
titel = os.path.basename(real)
|
||||||
|
for j in st["jobs"].values():
|
||||||
|
paths = [p for p in (j.get("paths") or ([j["path"]] if j.get("path") else [])) if p]
|
||||||
|
if real not in {os.path.realpath(p) for p in paths}:
|
||||||
|
continue
|
||||||
|
titel = j.get("title") or titel
|
||||||
|
rest = [p for p in paths if os.path.realpath(p) != real]
|
||||||
|
if j.get("paths") is not None:
|
||||||
|
j["paths"] = rest
|
||||||
|
if j.get("videos"):
|
||||||
|
j["videos"] = [v for v in j["videos"] if os.path.realpath(v.get("path") or "") != real]
|
||||||
|
if not rest:
|
||||||
|
j["status"] = "deleted"
|
||||||
|
_log(st, f"Slettet manuelt: {titel} ({_human(size)})")
|
||||||
|
save_state(st)
|
||||||
|
return {"ok": True, "title": titel, "size": size}
|
||||||
|
|
||||||
|
|
||||||
# ---------------- Emby ----------------
|
# ---------------- Emby ----------------
|
||||||
async def _emby(client, path, **params):
|
async def _emby(client, path, **params):
|
||||||
params["api_key"] = config.EMBY_API_KEY
|
params["api_key"] = config.EMBY_API_KEY
|
||||||
|
|||||||
Reference in New Issue
Block a user