vivekchakraverty Claude Opus 4.8 commited on
Commit
2f51a0e
·
1 Parent(s): 01abd01

Accept base64-encoded YT_COOKIES and auto-add Netscape header

Browse files

HF secret fields can convert the Netscape format's required TAB characters into spaces,
which makes yt-dlp reject the cookie file. _cookiefile now auto-detects and decodes a
base64-encoded cookies.txt (tab-safe), and prepends the Netscape header if missing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +42 -3
app.py CHANGED
@@ -6,6 +6,8 @@ startup stays fast.
6
  """
7
  from __future__ import annotations
8
 
 
 
9
  import os
10
  import re
11
  import shutil
@@ -36,13 +38,50 @@ VLM_CHOICES = [
36
  ]
37
 
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  def _cookiefile(workdir: str) -> str | None:
40
- """Materialize the YT_COOKIES secret (Netscape cookie file contents) to disk."""
 
 
 
 
41
  data = os.environ.get("YT_COOKIES")
42
- if not data:
43
  return None
 
 
 
 
 
 
 
 
 
 
 
44
  path = os.path.join(workdir, "cookies.txt")
45
- with open(path, "w", encoding="utf-8") as fh:
46
  fh.write(data)
47
  return path
48
 
 
6
  """
7
  from __future__ import annotations
8
 
9
+ import base64
10
+ import binascii
11
  import os
12
  import re
13
  import shutil
 
38
  ]
39
 
40
 
41
+ def _looks_like_netscape(text: str) -> bool:
42
+ """True if ``text`` is already a tab-separated Netscape cookie file."""
43
+ head = text.lstrip()
44
+ return head.startswith("#") or "\tTRUE\t" in text or "\tFALSE\t" in text
45
+
46
+
47
+ def _maybe_b64_decode(text: str) -> str | None:
48
+ """If ``text`` is base64 that decodes to a cookie file, return the decoded text.
49
+
50
+ HF secret fields can turn the required TAB characters into spaces, which breaks the
51
+ Netscape format. Pasting base64 of the file avoids that; we auto-detect and decode it.
52
+ """
53
+ compact = "".join(text.split())
54
+ if len(compact) < 16 or re.search(r"[^A-Za-z0-9+/=]", compact):
55
+ return None
56
+ try:
57
+ decoded = base64.b64decode(compact, validate=True).decode("utf-8", "replace")
58
+ except (binascii.Error, ValueError):
59
+ return None
60
+ return decoded if _looks_like_netscape(decoded) else None
61
+
62
+
63
  def _cookiefile(workdir: str) -> str | None:
64
+ """Materialize the YT_COOKIES secret to a Netscape cookie file on disk.
65
+
66
+ Accepts either the raw cookies.txt contents (tabs preserved) or a base64 encoding of
67
+ them. A missing header line is added so yt-dlp accepts the file.
68
+ """
69
  data = os.environ.get("YT_COOKIES")
70
+ if not data or not data.strip():
71
  return None
72
+
73
+ if not _looks_like_netscape(data):
74
+ decoded = _maybe_b64_decode(data)
75
+ if decoded:
76
+ data = decoded
77
+
78
+ if not data.lstrip().startswith(("# Netscape", "# HTTP")):
79
+ data = "# Netscape HTTP Cookie File\n" + data.lstrip("\n")
80
+ if not data.endswith("\n"):
81
+ data += "\n"
82
+
83
  path = os.path.join(workdir, "cookies.txt")
84
+ with open(path, "w", encoding="utf-8", newline="\n") as fh:
85
  fh.write(data)
86
  return path
87