Added support for pausing adding items from playlist.

This commit is contained in:
arabcoders 2025-08-25 17:34:40 +03:00
parent 32bebcaf46
commit 19b9f8dc6c
6 changed files with 39 additions and 18 deletions

View file

@ -80,6 +80,9 @@
"onefile",
"pathex",
"platformdirs",
"playlistend",
"playlistrandom",
"playlistreverse",
"plexmatch",
"postprocessor",
"preferredcodec",

View file

@ -305,7 +305,7 @@ class DownloadQueue(metaclass=Singleton):
entries = entry.get("entries", [])
LOG.info(f"Processing '{entry.get('id')}: {entry.get('title')}' Playlist.")
LOG.info(f"Processing '{entry.get('id')}: {entry.get('title')} ({len(entries)})' Playlist.")
playlistCount = int(entry.get("playlist_count", len(entries)))
results = []
@ -325,11 +325,19 @@ class DownloadQueue(metaclass=Singleton):
}
async def playlist_processor(i: int, etr: dict):
await self.processors.acquire()
try:
LOG.info(
f"Processing '{entry.get('title')}: {i}/{playlistCount}' - ID: {etr.get('id')} - Title: {etr.get('title')}"
item_name = (
f"'{entry.get('title')}: {i}/{playlist_keys['n_entries']}' - '{etr.get('id')}: {etr.get('title')}'"
)
LOG.debug(f"Waiting to acquire lock for {item_name}")
await self.processors.acquire()
LOG.debug(f"Acquired lock for {item_name}")
if self.is_paused():
LOG.warning(f"Download is paused. Skipping processing of '{item_name}'.")
return {"status": "ok"}
LOG.info(f"Processing '{item_name}'.")
_status, _msg = ytdlp_reject(entry=etr, yt_params=yt_params)
if not _status:

View file

@ -57,7 +57,7 @@ REMOVE_KEYS: list = [
"opt_list_format": "-F, --list-formats",
"opt_dump_agent": "--dump-user-agent",
"opt_extractor_descriptions": "--extractor-descriptions",
"opt_list_impersonate_targets": "--list-impersonate-targets"
"opt_list_impersonate_targets": "--list-impersonate-targets",
},
]
@ -459,6 +459,7 @@ def arg_converter(
level: int | bool | None = None,
dumps: bool = False,
removed_options: list | None = None,
keep_defaults: bool = False,
) -> dict:
"""
Convert yt-dlp options to a dictionary.
@ -468,6 +469,7 @@ def arg_converter(
level (int|bool|None): Level of options to remove, True for all.
dumps (bool): Dump options as JSON.
removed_options (list|None): List of removed options.
keep_defaults (bool): Keep default options.
Returns:
dict: yt-dlp options dictionary.
@ -488,8 +490,7 @@ def arg_converter(
default_opts = _default_opts([]).ydl_opts
opts = yt_dlp.parse_options(shlex.split(args)).ydl_opts
diff = {k: v for k, v in opts.items() if default_opts[k] != v}
diff = {k: v for k, v in opts.items() if default_opts[k] != v} if not keep_defaults else opts.items()
if "postprocessors" in diff:
diff["postprocessors"] = [pp for pp in diff["postprocessors"] if pp not in default_opts["postprocessors"]]

View file

@ -1,5 +1,3 @@
from __future__ import annotations
from typing import Any
import yt_dlp
@ -47,13 +45,16 @@ def ytdlp_options() -> list[dict[str, Any]]:
),
}
for opt in opts
if (
(getattr(opt, "_short_opts", []) or getattr(opt, "_long_opts", []))
and getattr(opt, "help", None)
and "SUPPRESSHELP" not in getattr(opt, "help", "")
)
if (getattr(opt, "_long_opts", []) and getattr(opt, "help", None))
]
return collect(parser.option_list, "root") + [
opts = collect(parser.option_list, "root") + [
entry for grp in parser.option_groups for entry in collect(grp.option_list, grp.title or "other")
]
for opt in opts:
if "SUPPRESSHELP" in opt.get("description", ""):
opt["description"] = "No description available from yt-dlp."
return opts

View file

@ -523,6 +523,7 @@ const cancelSelected = () => {
}
cancelItems(selectedElms.value)
selectedElms.value = []
masterSelectAll.value = false
return true
}

View file

@ -141,10 +141,17 @@ watch(() => stateStore.queue, () => {
const pauseDownload = () => {
dialog_confirm.value.visible = true
dialog_confirm.value.html_message = `<span class="is-bold">Pause All non-active downloads?</span><br>
<span class="has-text-danger">
dialog_confirm.value.html_message = `
<span class="icon-text">
<span class="icon"><i class="fa-solid fa-exclamation-triangle"></i></span>
<span>This will not stop downloads that are currently in progress.</span>
<span class="is-bold">Pause All non-active downloads?</span>
</span>
<br>
<span class="has-text-danger">
<ul>
<li>This will not stop downloads that are currently in progress.</li>
<li>If you are in middle of adding a playlist/channel, it will break and stop adding more items.</li>
</ul>
</span>`
dialog_confirm.value.confirm = () => {
socket.emit('pause', {})