From bdb6d0e36a1e8cc2a48049b6cfe23e6560315b7c Mon Sep 17 00:00:00 2001
From: arabcoders
Date: Wed, 3 Sep 2025 23:49:19 +0300
Subject: [PATCH] FEAT: Update default presets
---
app/library/Presets.py | 12 ++++++-----
app/library/YTDLPOpts.py | 10 ++++++---
app/library/config.py | 5 ++++-
ui/app/pages/index.vue | 41 +++++++++++++++++++++---------------
ui/app/stores/ConfigStore.ts | 1 -
ui/app/types/config.d.ts | 2 --
6 files changed, 42 insertions(+), 29 deletions(-)
diff --git a/app/library/Presets.py b/app/library/Presets.py
index 08d582d5..425061cf 100644
--- a/app/library/Presets.py
+++ b/app/library/Presets.py
@@ -19,33 +19,34 @@ DEFAULT_PRESETS: list[dict[int, dict[str, str | bool]]] = [
"id": "3e163c6c-64eb-4448-924f-814b629b3810",
"name": "default",
"default": True,
+ "cli": "--socket-timeout 30 --download-archive %(config_path)s/archive.log",
"description": "Default preset for yt-dlp. It will download whatever yt-dlp decides is the best quality for the video and audio.",
},
{
"id": "441675ed-b739-40f0-a0b0-1ecfcb9dc48d",
"name": "Mobile",
- "cli": '-t mp4 --merge-output-format mp4 --add-chapters --remux-video mp4 \n--embed-metadata --embed-thumbnail \n--postprocessor-args "-movflags +faststart"',
+ "cli": '--socket-timeout 30 --download-archive %(config_path)s/archive.log\n-t mp4 --merge-output-format mp4 --add-chapters --remux-video mp4 \n--embed-metadata --embed-thumbnail \n--postprocessor-args "-movflags +faststart"',
"default": True,
"description": "This preset is designed for mobile devices. It will download the best quality video and audio in mp4 format, merge them, and add chapters, metadata, and thumbnail.",
},
{
"id": "441675ed-b739-40f0-a0b0-1ecfcb9dc48b",
"name": "1080p",
- "cli": "-S vcodec:h264 --format 'bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]'",
+ "cli": "--socket-timeout 30 --download-archive %(config_path)s/archive.log\n-S vcodec:h264 --format 'bv[height<=1080][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]'",
"default": True,
"description": "Download the best quality video and audio in mp4 format for 1080p resolution.",
},
{
"id": "9719fcc3-4cf2-4d88-b1e4-74dff3dba00e",
"name": "720p",
- "cli": "-S vcodec:h264 --format 'bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]'",
+ "cli": "--socket-timeout 30 --download-archive %(config_path)s/archive.log\n-S vcodec:h264 --format 'bv[height<=720][ext=mp4]+ba[ext=m4a]/b[ext=mp4]/b[ext=webm]'",
"default": True,
"description": "Download the best quality video and audio in mp4 format for 720p resolution.",
},
{
"id": "a6fd4b25-2b3e-458d-bb57-b75e41cc4330",
"name": "Audio Only",
- "cli": "--extract-audio --add-chapters --embed-metadata --embed-thumbnail --format 'bestaudio/best'",
+ "cli": "--socket-timeout 30 --download-archive %(config_path)s/archive.log\n--extract-audio --add-chapters --embed-metadata --embed-thumbnail --format 'bestaudio/best'",
"default": True,
"description": "This preset is designed to download only the audio of the video. It will extract the audio, add chapters, metadata, and thumbnail.",
},
@@ -55,7 +56,7 @@ DEFAULT_PRESETS: list[dict[int, dict[str, str | bool]]] = [
"description": 'This preset generate specific filename format and metadata to work with yt-dlp info reader plugins for jellyfin/emby and plex and to make play state sync work for WatchState.\n\nThere is one more step you need to do via Other > Terminal if you have it enabled or directly from container shell\n\nyt-dlp -I0 --write-info-json --write-thumbnail --convert-thumbnails jpg --paths /downloads/youtube -o "%(channel|Unknown_title)s [%(channel_id|Unknown_id)s]/%(title).180B [%(channel_id|Unknown_id)s].%(ext)s" -- https://www.youtube.com/channel/UCClfFsWcT3N2I7VTXXyt84A\n\nChange the url to the channel you want to download.\n\nFor more information please visit \nhttps://github.com/arabcoders/watchstate/blob/master/FAQ.md#how-to-get-watchstate-working-with-youtube-contentlibrary',
"folder": "youtube",
"template": "%(channel)s %(channel_id|Unknown_id)s/Season %(release_date>%Y,upload_date>%Y|Unknown)s/%(release_date>%Y%m%d,upload_date>%Y%m%d)s - %(title).180B [%(extractor)s-%(id)s].%(ext)s",
- "cli": "--windows-filenames --write-info-json --embed-info-json \n--convert-thumbnails jpg --write-thumbnail --embed-metadata",
+ "cli": "--socket-timeout 30 --download-archive %(config_path)s/archive.log\n--windows-filenames --write-info-json --embed-info-json \n--convert-thumbnails jpg --write-thumbnail --embed-metadata",
"default": True,
},
]
@@ -92,6 +93,7 @@ class Preset:
def json(self) -> str:
from .encoder import Encoder
+
return Encoder().encode(self.serialize())
def get(self, key: str, default: Any = None) -> Any:
diff --git a/app/library/YTDLPOpts.py b/app/library/YTDLPOpts.py
index ee421357..ab1b6239 100644
--- a/app/library/YTDLPOpts.py
+++ b/app/library/YTDLPOpts.py
@@ -22,7 +22,7 @@ class YTDLPOpts:
"""The command options for yt-dlp from preset."""
def __init__(self):
- self._config = Config.get_instance()
+ self._config: Config = Config.get_instance()
@staticmethod
def get_instance() -> "YTDLPOpts":
@@ -96,7 +96,7 @@ class YTDLPOpts:
"""
preset: Preset | None = Presets.get_instance().get(name)
- if not preset or "default" == name:
+ if not preset:
return self
if preset.cli:
@@ -169,7 +169,11 @@ class YTDLPOpts:
if len(self._item_cli) > 0:
try:
- user_cli: dict = arg_converter(args="\n".join(self._item_cli), level=True)
+ user_cli = "\n".join(self._item_cli)
+ for k, v in self._config.get_replacers().items():
+ user_cli = user_cli.replace(f"%({k})s", v if isinstance(v, str) else str(v))
+
+ user_cli: dict = arg_converter(args=user_cli, level=True)
except Exception as e:
msg = f"Invalid command options for yt-dlp were given. '{e!s}'."
raise ValueError(msg) from e
diff --git a/app/library/config.py b/app/library/config.py
index 3cb54a21..7331629b 100644
--- a/app/library/config.py
+++ b/app/library/config.py
@@ -402,6 +402,9 @@ class Config:
self._ytdlp_cli_mutable += f"\n--socket-timeout {self.socket_timeout}"
if self.keep_archive:
+ LOG.warning(
+ "The global 'keep_archive' option is deprecated and will be removed in future releases. please use presets instead."
+ )
archive_file: Path = Path(self.archive_file)
if not archive_file.exists():
LOG.info(f"Creating archive file '{archive_file}'.")
@@ -537,7 +540,7 @@ class Config:
data["ytdlp_version"] = Config._ytdlp_version()
return data
- def get_replacer(self) -> dict:
+ def get_replacers(self) -> dict:
"""
Get the variables that can be used in Command options for yt-dlp.
diff --git a/ui/app/pages/index.vue b/ui/app/pages/index.vue
index ffd3042d..c42cbf20 100644
--- a/ui/app/pages/index.vue
+++ b/ui/app/pages/index.vue
@@ -72,25 +72,16 @@
-
- The environment variables
YTP_KEEP_ARCHIVE and YTP_SOCKET_TIMEOUT will no
- longer be user-configurable. Their behavior will be part of the default presets. To keep
- your current behavior and avoid re-downloading, please add the following Command
- options for yt-dlp to your presets:
- --socket-timeout 30 --download-archive /config/archive.log
+ The following ENVs YTP_KEEP_ARCHIVE and YTP_SOCKET_TIMEOUT will be
+ removed.
+ Their behavior will be part of the default presets. To keep your current behavior
+ and avoid re-downloading, please add the following Command options for
+ yt-dlp to your presets:
+ --socket-timeout 30 --download-archive %(config_path)s/archive.log
-
- The global yt-dlp config file
/config/ytdlp.cli is deprecated and will be removed. Please
- migrate any global options into your presets.
-
- -
- The Basic mode (which limited the interface to the new download form) is being removed.
- Everything except what is available behind configurable flag will become part of the standard interface.
-
- -
- The file browser feature will be enabled by default, and the associated environment
- variable
YTP_BROWSER_ENABLED will be removed, We will keep the
- YTP_BROWSER_CONTROL_ENABLED to control whether you want to enable the file management
- features or not. it will default to false.
+ The global yt-dlp config file /config/ytdlp.cli will be removed. Please migrate to
+ presets.
- The archive.manual.log feature has been removed.
@@ -98,6 +89,22 @@
These changes help reduce confusion from multiple sources of truth. Going forward, presets
and the Command options for yt-dlp will be the single source of truth.
+
+ Notable changes in v0.10.x:
+
+
+ -
+ The file browser feature is going to be enabled by default. and the associated ENV
+ YTP_BROWSER_ENABLED will be removed, YTP_BROWSER_CONTROL_ENABLED will
+ remain and
+ will default to false.
+
+ -
+ The Basic mode (which limited the interface to just the new download form) along it's
+ associated ENV YTP_BASIC_MODE is being removed. Everything except what is available
+ behind configurable flag will become part of the standard interface.
+
+
diff --git a/ui/app/stores/ConfigStore.ts b/ui/app/stores/ConfigStore.ts
index 7b1bb05f..8b61e0af 100644
--- a/ui/app/stores/ConfigStore.ts
+++ b/ui/app/stores/ConfigStore.ts
@@ -6,7 +6,6 @@ export const useConfigStore = defineStore('config', () => {
showForm: useStorage('showForm', false),
app: {
download_path: '/downloads',
- keep_archive: false,
remove_files: false,
ui_update_title: true,
output_template: '',
diff --git a/ui/app/types/config.d.ts b/ui/app/types/config.d.ts
index 60960563..d6f22f2c 100644
--- a/ui/app/types/config.d.ts
+++ b/ui/app/types/config.d.ts
@@ -4,8 +4,6 @@ import type { DLField } from "./dl_fields"
type AppConfig = {
/** Path where downloaded files will be saved */
download_path: string
- /** Indicates if the app should keep an archive of downloaded files */
- keep_archive: boolean
/** Indicates if files should be removed after download */
remove_files: boolean
/** Indicates if the UI should update the title with the current download status */