Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 123 additions & 147 deletions README.md
Original file line number Diff line number Diff line change
@@ -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 <dataset>
```

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

<a href="https://github.com/baker-scripts/StarrScripts/graphs/contributors">
<img src="https://contrib.rocks/image?repo=baker-scripts/StarrScripts" alt="Contributors" />
</a>
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

Expand Down
Loading