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:
|
try:
|
||||||
files_spec = client.list_files(f.url)
|
files_spec = client.list_files(f.url)
|
||||||
if not files_spec:
|
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] = []
|
files: list[dict] = []
|
||||||
for relpath, name, link in files_spec:
|
for relpath, name, link in files_spec:
|
||||||
dest = Path(args.out_dir) / "downloads" / "gofile" / relpath / name
|
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)
|
log.error("DEAD LINK %s: %s", f.url, exc)
|
||||||
state.mark(f.url, status="failed", error=str(exc), files=[])
|
state.mark(f.url, status="failed", error=str(exc), files=[])
|
||||||
break
|
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:
|
except dlph_gofile.GoFileAuthError as exc:
|
||||||
# Token may have died mid-run (rate limit); re-auth once per attempt
|
# 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)
|
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):
|
class GoFileAuthError(GoFileError):
|
||||||
"""The account token was rejected; the client can re-auth once."""
|
"""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