postprocess plugin - degoya/rDownloader GitHub Wiki
A post-processing step runs once a package has been downloaded, after cleanup and before a user script: checking, converting, renaming, tagging. It is switched on globally or per category, in an ordered list — installing one changes nothing until somebody enables it.
| Scaffold | rdownloader plugin new --type postprocess |
plugin_type |
postprocess |
| World | postprocess-plugin |
| Exports | run |
| Template | sdk/templates/postprocess |
| Contract | Interface postprocess |
-
You never name a file. A package handle plus the names in
filesis all there is, and both only mean anything inside this invocation.filesholds every file of the package, folders walked, as relative paths (Film/film.mkv). A file may be renamed to a bare name in the folder it is in, never over an existing one. -
Stopping is normal. Check
should-stopand returnstoppedwith a checkpoint; the host stores it and hands it back, so a service restart resumes instead of starting over. -
You are told what is gone on purpose.
removednames, likefiles, what post-processing removed before your step ran: unpacked archive volumes, PAR2 files, what the cleanup deleted. A checksum list that names one of them is not wrong; no need to guess from an extension. -
A pass can say something.
completecarrieswarningsnext to the checkpoint: codes from yourlocales/, with parameters and an English fallback. The step is shown as completed with the warning on it — the place for "passed, but three listed files were not here".
The scaffold asks for nothing: reading the package is part of the type, through source, which no
manifest can ask for. Add net_http only for a step that has to reach a service.
[extension] claims stays empty: a step is switched on per category rather than matched against a
link.
Ask for exactly what you use: the install preview shows every grant, and a component importing an interface its manifest does not grant cannot be instantiated. Every capability is listed under Capabilities.
Nothing to do is skipped, not failed — a failure would fail every package in a category the
step is switched on for. Something worth saying about a pass is a warning, not a failure either. And the checkpoint holds everything a resumed run needs, not only an
offset: the scaffold's keeps the file, the offset and the checksum so far.
plugin new reads its templates from sdk/templates, so run it from a checkout of the repository:
git clone https://github.com/degoya/rDownloader.git
cd rDownloader
rdownloader plugin new --type postprocess --out ../mystep
cd ../mystepWithout an installation of rDownloader, the packaging tool rd-pack —
cargo build --profile release-test -p rd-pack in the checkout — takes the same arguments:
target/release-test/rd-pack plugin new --type postprocess --out ../mystep.
The directory name becomes the crate name and the plugin's slug (--name sets another). The
scaffold gets its own plugin id, its own copy of the contract in wit/rdownloader.wit and its own
Ed25519 key pair: plugin-signing.key, whose public half is already in manifest.toml. Keep that
file out of version control.
-
src/lib.rsholds the work and the checkpoint; the scaffold computes a CRC-32 per file, reading in chunks and stopping half-way without losing what was done. -
src/guest.rsholdsrun. -
manifest.toml:[limits] timeout_milliseconds— a step may run for minutes. -
locales/en.json: the English text of every failure and warning code you report.
Change description and author under [metadata], and read the comment at the top of
src/lib.rs: it states what the host promises this type.
cargo testThe unit tests need no WebAssembly toolchain: only src/guest.rs is wasm32-specific. Give every
answer of your provider you read a test of its own.
cargo build --release --target wasm32-unknown-unknown
wasm-tools component new target/wasm32-unknown-unknown/release/mystep.wasm -o target/mystep.wasmThis needs the wasm32-unknown-unknown target and wasm-tools 1.261.0, the version the bundled
plugins are made with: cargo build makes a core module that carries the world src/guest.rs
generates, and wasm-tools component new turns it into the component. The plugin is built
without WASI: a component importing anything outside rdownloader:plugin is refused — see
Building without WASI.
rdownloader plugin package --manifest manifest.toml \
--component target/mystep.wasm \
--locales locales --key plugin-signing.key --output mystep.rdplug
rdownloader plugin conformance mystep.rdplug --jsonconformance answers whether this application would run the package; it has to be clean before
you publish. For a key that outlives the scaffold, rdownloader plugin keygen --role plugin --output ./keys writes a pair: the Base64 in the .pub file goes into public_key, and key_id
gets a name of your own. In CI, RDOWNLOADER_PLUGIN_SIGNING_KEY holding the private key's PEM
text replaces --key. Details:
Packaging, signing and distribution.
For a first try without signing, package with --development instead of --key and start
rdownloader serve --plugin-development-mode, the only mode that accepts an unsigned package.
Install a signed package under Settings → Plugins → Add as an upload, or with
rdownloader plugin install mystep.rdplug --root data/plugins. Review before installing shows
every permission and the signing key; a key this installation has not seen asks to be trusted —
compare its fingerprint. The message after installing says whether the plugin runs at once or
after the next restart; see Installing and trust.
Enable the step under Settings → Post-processing → Scripts & upload, globally or for one category, and download a package into it; see Post-processing.
Publish the .rdplug together with your key's fingerprint, or — so that people get your new
versions in the Catalogue — in a plugin repository of your own: a signed index built with
rdownloader plugin index build and a repository-role key. A repository only delivers: every
package in it still needs your plugin key, approved by the person installing it. See
A repository index and
Running a plugin repository.
The SDK's reusable CI workflow,
sdk/ci/plugin.yml, builds,
checks the imports, packages and runs conformance on every push and pull request; it signs only
on a push to the default branch or a tag, so a pull request never sees the key.
- Post-processing steps in the plugin reference — what the host does with each call, in full
-
Interface
postprocess— every function and type, generated from the contract - Developing a plugin — the tools, translations, errors and what every type shares
-
The
postprocesstemplate on GitHub