Added support for pausing adding items from playlist.
This commit is contained in:
parent
32bebcaf46
commit
19b9f8dc6c
6 changed files with 39 additions and 18 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -80,6 +80,9 @@
|
|||
"onefile",
|
||||
"pathex",
|
||||
"platformdirs",
|
||||
"playlistend",
|
||||
"playlistrandom",
|
||||
"playlistreverse",
|
||||
"plexmatch",
|
||||
"postprocessor",
|
||||
"preferredcodec",
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"]]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ const cancelSelected = () => {
|
|||
}
|
||||
cancelItems(selectedElms.value)
|
||||
selectedElms.value = []
|
||||
masterSelectAll.value = false
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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', {})
|
||||
|
|
|
|||
Loading…
Reference in a new issue