Skip to content

Commit 1a3e618

Browse files
authored
Merge pull request #90 from glubsy/po_token_as_file
Allow passing multiple "extractor_args"
2 parents e5817cf + 47bcca2 commit 1a3e618

6 files changed

Lines changed: 49 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [v0.3.2] - 2025-10-25
9+
10+
### Added
11+
- Store PO token in a file inside the configuration directory
12+
813
## [v0.3.1] - 2025-08-24
914

1015
### Added

config/po_token.txt

Whitespace-only changes.

config/ytdlp_config.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717
// https://github.com/yt-dlp/yt-dlp/wiki/Extractors
1818
// You can load one PO_TOKEN value into environment variables with
1919
// export PO_TOKEN="your_token"
20+
// or you can put it into a file named "po_token.txt" in the config directory
2021
// and it will be automatically replaced in the config.
21-
"extractor-args": "youtube:player-client=web,default;po_token=web+<PO_TOKEN_VALUE>",
22+
// This can be a single string value or a list of strings for multiple args.
23+
"extractor-args": [
24+
"youtube:player-client=web,default;po_token=web+<PO_TOKEN_VALUE>",
25+
"youtube:po_token=web.subs+<PO_TOKEN_VALUE>"
26+
],
2227

2328
// Do not stop on download/postprocessing errors.
2429
// Can be "only_download" to ignore only download errors.

docker/Containerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ COPY "livestream_saver.py" .
1515
COPY "./config/ytdlp_config.json" "/root/.config/livestream_saver/ytdlp_config.json"
1616
COPY "./config/livestream_saver.cfg" "/root/.config/livestream_saver/livestream_saver.cfg"
1717
COPY "./config/.env" "/root/.config/livestream_saver/.env"
18+
COPY "./config/po_token.txt" "/root/.config/livestream_saver/po_token.txt"
1819

1920
COPY "./docker/entrypoint.sh" ./entrypoint.sh
2021
RUN chmod +x ./entrypoint.sh

livestream_saver/livestream_saver.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -907,25 +907,52 @@ def load_commented_json(path: Path) -> Dict:
907907
return data
908908

909909

910-
def interpolate_ytdlp_config(data: dict[str, Any]) -> None:
910+
def interpolate_ytdlp_config(data: dict[str, Any], po_token: str) -> None:
911911
"""
912912
Interpolate the ytdlp config file with values from the environment variables.
913913
"""
914914
# currently this is only used to replace the default PO token value
915915
if not (extractor_args := data.get("extractor-args")):
916916
return
917-
if "<PO_TOKEN_VALUE>" not in extractor_args:
918-
return
917+
if type(extractor_args) is str:
918+
if "<PO_TOKEN_VALUE>" not in extractor_args:
919+
return
920+
data["extractor-args"] = extractor_args.replace(
921+
"<PO_TOKEN_VALUE>", po_token
922+
)
923+
# Looks like passing a list to ytdlp works as if passing multiple --extractor-args flags
924+
elif type(extractor_args) is list:
925+
for i, val in enumerate(extractor_args):
926+
if type(val) is str and "<PO_TOKEN_VALUE>" in val:
927+
extractor_args[i] = val.replace("<PO_TOKEN_VALUE>", po_token)
928+
else:
929+
log.warning(
930+
"extractor-args in ytdlp config is neither a string, list or dict."
931+
"Cannot interpolate PO token."
932+
)
933+
919934

935+
def load_po_token(config_dir: Path) -> str:
936+
"""
937+
Load the PO token either from environment variable or from file (env variable
938+
takes precedence).
939+
Raise ValueError if none was found.
940+
"""
920941
token = environ.get("PO_TOKEN", None)
942+
if token and len(token) > 0:
943+
return token.strip()
944+
945+
with open(config_dir / "po_token.txt", "r") as f:
946+
token = f.read().strip()
947+
921948
if not token:
922949
raise ValueError(
923-
"PO_TOKEN environment variable not set. "
924-
"Please set the value with export PO_TOKEN=<your_token_value>"
950+
"Failed to load PO token from environment variable or po_token file."
951+
"Please set the value with export PO_TOKEN=<your_token_value> "
952+
"or create a file named 'po_token' in the config directory."
925953
)
926-
data["extractor-args"] = extractor_args.replace(
927-
"<PO_TOKEN_VALUE>", token
928-
)
954+
return token
955+
929956

930957

931958
def load_env_file(path: Path) -> None:
@@ -987,7 +1014,7 @@ def main():
9871014
ytdlp_conf_file = fallback
9881015

9891016
loaded_ytdlp_conf = load_commented_json(ytdlp_conf_file)
990-
interpolate_ytdlp_config(loaded_ytdlp_conf)
1017+
interpolate_ytdlp_config(loaded_ytdlp_conf, po_token=load_po_token(config_dir))
9911018
args["ytdlp_config"] = loaded_ytdlp_conf
9921019

9931020
logfile_path = Path("") # cwd by default

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "livestream_saver"
3-
version = "0.3.1"
3+
version = "0.3.2"
44
description = "Monitor Youtube channels to download live streams"
55
readme = "README.md"
66
requires-python = ">=3.12"

0 commit comments

Comments
 (0)