From 1409d2b4762016c6a95108dbd55e7785704bbd54 Mon Sep 17 00:00:00 2001 From: bakerboy448 <55419169+bakerboy448@users.noreply.github.com> Date: Tue, 20 Oct 2026 17:23:17 -0500 Subject: [PATCH] docs: rewrite README Co-Authored-By: Claude Sonnet 5.5 --- README.md | 270 +++++++++++++++++++++++++----------------------------- 1 file changed, 123 insertions(+), 147 deletions(-) diff --git a/README.md b/README.md index a28024e..f6d8a4d 100644 --- a/README.md +++ b/README.md @@ -1,159 +1,135 @@ # StarrScripts [![ShellCheck](https://github.com/baker-scripts/StarrScripts/actions/workflows/shellcheck.yml/badge.svg)](https://github.com/baker-scripts/StarrScripts/actions/workflows/shellcheck.yml) - -A curated collection of scripts to optimize and manage various functions related to Starr applications and associated tools. -Occasionally holds random useful scripts as well. -These scripts are designed to enhance functionality, improve management, and automate routine tasks. -All scripts are **Created By: [Bakerboy448](https://github.com/bakerboy448/) unless otherwise noted.** - -**Warning**: Do not edit files on Windows that will be executed on Linux without ensuring the line-endings are set to `LF`. -This means that `CRLF` cannot be used in .sh scripts. Bash scripts will not execute properly and you will receive an -error. - -## Scripts Overview - -### qui Cross-Seed Trigger for Starr Apps - -- **Script:** `qui-xseed.sh` -- **Description:** Triggers a [qui](https://github.com/autobrr/qui) data-based cross-seed search when Radarr or Sonarr completes an import. The script creates a dir-scan entry in qui, triggers a scan, polls for completion, then cleans up. -- **Creator:** [Bakerboy448](https://github.com/bakerboy448/) -- **Requirements:** - - [qui](https://github.com/autobrr/qui) with API access enabled - - Radarr/Sonarr with Custom Script connect support -- **Instructions:** - 1. Copy `.env.sample` to `.env` and configure the `QUI_*` variables. - 2. Docker Users: Mount `.env` and `qui-xseed.sh` to your Starr's `/config` mount. - 3. In Radarr: `Settings` -> `Connect` -> `Custom Script` -> select "On Import" and "On Upgrade". - 4. In Sonarr: `Settings` -> `Connect` -> `Custom Script` -> select "On Import Complete". - 5. Test and Save. -- **Configuration (`.env`):** - - `QUI_HOST` - qui hostname (default: `localhost`) - - `QUI_PORT` - qui API port (default: `7476`) - - `QUI_APIKEY` - qui API key - - `QUI_TARGET_INSTANCE_ID` - qui instance ID (default: `1`) - - `QUI_QBIT_PATH_PREFIX` - optional path prefix for qBittorrent - - `QUI_TAGS` - optional comma-separated tags - - `TORRENT_CLIENTS` - comma-separated torrent client names (default: `qBittorrent`) - - `USENET_CLIENTS` - comma-separated usenet client names (default: `SABnzbd`) - - `LOG_FILE` - log file path (default: `./qui_xseed.log`) -- **Notes:** - - Only errors are written to stderr (which starr apps capture). All other logging goes to the log file only, to avoid noisy notifications. - - The script is idempotent — duplicate download IDs are skipped via the ID log file. - - Replaces the legacy `xseed.sh` (removed in v4.0.0) which used the cross-seed API directly. - -### Duplicate File Manager - -- **Script:** `dupe.sh` -- **Description:** Executes `jdupes` to find and manage duplicate files in the specified directory. -- **Instructions:** - 1. Copy `.env.sample` to `.env`. - 2. Populate required values under "# Jdupes" header. - 3. Review and adjust script parameters to fit your use case. -- **Output:** Results are saved to a file as specified in the script. - -### Merge Folders Utility - -- **Script:** `merge_folders.py` -- **Description:** A robust utility designed for merging multiple directories into a single target directory, ensuring that no existing files are overwritten in the process. This script uses a recursive function to efficiently merge content, while providing detailed logging of each step to monitor the creation, movement, and skipping of files and directories. -- **Features:** - - **Recursive Merging:** Seamlessly combines contents of source directories into a target directory. - - **Non-destructive:** Preserves existing files by not overwriting them. - - **Error Handling:** Captures and logs errors during the merging process, ensuring reliable operations. - - **Detailed Logging:** Tracks and logs every file and directory operation, providing clear visibility into the process. -- **Usage Case:** Ideal for consolidating data in scenarios like organizing media libraries, merging data backups, or simplifying file system structures. -- **Instructions:** - 1. Update `source_dirs` and uncomment the variable - 2. Update `target_dir` and uncomment the variable - 3. Uncomment `atomic_moves` to engage the movement operation - 4. Run the script with `python3 merge_folders.py` - -### Plex Image Cleanup Updater - -- **Script:** `pic-update.sh` -- **Description:** Updates [Plex-Image-Cleanup](https://github.com/meisnate12/Plex-Image-Cleanup) to the latest branch. -- **Review:** Check that script parameters are suitable for your environment. - -### Plex Meta Manager Updater - -- **Script:** `pmm-update.sh` -- **Description:** Updates [Plex Meta Manager](https://github.com/meisnate12/Plex-Meta-Manager) to the latest branch. -- **Review:** Confirm script parameters align with your configuration. - -### QbitManage API Trigger - -- **Script:** `qbm-api-trigger.sh` -- **Description:** Triggers [QbitManage](https://github.com/StuffAnThings/qbit_manage) commands via Web API for specific torrent hashes. -- **Requirements:** - - QbitManage v4.5+ with Web API enabled (`QBT_WEB_SERVER=true`) - - QbitManage container accessible via HTTP -- **Instructions:** - 1. Configure QbitManage Web API in your docker-compose.yml - 2. In qBittorrent, navigate to `Options` -> `Downloads` -> `Run external program on torrent completion` - 3. Add command: `/path/to/qbm-api-trigger.sh %I` - 4. The `%I` variable passes the torrent hash to trigger commands like `tag_update`, `share_limits`, `rem_unregistered`, and `recheck` -- **Notes:** - - Script sends POST request to `http://127.0.0.1:4269/api/run-command` by default - - Modify `API_URL` and `COMMANDS` variables in script to customize behavior - - All execution details logged to `run_qbit_manage_commands.log` - -### QbitManage Updater - -- **Script:** `qbm-update.sh` -- **Description:** Updates [QbitManage](https://github.com/StuffAnThings/qbit_manage) to the latest branch. -- **Review:** Ensure script parameters match your setup before execution. - -### Servarr Bot Merger - -- **Script:** `servarr/servarr_bot_merge.sh` -- **Description:** Merges the latest changes from the Servarr Wiki Bot Branch into the Prowlarr Indexers Wiki Master. - -### Backup Config - -- **Script:** `backup_config.sh` -- **Description:** Backs up configuration directories to a compressed archive. - -### Fail2ban Config Dump - -- **Script:** `f2b-dump.sh` -- **Description:** Dumps Fail2ban configuration details to a temporary file for review. - -### Omegabrr Updater - -- **Script:** `omegabrr_upgrade.sh` -- **Description:** Upgrades [Omegabrr](https://github.com/autobrr/omegabrr) to the latest version. - -### Radarr Duplicate Finder - -- **Script:** `radarr_dupefinder.sh` -- **Description:** Finds duplicate files in Radarr library directories. - -### Sonarr Duplicate Finder - -- **Script:** `sonarr_dupefinder.sh` -- **Description:** Finds duplicate files in Sonarr library directories. - -### ZFS Snapshot Cleanup - -- **Script:** `zfsburn.sh` -- **Description:** Deletes ZFS autosnapshots older than a specified number of days. -- **Instructions:** - 1. Copy `.env.sample` to `.env`. - 2. Fill in the required values under "# ZFS Destroy" header. +[![Pre-commit](https://github.com/baker-scripts/StarrScripts/actions/workflows/pre-commit.yml/badge.svg)](https://github.com/baker-scripts/StarrScripts/actions/workflows/pre-commit.yml) +[![Release](https://img.shields.io/github/v/release/baker-scripts/StarrScripts)](https://github.com/baker-scripts/StarrScripts/releases) + +Bash and Python scripts for Starr apps (Radarr, Sonarr) and the tools around them: qui cross-seeding, qBittorrent automation, app updaters, duplicate finders, and ZFS snapshot cleanup. Created by [Bakerboy448](https://github.com/bakerboy448/) unless noted. + +Many scripts hardcode paths, service names, and hosts in variables at the top. Read a script and edit those before running it. Several use `sudo`, delete files, or restart services. + +Do not edit `.sh` files on Windows without keeping `LF` line endings; `CRLF` breaks Bash scripts. + +## Scripts + +| Script | Purpose | +| --- | --- | +| `qui-xseed.sh` | Radarr/Sonarr custom script: triggers a [qui](https://github.com/autobrr/qui) data-based cross-seed search after an import | +| `qbm-api-trigger.sh` | Runs [qbit_manage](https://github.com/StuffAnThings/qbit_manage) commands through its Web API for one torrent hash | +| `qbm-qbit.sh` | Waits 10 minutes, then runs qbit_manage once, under a lock file | +| `qbm-update.sh` | Updates a qbit_manage git checkout and restarts its service | +| `pmm-update.sh` | Updates a [Plex Meta Manager](https://github.com/meisnate12/Plex-Meta-Manager) checkout and restarts its service | +| `pic-update.sh` | Updates a [Plex-Image-Cleanup](https://github.com/meisnate12/Plex-Image-Cleanup) checkout and restarts its service | +| `omegabrr_upgrade.sh` | Installs the latest [Omegabrr](https://github.com/autobrr/omegabrr) `linux_x86_64` release and restarts its service | +| `notifiarr-branch-builder.sh` | Builds the Notifiarr client from a chosen branch, replaces the installed binary, and restarts the service | +| `dupe.sh` | Runs `jdupes` over two directories and hardlinks duplicates | +| `radarr_dupefinder.sh` | Prints directories containing more than one video file | +| `sonarr_dupefinder.sh` | Prints directories containing the same episode number more than once | +| `merge_folders.py` | Merges several directories into one without overwriting existing files | +| `zfsburn.sh` | Destroys ZFS autosnapshots beyond per-type count limits | +| `backup_config.sh` | Archives `/.config` (minus media) and rsyncs the archive to a backup path | +| `f2b-dump.sh` | Collects Fail2ban status and config files and uploads them to termbin.com | +| `servarr/servarr_bot_merge.sh` | Rebases the Servarr Wiki bot branch onto `master` and pushes it | + +## Quick start: qui cross-seed trigger + +1. Copy `.env.sample` to `.env` next to `qui-xseed.sh` and fill in the `QUI_*`, `TORRENT_CLIENTS`, and `USENET_CLIENTS` values. +2. Docker users: mount `.env` and `qui-xseed.sh` into the Starr app's `/config`. +3. Radarr: `Settings` -> `Connect` -> `Custom Script`, enable "On Import" and "On File Upgrade". +4. Sonarr: `Settings` -> `Connect` -> `Custom Script`, enable "On Import Complete". +5. Save and use Test. + +On each import the script adds the parent directory to qui as a cross-seed data directory, triggers a scan, polls qui every 10, 20, ... seconds (up to a day) until it finishes, then removes the directory. For Sonarr episodes it scans the whole season folder. Download IDs already in `LOGID_FILE` are skipped. Only warnings and errors go to stderr, so the Starr app does not raise notifications for routine output. It replaces the legacy `xseed.sh` removed in v4.0.0. + +## Configuration + +Settings come from `.env` in the script's directory (see `.env.sample`) or the environment. Defaults below are the script defaults, which differ from some `.env.sample` examples. + +### qui-xseed.sh + +| Variable | Default | Purpose | +| --- | --- | --- | +| `QUI_HOST` | `localhost` | qui host | +| `QUI_PORT` | `7476` | qui API port | +| `QUI_APIKEY` | placeholder | qui API key | +| `QUI_TARGET_INSTANCE_ID` | `1` | qui instance ID | +| `QUI_QBIT_PATH_PREFIX` | empty | Path prefix as qBittorrent sees it, if it differs from the Starr app's | +| `QUI_TAGS` | empty | Comma-separated qBittorrent tags | +| `TORRENT_CLIENTS` | `Qbit` | Comma-separated Starr download client names that are torrent clients | +| `USENET_CLIENTS` | `SABnzbd` | Comma-separated usenet client names | +| `LOG_FILE` | `qui_xseed.log` in the script directory | Log file | +| `LOGID_FILE` | `qui_xseed_id.log` in the script directory | Processed download IDs | + +### dupe.sh + +| Variable | Default | +| --- | --- | +| `JDUPES_SOURCE_DIR` | `/mnt/data/media/` | +| `JDUPES_DESTINATION_DIR` | `/mnt/data/torrents/` | +| `JDUPES_OUTPUT_LOG` | `/mnt/data/jdupes.log` | +| `JDUPES_HASH_DB` | `/.config/jdupes_hashdb` | +| `JDUPES_COMMAND` | `/usr/local/bin/jdupes` | +| `JDUPES_EXCLUDE_DIRS` | `-X nostr:.RecycleBin -X nostr:.trash` | +| `JDUPES_INCLUDE_EXT` | `mp4,mkv,avi` | +| `DEBUG` | `false` | + +### zfsburn.sh + +| Variable | Default | Purpose | +| --- | --- | --- | +| `VERBOSE` | `1` | Per-snapshot logging | +| `MAX_FREQ`, `MAX_HOURLY`, `MAX_DAILY`, `MAX_WEEKLY`, `MAX_MONTHLY` | 4, 2, 7, 4, 3 | Count limit per snapshot type; `0` destroys all of that type | + +### qbm-qbit.sh + +| Variable | Default | +| --- | --- | +| `QBIT_MANAGE_LOCK_FILE_PATH` | `/var/lock/qbm-qbit.lock` | +| `QBIT_MANAGE_PATH` | `/opt/qbit-manage` | +| `QBIT_MANAGE_VENV_PATH` | `/opt/qbit-manage/.venv` | +| `QBIT_MANAGE_CONFIG_PATH` | `/opt/qbit-manage/config.yml` | +| `QBIT_MANAGE_OPTIONS` | `-cs -re -cu -tu -ru -sl -r` | + +It reads `.env` from the current directory and needs the `lockfile` command (procmail package). + +## Usage + +```bash +# qBittorrent "Run external program on torrent completion" (Options -> Downloads) +/path/to/qbm-api-trigger.sh %I + +# Updaters (run as the checkout's owner; pass "true" to force an update) +./qbm-update.sh [true] +./pmm-update.sh [true] +./pic-update.sh [true] + +# Notifiarr from source (prompts interactively) +./notifiarr-branch-builder.sh [--repo-url URL] [--repo-dir DIR] [--bin-path PATH] [--branch BRANCH] [--reinstall-apt] + +# Duplicates and cleanup +./dupe.sh +./radarr_dupefinder.sh [directory] +./sonarr_dupefinder.sh [directory] +./zfsburn.sh +``` + +Script notes: + +- `qbm-api-trigger.sh` posts `tag_update`, `share_limits`, `rem_unregistered`, and `recheck` for the hash to `http://127.0.0.1:4269/api/run-command` and logs to `run_qbit_manage_commands.log`. Edit `API_URL` and `COMMANDS` in the script. qbit_manage's Web API must be enabled and reachable. +- `qbm-update.sh`, `pmm-update.sh`, and `pic-update.sh` hard-reset the checkout to its upstream branch, so local changes there are lost. Default paths are `/opt/qbit_manage`, `/opt/Plex-Meta-Manager`, and `/opt/Plex-Image-Cleanup`; services restarted are `qbmanage`, `pmm`, and `pmm-image`. +- `omegabrr_upgrade.sh` restarts the `omegabrr@bakerboy448` service; change `service_name` first. +- `merge_folders.py` ships with its example call commented out. Set `source_dirs` and `target_dir`, uncomment the `atomic_moves(...)` call at the bottom, then run `python3 merge_folders.py`. +- `backup_config.sh` uses `/.config` as the source and `/mnt/backup-server/.config` as the destination; edit the variables at the top. +- `f2b-dump.sh` uploads its report to termbin.com, a public paste service. Review the output first or remove the upload line. +- `servarr/servarr_bot_merge.sh` expects a clone at `REPO_DIR` (set at the top of the script) with push access to `Servarr/Wiki`. ## Contributing -Issues and pull requests welcome. See the [contributing guidelines](https://github.com/baker-scripts/.github/blob/main/CONTRIBUTING.md); [open an issue](https://github.com/baker-scripts/StarrScripts/issues) to discuss larger changes. - -## Contributors - - - Contributors - +Issues and pull requests welcome. See the [contributing guidelines](https://github.com/baker-scripts/.github/blob/main/CONTRIBUTING.md) and [open an issue](https://github.com/baker-scripts/StarrScripts/issues) to discuss larger changes. Run `pre-commit run --all-files` before committing. ## Disclaimer -These scripts are provided as-is with no warranty. Scripts may delete files, modify configurations, or interact with external APIs. Always review scripts before running and test in a non-production environment first. The authors are not responsible for any data loss or issues resulting from their use. +Provided as-is with no warranty. These scripts can delete files, change configuration, and call external APIs. Review them and test outside production first. ## License