mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-11 19:45:06 +00:00
feat(dl): add --no-postscript to skip post-scripts for one run
This commit is contained in:
@@ -149,6 +149,7 @@ Keep only certain track types, or skip certain track types.
|
||||
| `--tag` | Group tag override. |
|
||||
| `--repack` | Add a `REPACK` tag to the filename. |
|
||||
| `--postscript` | Run a command after each output file, with `{variable}` placeholders substituted. Repeatable. Replaces the `post_scripts` config for this run. See [Post-scripts](../reference/configuration/post-scripts.md). |
|
||||
| `--no-postscript` | Run no post-script for this run, neither the configured ones nor `--postscript`. |
|
||||
|
||||
### Metadata & tagging
|
||||
|
||||
|
||||
@@ -698,6 +698,13 @@ that run writes no muxed output. A `failure` post-script still operates if the d
|
||||
unshackle dl --postscript "python /opt/upload.py {filepath} --service={service}" EXAMPLE 81234567
|
||||
```
|
||||
|
||||
`--no-postscript` operates the run with no post-script at all. It silences the `post_scripts`
|
||||
config and `--postscript` together, for every event and mode.
|
||||
|
||||
```shell title="Skip the uploader for one run"
|
||||
unshackle dl --no-postscript EXAMPLE 81234567
|
||||
```
|
||||
|
||||
For post-scripts that continue across runs, for the `season` and `run` modes, for `failure`
|
||||
post-scripts and for the full variable list, see
|
||||
[Post-scripts](../reference/configuration/post-scripts.md).
|
||||
@@ -946,7 +953,7 @@ authoritative list.
|
||||
| `--best-available` | | Degrade gracefully instead of failing. |
|
||||
| `--output` | `-o` | Output directory for this run. |
|
||||
| `--split-audio` / `--merge-video` / `--no-mux` | | Muxing behaviour. |
|
||||
| `--postscript` | | Run a command after each output file. Repeatable. |
|
||||
| `--postscript` / `--no-postscript` | | Run a command after each output file, or run none. |
|
||||
| `--proxy` / `--no-proxy` / `--no-proxy-download` | | Proxy control. |
|
||||
| `--workers` / `--downloads` / `--slow` | | Concurrency and pacing. |
|
||||
| `--list` / `--list-titles` / `--skip-dl` | | Dry runs. |
|
||||
|
||||
@@ -282,6 +282,16 @@ It replaces the `post_scripts` config for that run rather than adding to it, so
|
||||
configured entry runs while it is in use. That includes your `season`, `run` and `failure`
|
||||
entries, which have no `--postscript` equivalent.
|
||||
|
||||
## `--no-postscript`
|
||||
|
||||
`dl --no-postscript` operates the run with no post-script. It silences every configured entry
|
||||
and every `--postscript` command, for each event and mode. Use it to skip an uploader or a
|
||||
notifier for one run without an edit to `unshackle.yaml`.
|
||||
|
||||
```console
|
||||
$ unshackle dl --no-postscript SERVICE TITLE_ID
|
||||
```
|
||||
|
||||
## The REST API
|
||||
|
||||
The API never accepts a post-script command. `postscript`, `post_script` and `post_scripts`
|
||||
|
||||
@@ -7,8 +7,12 @@ from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
import unshackle.core.utils.post_scripts as ps
|
||||
from unshackle.core.config import config
|
||||
from unshackle.core.utils.post_scripts import (
|
||||
EVENTS,
|
||||
MODES,
|
||||
NO_POST_SCRIPTS,
|
||||
SIDECAR_SEPARATOR,
|
||||
_entries,
|
||||
build_context,
|
||||
@@ -217,3 +221,14 @@ def test_wait_true_waits_for_the_script_and_logs_the_exit_code(monkeypatch, capl
|
||||
def test_wait_defaults_to_fire_and_forget(monkeypatch):
|
||||
slow = 'python -c "import time; time.sleep(0.3)"'
|
||||
assert _dispatch_seconds(monkeypatch, {"command": slow}) < 0.3
|
||||
|
||||
|
||||
def test_no_postscript_override_silences_every_event_and_mode(monkeypatch):
|
||||
"""``dl --no-postscript`` passes NO_POST_SCRIPTS as the override list. Nothing may spawn."""
|
||||
monkeypatch.setattr(config, "post_scripts", [{"command": "should_not_run.py", "mode": mode} for mode in MODES])
|
||||
spawned: list[list[str]] = []
|
||||
monkeypatch.setattr(ps.subprocess, "Popen", lambda argv, **kw: spawned.append(argv))
|
||||
for event in EVENTS:
|
||||
for mode in MODES:
|
||||
dispatch(event, mode, {"filepath": "/x/y.mkv"}, NO_POST_SCRIPTS)
|
||||
assert spawned == []
|
||||
|
||||
@@ -99,7 +99,7 @@ from unshackle.core.utils.click_types import (
|
||||
SubtitleCodecChoice,
|
||||
)
|
||||
from unshackle.core.utils.collections import ci_get, merge_dict
|
||||
from unshackle.core.utils.post_scripts import build_context, dispatch, season_context
|
||||
from unshackle.core.utils.post_scripts import NO_POST_SCRIPTS, build_context, dispatch, season_context
|
||||
from unshackle.core.utils.redact import mask_proxy
|
||||
from unshackle.core.utils.selector import select_multiple
|
||||
from unshackle.core.utils.subprocess import ffprobe
|
||||
@@ -875,6 +875,12 @@ class dl:
|
||||
"variables substituted. Repeatable. Replaces the post_scripts config for this run."
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
"--no-postscript",
|
||||
is_flag=True,
|
||||
default=False,
|
||||
help="Do not run any post-script for this run, configured or --postscript.",
|
||||
)
|
||||
@click.option(
|
||||
"--workers",
|
||||
type=int,
|
||||
@@ -1533,9 +1539,12 @@ class dl:
|
||||
real_audio_bitrate: bool = False,
|
||||
progress_sink: Optional[Callable[[dict[str, Any]], None]] = None,
|
||||
postscript: Sequence[str] = (),
|
||||
no_postscript: bool = False,
|
||||
*_: Any,
|
||||
**__: Any,
|
||||
) -> None:
|
||||
if no_postscript:
|
||||
postscript = NO_POST_SCRIPTS
|
||||
if continue_downloads:
|
||||
config.continue_downloads = True
|
||||
self.tmdb_searched = False
|
||||
|
||||
@@ -35,6 +35,8 @@ EVENTS = ("success", "failure")
|
||||
MODES = ("file", "season", "run")
|
||||
|
||||
SIDECAR_SEPARATOR = "\n"
|
||||
NO_POST_SCRIPTS: tuple[str, ...] = ("",)
|
||||
"""``dl --no-postscript``: an override list that replaces the config and holds no command to run."""
|
||||
|
||||
_warned_entries: set[str] = set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user