GoFileEmpty: no retries for content that exists but is empty; add tools/debug_gofile.py for raw content-API inspection
This commit is contained in:
@@ -157,7 +157,7 @@ def run_gofile(
|
||||
try:
|
||||
files_spec = client.list_files(f.url)
|
||||
if not files_spec:
|
||||
raise dlph_gofile.GoFileError("no files found under URL")
|
||||
raise dlph_gofile.GoFileEmpty("content exists but contains no files")
|
||||
files: list[dict] = []
|
||||
for relpath, name, link in files_spec:
|
||||
dest = Path(args.out_dir) / "downloads" / "gofile" / relpath / name
|
||||
@@ -182,6 +182,11 @@ def run_gofile(
|
||||
log.error("DEAD LINK %s: %s", f.url, exc)
|
||||
state.mark(f.url, status="failed", error=str(exc), files=[])
|
||||
break
|
||||
except dlph_gofile.GoFileEmpty as exc:
|
||||
# Emptied content is stable - no retry
|
||||
log.error("EMPTY CONTENT %s: %s", f.url, exc)
|
||||
state.mark(f.url, status="failed", error=str(exc), files=[])
|
||||
break
|
||||
except dlph_gofile.GoFileAuthError as exc:
|
||||
# Token may have died mid-run (rate limit); re-auth once per attempt
|
||||
log.warning("Auth error for %s: %s - re-authenticating", f.url, exc)
|
||||
|
||||
@@ -60,6 +60,13 @@ class GoFileNotFound(GoFileError):
|
||||
"""
|
||||
|
||||
|
||||
class GoFileEmpty(GoFileError):
|
||||
"""The content exists but contains no files (e.g. emptied folder).
|
||||
|
||||
Stable state like a dead link: no retry.
|
||||
"""
|
||||
|
||||
|
||||
class GoFileAuthError(GoFileError):
|
||||
"""The account token was rejected; the client can re-auth once."""
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""One-off diagnostic: inspect the raw gofile API response for one content id.
|
||||
|
||||
Prints everything except the account token. Creates exactly one guest account.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
CID = sys.argv[1]
|
||||
|
||||
USER_AGENT = "Mozilla/5.0"
|
||||
LOCALE = "en-US"
|
||||
TOKEN_SECRET = "12af056dacea0b"
|
||||
WINDOW_SEC = 14400
|
||||
COMMON = {"User-Agent": USER_AGENT, "Accept-Encoding": "gzip", "Accept": "*/*",
|
||||
"Connection": "keep-alive"}
|
||||
|
||||
resp = requests.post("https://api.gofile.io/accounts", headers=COMMON, timeout=15)
|
||||
data = resp.json()
|
||||
assert data.get("status") == "ok", data
|
||||
token = data["data"]["token"]
|
||||
|
||||
window = int(time.time()) // WINDOW_SEC
|
||||
seed = f"{USER_AGENT}::{LOCALE}::{token}::{window}::{TOKEN_SECRET}"
|
||||
wtoken = hashlib.sha256(seed.encode()).hexdigest()
|
||||
headers = {
|
||||
**COMMON,
|
||||
"Authorization": f"Bearer {token}",
|
||||
"X-Website-Token": wtoken,
|
||||
"X-BL": LOCALE,
|
||||
}
|
||||
|
||||
r = requests.get(
|
||||
f"https://api.gofile.io/contents/{CID}?cache=true&sortField=createTime&sortDirection=1",
|
||||
headers=headers, timeout=30,
|
||||
)
|
||||
print("HTTP", r.status_code)
|
||||
body = r.json()
|
||||
print("api status:", body.get("status"))
|
||||
|
||||
|
||||
def scrub(node):
|
||||
"""Remove anything token-like from the tree before printing."""
|
||||
if isinstance(node, dict):
|
||||
return {
|
||||
k: ("<redacted>" if k in ("token", "accountToken") else scrub(v))
|
||||
for k, v in node.items()
|
||||
}
|
||||
if isinstance(node, list):
|
||||
return [scrub(x) for x in node]
|
||||
return node
|
||||
|
||||
|
||||
d = body.get("data") or {}
|
||||
print("data keys:", sorted(d.keys()))
|
||||
print("type:", d.get("type"))
|
||||
children = d.get("children") or {}
|
||||
print("children count:", len(children))
|
||||
for cid, child in list(children.items())[:5]:
|
||||
print(" child:", cid, "type:", child.get("type"), "name:", child.get("name"),
|
||||
"has link:", "link" in child)
|
||||
print()
|
||||
print(json.dumps(scrub(body), indent=2)[:3000])
|
||||
Reference in New Issue
Block a user