Spaces:
Sleeping
Sleeping
Commit ·
e935ba7
1
Parent(s): 4b8e533
Add one-click extension .zip download button in the Space UI
Browse filesZip the bundled extension/ folder at startup (top-level extension/ dir, ready to "Load
unpacked") and expose it via a gr.DownloadButton in the YouTube-access panel; allow the
temp dir in launch() so Gradio can serve it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
README.md
CHANGED
|
@@ -71,11 +71,13 @@ Paste the values into the app's **"YouTube access — cookies / proxy"** panel:
|
|
| 71 |
### Easiest: the PO Token Grabber extension (one click)
|
| 72 |
|
| 73 |
This repo ships a tiny Chrome/Edge extension in [`extension/`](extension/) that reads the
|
| 74 |
-
PO token + visitor data for you.
|
| 75 |
-
(
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
the
|
|
|
|
|
|
|
| 79 |
[`extension/README.md`](extension/README.md). (It's unpublished/sideloaded and may need
|
| 80 |
updates when YouTube changes; the manual steps below always work as a fallback.)
|
| 81 |
|
|
|
|
| 71 |
### Easiest: the PO Token Grabber extension (one click)
|
| 72 |
|
| 73 |
This repo ships a tiny Chrome/Edge extension in [`extension/`](extension/) that reads the
|
| 74 |
+
PO token + visitor data for you. Grab it with the **⬇️ Download the PO Token Grabber
|
| 75 |
+
extension (.zip)** button in the app's *YouTube access* panel (or from
|
| 76 |
+
[`extension/`](extension/)), unzip it, and load it unpacked (`chrome://extensions` →
|
| 77 |
+
Developer mode → Load unpacked). Open a YouTube video and press play, then click the
|
| 78 |
+
extension **while on the YouTube tab** to capture the values. Open this Space in another
|
| 79 |
+
tab and hit **⤵ Fill the Space tab** to inject them straight into the fields below (or use
|
| 80 |
+
the Copy buttons and paste). See
|
| 81 |
[`extension/README.md`](extension/README.md). (It's unpublished/sideloaded and may need
|
| 82 |
updates when YouTube changes; the manual steps below always work as a fallback.)
|
| 83 |
|
app.py
CHANGED
|
@@ -26,6 +26,25 @@ from pipeline import (
|
|
| 26 |
tutorial as tutorial_mod,
|
| 27 |
)
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
LLM_CHOICES = [
|
| 30 |
"deepseek-ai/DeepSeek-V3",
|
| 31 |
"meta-llama/Llama-3.3-70B-Instruct",
|
|
@@ -291,6 +310,11 @@ def build_ui():
|
|
| 291 |
"- An operator can instead set Space secrets `YT_COOKIES` / `YT_PROXY` / "
|
| 292 |
"`YT_POT` / `YT_VISITOR_DATA` as shared defaults."
|
| 293 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
cookies_text = gr.Textbox(
|
| 295 |
label="YouTube cookies (cookies.txt contents or base64)", lines=4,
|
| 296 |
placeholder="# Netscape HTTP Cookie File … (or a base64 blob)")
|
|
@@ -350,4 +374,4 @@ def build_ui():
|
|
| 350 |
|
| 351 |
|
| 352 |
if __name__ == "__main__":
|
| 353 |
-
build_ui().queue().launch()
|
|
|
|
| 26 |
tutorial as tutorial_mod,
|
| 27 |
)
|
| 28 |
|
| 29 |
+
APP_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 30 |
+
EXTENSION_DIR = os.path.join(APP_DIR, "extension")
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def _build_extension_zip() -> str | None:
|
| 34 |
+
"""Zip the bundled browser extension for one-click download; return the .zip path.
|
| 35 |
+
|
| 36 |
+
Produces an archive whose top-level folder is ``extension/`` so it unzips to a
|
| 37 |
+
ready-to-"Load unpacked" directory. Returns None if the folder isn't present.
|
| 38 |
+
"""
|
| 39 |
+
if not os.path.isdir(EXTENSION_DIR):
|
| 40 |
+
return None
|
| 41 |
+
out_base = os.path.join(tempfile.gettempdir(), "tutorialmaker-extension")
|
| 42 |
+
try:
|
| 43 |
+
return shutil.make_archive(out_base, "zip", root_dir=APP_DIR, base_dir="extension")
|
| 44 |
+
except Exception:
|
| 45 |
+
return None
|
| 46 |
+
|
| 47 |
+
|
| 48 |
LLM_CHOICES = [
|
| 49 |
"deepseek-ai/DeepSeek-V3",
|
| 50 |
"meta-llama/Llama-3.3-70B-Instruct",
|
|
|
|
| 310 |
"- An operator can instead set Space secrets `YT_COOKIES` / `YT_PROXY` / "
|
| 311 |
"`YT_POT` / `YT_VISITOR_DATA` as shared defaults."
|
| 312 |
)
|
| 313 |
+
_ext_zip = _build_extension_zip()
|
| 314 |
+
if _ext_zip:
|
| 315 |
+
gr.DownloadButton(
|
| 316 |
+
"⬇️ Download the PO Token Grabber extension (.zip)",
|
| 317 |
+
value=_ext_zip, size="sm")
|
| 318 |
cookies_text = gr.Textbox(
|
| 319 |
label="YouTube cookies (cookies.txt contents or base64)", lines=4,
|
| 320 |
placeholder="# Netscape HTTP Cookie File … (or a base64 blob)")
|
|
|
|
| 374 |
|
| 375 |
|
| 376 |
if __name__ == "__main__":
|
| 377 |
+
build_ui().queue().launch(allowed_paths=[tempfile.gettempdir()])
|