pearlarr 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pearlarr-1.0.0/.gitignore +239 -0
- pearlarr-1.0.0/CHANGELOG.md +185 -0
- pearlarr-1.0.0/LICENSE +674 -0
- pearlarr-1.0.0/PKG-INFO +196 -0
- pearlarr-1.0.0/README.md +155 -0
- pearlarr-1.0.0/pearlarr/__init__.py +32 -0
- pearlarr-1.0.0/pearlarr/__main__.py +6 -0
- pearlarr-1.0.0/pearlarr/anibridge.py +473 -0
- pearlarr-1.0.0/pearlarr/anilist_client.py +337 -0
- pearlarr-1.0.0/pearlarr/anilist_gateway.py +222 -0
- pearlarr-1.0.0/pearlarr/arr_activity.py +178 -0
- pearlarr-1.0.0/pearlarr/arr_http.py +337 -0
- pearlarr-1.0.0/pearlarr/boot_flow.py +139 -0
- pearlarr-1.0.0/pearlarr/bootstrap.py +454 -0
- pearlarr-1.0.0/pearlarr/cache.py +938 -0
- pearlarr-1.0.0/pearlarr/cli.py +957 -0
- pearlarr-1.0.0/pearlarr/config.py +1063 -0
- pearlarr-1.0.0/pearlarr/config_migrations.py +185 -0
- pearlarr-1.0.0/pearlarr/config_sample.yml +237 -0
- pearlarr-1.0.0/pearlarr/console_caps.py +138 -0
- pearlarr-1.0.0/pearlarr/coverage.py +100 -0
- pearlarr-1.0.0/pearlarr/discord.py +138 -0
- pearlarr-1.0.0/pearlarr/env_registry.py +50 -0
- pearlarr-1.0.0/pearlarr/grab_pipeline.py +530 -0
- pearlarr-1.0.0/pearlarr/import_wait.py +808 -0
- pearlarr-1.0.0/pearlarr/json_narrow.py +24 -0
- pearlarr-1.0.0/pearlarr/log.py +666 -0
- pearlarr-1.0.0/pearlarr/manual_import.py +538 -0
- pearlarr-1.0.0/pearlarr/mapping_store.py +534 -0
- pearlarr-1.0.0/pearlarr/mappings.py +841 -0
- pearlarr-1.0.0/pearlarr/notify.py +476 -0
- pearlarr-1.0.0/pearlarr/output/__init__.py +202 -0
- pearlarr-1.0.0/pearlarr/output/boot_region.py +204 -0
- pearlarr-1.0.0/pearlarr/output/breadcrumbs.py +213 -0
- pearlarr-1.0.0/pearlarr/output/bridge.py +167 -0
- pearlarr-1.0.0/pearlarr/output/cli_surface.py +216 -0
- pearlarr-1.0.0/pearlarr/output/events.py +869 -0
- pearlarr-1.0.0/pearlarr/output/hub.py +609 -0
- pearlarr-1.0.0/pearlarr/output/live_region.py +94 -0
- pearlarr-1.0.0/pearlarr/output/recording.py +63 -0
- pearlarr-1.0.0/pearlarr/output/rich_renderer.py +296 -0
- pearlarr-1.0.0/pearlarr/output/runtime.py +93 -0
- pearlarr-1.0.0/pearlarr/output/scan_lines.py +481 -0
- pearlarr-1.0.0/pearlarr/output/scopes.py +340 -0
- pearlarr-1.0.0/pearlarr/output/textline.py +965 -0
- pearlarr-1.0.0/pearlarr/output/trace.py +39 -0
- pearlarr-1.0.0/pearlarr/output/wait_lines.py +401 -0
- pearlarr-1.0.0/pearlarr/output/wait_region.py +374 -0
- pearlarr-1.0.0/pearlarr/paths.py +63 -0
- pearlarr-1.0.0/pearlarr/planner.py +937 -0
- pearlarr-1.0.0/pearlarr/protocols.py +180 -0
- pearlarr-1.0.0/pearlarr/py.typed +0 -0
- pearlarr-1.0.0/pearlarr/radarr_client.py +236 -0
- pearlarr-1.0.0/pearlarr/replay.py +131 -0
- pearlarr-1.0.0/pearlarr/reporter.py +712 -0
- pearlarr-1.0.0/pearlarr/run_loop.py +461 -0
- pearlarr-1.0.0/pearlarr/run_services.py +656 -0
- pearlarr-1.0.0/pearlarr/runlock.py +68 -0
- pearlarr-1.0.0/pearlarr/seadex_filter.py +296 -0
- pearlarr-1.0.0/pearlarr/seadex_gateway.py +221 -0
- pearlarr-1.0.0/pearlarr/seadex_radarr.py +276 -0
- pearlarr-1.0.0/pearlarr/seadex_sonarr.py +525 -0
- pearlarr-1.0.0/pearlarr/seadex_types.py +894 -0
- pearlarr-1.0.0/pearlarr/sonarr_client.py +569 -0
- pearlarr-1.0.0/pearlarr/sonarr_episodes.py +457 -0
- pearlarr-1.0.0/pearlarr/sonarr_import.py +742 -0
- pearlarr-1.0.0/pearlarr/sonarr_import_plan.py +908 -0
- pearlarr-1.0.0/pearlarr/sonarr_mapper.py +196 -0
- pearlarr-1.0.0/pearlarr/sonarr_parse.py +383 -0
- pearlarr-1.0.0/pearlarr/sqlite_util.py +195 -0
- pearlarr-1.0.0/pearlarr/torrent.py +157 -0
- pearlarr-1.0.0/pearlarr/torrents.py +230 -0
- pearlarr-1.0.0/pearlarr/wait_view.py +221 -0
- pearlarr-1.0.0/pearlarr/web_client.py +92 -0
- pearlarr-1.0.0/pyproject.toml +291 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
#uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
#poetry.lock
|
|
109
|
+
#poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
#pdm.lock
|
|
116
|
+
#pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
#pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# SageMath parsed files
|
|
135
|
+
*.sage.py
|
|
136
|
+
|
|
137
|
+
# Environments
|
|
138
|
+
.env
|
|
139
|
+
.envrc
|
|
140
|
+
.venv
|
|
141
|
+
env/
|
|
142
|
+
venv/
|
|
143
|
+
ENV/
|
|
144
|
+
env.bak/
|
|
145
|
+
venv.bak/
|
|
146
|
+
|
|
147
|
+
# Spyder project settings
|
|
148
|
+
.spyderproject
|
|
149
|
+
.spyproject
|
|
150
|
+
|
|
151
|
+
# Rope project settings
|
|
152
|
+
.ropeproject
|
|
153
|
+
|
|
154
|
+
# mkdocs documentation
|
|
155
|
+
/site
|
|
156
|
+
|
|
157
|
+
# mypy
|
|
158
|
+
.mypy_cache/
|
|
159
|
+
.dmypy.json
|
|
160
|
+
dmypy.json
|
|
161
|
+
|
|
162
|
+
# Pyre type checker
|
|
163
|
+
.pyre/
|
|
164
|
+
|
|
165
|
+
# pytype static type analyzer
|
|
166
|
+
.pytype/
|
|
167
|
+
|
|
168
|
+
# Cython debug symbols
|
|
169
|
+
cython_debug/
|
|
170
|
+
|
|
171
|
+
# PyCharm
|
|
172
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
173
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
174
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
175
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
176
|
+
.idea/
|
|
177
|
+
|
|
178
|
+
# Abstra
|
|
179
|
+
# Abstra is an AI-powered process automation framework.
|
|
180
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
181
|
+
# Learn more at https://abstra.io/docs
|
|
182
|
+
.abstra/
|
|
183
|
+
|
|
184
|
+
# Visual Studio Code
|
|
185
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
186
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
188
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
189
|
+
# .vscode/
|
|
190
|
+
|
|
191
|
+
# Ruff stuff:
|
|
192
|
+
.ruff_cache/
|
|
193
|
+
|
|
194
|
+
# PyPI configuration file
|
|
195
|
+
.pypirc
|
|
196
|
+
|
|
197
|
+
# Cursor
|
|
198
|
+
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
|
199
|
+
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
|
200
|
+
# refer to https://docs.cursor.com/context/ignore-files
|
|
201
|
+
.cursorignore
|
|
202
|
+
.cursorindexingignore
|
|
203
|
+
|
|
204
|
+
# Marimo
|
|
205
|
+
marimo/_static/
|
|
206
|
+
marimo/_lsp/
|
|
207
|
+
__marimo__/
|
|
208
|
+
|
|
209
|
+
# macOS
|
|
210
|
+
.DS_Store
|
|
211
|
+
|
|
212
|
+
# Editor settings
|
|
213
|
+
.vscode/
|
|
214
|
+
|
|
215
|
+
# uv lockfile
|
|
216
|
+
# uv.lock
|
|
217
|
+
|
|
218
|
+
# Pearlarr runtime / user files (root-anchored: .github/ISSUE_TEMPLATE/config.yml
|
|
219
|
+
# is a tracked GitHub file, not a runtime config)
|
|
220
|
+
/config.yml
|
|
221
|
+
cache.json
|
|
222
|
+
cache.json.migrated
|
|
223
|
+
cache.db
|
|
224
|
+
cache.db-wal
|
|
225
|
+
cache.db-shm
|
|
226
|
+
cache.backup.db
|
|
227
|
+
cache.db.corrupt-*
|
|
228
|
+
mappings.db
|
|
229
|
+
mappings.db-wal
|
|
230
|
+
mappings.db-shm
|
|
231
|
+
mappings.db.corrupt-*
|
|
232
|
+
.pearlarr.lock
|
|
233
|
+
logs/
|
|
234
|
+
|
|
235
|
+
# Downloaded mapping data
|
|
236
|
+
anime_ids.json
|
|
237
|
+
anime-list-master.xml
|
|
238
|
+
anibridge_mappings.json
|
|
239
|
+
anibridge_mappings_v3.json
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable, user-observable changes to Pearlarr are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
|
+
|
|
6
|
+
Pearlarr is a fork of [bbtufty/seadexarr](https://github.com/bbtufty/seadexarr); everything up to and including 0.9.0 is inherited upstream history.
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-07-12
|
|
9
|
+
|
|
10
|
+
The first release of the fork.
|
|
11
|
+
|
|
12
|
+
### Upgrade notes
|
|
13
|
+
|
|
14
|
+
Coming from upstream 0.9.x:
|
|
15
|
+
|
|
16
|
+
- **The project is renamed** from SeaDexArr to Pearlarr: the package, the `pearlarr` command, the data directory, and the `PEARLARR_*` environment variables all follow (the `seadexarr` PyPI name stays with upstream).
|
|
17
|
+
- **The config format changed wholesale**, from flat keys to nested groups with strict validation.
|
|
18
|
+
Rewrite your `config.yml` against the new layout (`pearlarr config init` writes a commented starter, and [docs/configuration.md](docs/configuration.md) documents every key): `sonarr_url` is now `sonarr.url`, `qbit_info` is `qbittorrent.*`, `torrent_tags` is `qbittorrent.tags`, `seadex.public_only` is replaced by `seadex.private_releases`.
|
|
19
|
+
Unknown or misspelled keys now fail at load instead of being ignored.
|
|
20
|
+
- **The data location moved** off the install directory to one OS-standard data directory (`~/.local/share/pearlarr` on Linux, `~/Library/Application Support/pearlarr` on macOS).
|
|
21
|
+
`pearlarr config init` writes the new config there; set `PEARLARR_DATA_DIR` to relocate everything.
|
|
22
|
+
Logs follow the data directory instead of the working directory; `pearlarr paths` prints every resolved location.
|
|
23
|
+
- **The cache is not carried over**: the SQLite `cache.db` replaces `cache.json`, and the old file is not read.
|
|
24
|
+
The first run re-evaluates the library from scratch - cheap in the default matching mode, which checks what the arrs already have on disk; see [docs/deployment.md](docs/deployment.md#migrating-from-upstream-seadexarr) before enabling hash matching.
|
|
25
|
+
- **Python 3.13 or newer is required** (3.12 support dropped); the Docker image runs 3.14.
|
|
26
|
+
- **`SCHEDULE_TIME` is deprecated** in favor of `schedule.interval_hours` (on bare metal a still-set `SCHEDULE_TIME` wins, with a deprecation warning; the Docker image never reads it - set `PEARLARR_CRON`).
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Wait-for-completion and Sonarr manual import (`imports.wait_mode`: `off`/`deferred`/`blocking`/`hybrid`): Pearlarr waits for qBittorrent to finish grabbed torrents, lets Sonarr import them, and steps in with a series-pinned manual import when Sonarr can't.
|
|
31
|
+
Downloads that outlast a run are carried as pending imports and picked up by a later run.
|
|
32
|
+
- `notifications.wait_webhook_url`: a generic outbound webhook (ntfy, gotify, Home Assistant, ...) for the wait-pass summary, alongside the Discord webhook, with `notifications.wait_notify` controlling the push.
|
|
33
|
+
- `imports.post_import_category`: move a torrent to a different qBittorrent category (created if missing) once its import is verified complete, e.g. to give finished torrents different seeding rules.
|
|
34
|
+
- Arr-side activity detection (`advanced.detect_arr_activity`, on by default): each run polls the arr's history and re-checks titles whose files were imported or deleted arr-side since the last run, so a quality upgrade or manual grab is re-evaluated without waiting for SeaDex to update.
|
|
35
|
+
The first scan covers the last 30 days; a coverage gap re-checks everything once.
|
|
36
|
+
- AniBridge mappings as the primary ID/episode mapping source, mopping up titles the other sources miss.
|
|
37
|
+
- `seadex.ignore_anilist_ids` (skip specific AniList IDs), `seadex.ignore_tags` (filter releases by SeaDex tag), and `qbittorrent.tags` (tag every added torrent).
|
|
38
|
+
- Discord notifications are rich embeds with colors, links, and a version footer.
|
|
39
|
+
- The console shows a live cockpit during startup and the import-wait pass (spinners, ticking timers, files-imported progress).
|
|
40
|
+
- `advanced.log_format` picks the console surface (`auto`/`rich`/`plain`/`json`); `json` writes one JSON object per event to stdout - a versioned machine interface with a generated event catalog ([docs/output.md](docs/output.md)).
|
|
41
|
+
- Rotated logs are dated per-run backups, kept for `advanced.log_retention_days` days, replacing the fixed ten-file cascade.
|
|
42
|
+
- New CLI surface:
|
|
43
|
+
- `run single --dry-run` (simulate without grabbing, caching, or notifying), `--movie-id`/`--series-id` (single-title runs by TMDB/TVDB ID), and `--import-wait-mode`/`--log-level` per-run overrides.
|
|
44
|
+
- `config validate` and `config show` (effective config with secrets redacted, safe to paste into a bug report).
|
|
45
|
+
- `cache stats` and `cache check`.
|
|
46
|
+
- `pearlarr --version`, `-h` everywhere; a bare group command prints its help.
|
|
47
|
+
- `replay FILE` (or `-` for stdin) re-renders a captured `log_format: json` / `--json` stream back into the readable text log grammar, for reading a docker-captured log after the fact.
|
|
48
|
+
- `--json` on every subcommand (`paths`, `config init`/`validate`/`migrate`/`show`, `cache backup`/`restore`/`remove`/`stats`/`check`) emitting the same `schema_version` 1 envelope as run logs.
|
|
49
|
+
- Every config key can be set by environment variable as `PEARLARR_<GROUP>__<KEY>` (for example `PEARLARR_SONARR__URL`); values are parsed as YAML and an environment override beats the file.
|
|
50
|
+
- The scheduled-run cadence is a config field, `schedule.interval_hours` (default 6), re-read each cycle so an edit takes effect without a restart.
|
|
51
|
+
- Config schema versioning: `config_version` stamps the file, and a file from an older Pearlarr is migrated automatically in memory at every load (a nested-format file still saying `seadex.public_only` or `private_releases: allow` keeps loading, with a warning naming the fold).
|
|
52
|
+
`pearlarr config migrate` rewrites the file itself at the current schema, keeping the previous file as `config.yml.bak`.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- **Private releases are never grabbed** (SeaDex carries no download link for them, and no private-tracker auth is supported).
|
|
57
|
+
`seadex.private_releases` decides what happens when a title's preferred release is private-only: `warn` (default) warns and leaves the title uncached so it is re-checked every run; `fallback` grabs the entry's best public alternative, warning only when none exists.
|
|
58
|
+
Titles satisfied by a fallback are remembered; switching back to `warn` re-checks them and resurfaces the warning.
|
|
59
|
+
- Where multiple preferred release groups cover exactly the same files, only one is downloaded (preferring a public release) instead of all of them.
|
|
60
|
+
- `advanced.max_torrents_to_add` defaults to `10` instead of unlimited, so a first run against a large library doesn't flood qBittorrent - later runs pick up where the cap stopped.
|
|
61
|
+
Preview runs ignore the cap and always report the whole library; set the key to `0` to remove the cap.
|
|
62
|
+
- Only configured arrs run: a Sonarr-only (or Radarr-only) config skips the other arr with a ledger note instead of failing every cycle; explicitly selecting an unconfigured arr fails with a one-line error naming the missing keys; a half-configured arr (URL without API key, or the reverse) is warned about by name.
|
|
63
|
+
- `run single` with no selection flags runs every configured arr, mirroring scheduled mode (previously it printed a usage hint and failed).
|
|
64
|
+
- Failed CLI commands exit non-zero (previously always 0); a malformed config, missing backup, unreachable arr, or rejected API key is reported as a clean one-line error naming the config keys to check, instead of a traceback.
|
|
65
|
+
- `cache backup` writes via a temp file so a failed backup can never destroy the previous good one; `cache restore` copies instead of consuming the backup, so a restore is repeatable.
|
|
66
|
+
- `config init` refuses to overwrite an existing `config.yml` unless `--force` is passed.
|
|
67
|
+
- The Python import surface is internal as of 1.0.0: the supported interfaces are the CLI, the config schema, the JSON event stream, and the notification payloads.
|
|
68
|
+
- Runtime dependencies bumped to current majors (typer 0.26, rich 15, qbittorrent-api 2026.6).
|
|
69
|
+
|
|
70
|
+
### Deprecated
|
|
71
|
+
|
|
72
|
+
- `SCHEDULE_TIME` (Docker-era env var): set `schedule.interval_hours` (bare metal) or `PEARLARR_CRON` (Docker, which ignores `SCHEDULE_TIME`) instead; an invalid value now falls back to the configured cadence with a report instead of crashing the scheduler.
|
|
73
|
+
|
|
74
|
+
### Removed
|
|
75
|
+
|
|
76
|
+
- `seadex.public_only` (replaced by `seadex.private_releases`, see Upgrade notes).
|
|
77
|
+
- Python 3.12 support.
|
|
78
|
+
|
|
79
|
+
### Fixed
|
|
80
|
+
|
|
81
|
+
- `advanced.log_level` is honored everywhere: `ERROR` is a real level (the logger previously treated it as `INFO`), and CLI runs no longer force `INFO` regardless of config.
|
|
82
|
+
- In `fallback` mode, a public substitute never replaces a copy of the preferred private release you already own: when your private copy is stale-sized, Pearlarr warns and holds the title (the summary names both ways out) instead of overwriting it with the fallback.
|
|
83
|
+
|
|
84
|
+
## Inherited from upstream
|
|
85
|
+
|
|
86
|
+
The releases below are [bbtufty/seadexarr](https://github.com/bbtufty/seadexarr) history, reproduced as shipped.
|
|
87
|
+
|
|
88
|
+
## [0.9.0] - 2025-09-13
|
|
89
|
+
|
|
90
|
+
- Include PlexAniBridge-Mappings to mop up some missed titles
|
|
91
|
+
- Update cache if version/config changes
|
|
92
|
+
- Add option to ignore SeaDex update time
|
|
93
|
+
- Don't recreate cache on config change
|
|
94
|
+
- Add a number of useful CLI commands
|
|
95
|
+
- Include option to just check torrents by hash
|
|
96
|
+
- Update cache if no suitable releases found
|
|
97
|
+
- Check file sizes, for different versions of releases etc.
|
|
98
|
+
|
|
99
|
+
## [0.8.1] - 2025-09-05
|
|
100
|
+
|
|
101
|
+
- Fix cache not updating with versions
|
|
102
|
+
|
|
103
|
+
## [0.8.0] - 2025-09-05
|
|
104
|
+
|
|
105
|
+
- If we're ignoring Radarr movies in Sonarr, also check the cache
|
|
106
|
+
- Do a more proper check for episodes in Sonarr
|
|
107
|
+
- Ensure docker-compose run also uses cache
|
|
108
|
+
- Fix crash if AniList ID isn't already in cache
|
|
109
|
+
- Include AniList name in cache
|
|
110
|
+
- Sort cache by AniList ID
|
|
111
|
+
- Revert removing trackers
|
|
112
|
+
|
|
113
|
+
## [0.7.0] - 2025-08-24
|
|
114
|
+
|
|
115
|
+
- Create a cache to avoid checked entries that haven't updated
|
|
116
|
+
- Fix grabbing multiple releases when there's a mismatch in episode parsing
|
|
117
|
+
- Removed trackers that aren't used by SeaDex
|
|
118
|
+
- Add support for RuTracker
|
|
119
|
+
|
|
120
|
+
## [0.6.0] - 2025-08-13
|
|
121
|
+
|
|
122
|
+
- Take Ja-only releases if `prefer_dual_audio` is False
|
|
123
|
+
- Catch crash if SeaDex is unreachable
|
|
124
|
+
- Cleanup dictionaries
|
|
125
|
+
- Search specifically in qBittorrent by torrent hash, to speed up hash checks
|
|
126
|
+
- Skip adding downloads to torrent client if download flag not set
|
|
127
|
+
- Fix bug where maximum number of torrents added was not respected
|
|
128
|
+
|
|
129
|
+
## [0.5.0] - 2025-08-08
|
|
130
|
+
|
|
131
|
+
- Fix UTF-8 encoding warning in log
|
|
132
|
+
- Move to episode-based filtering of torrents for Sonarr
|
|
133
|
+
- Include SeaDex tags in log and Discord messages
|
|
134
|
+
- Add options to ignore unmonitored series/movies
|
|
135
|
+
- Save logs to file
|
|
136
|
+
- Ensure SCHEDULE_TIME is brought in as a float
|
|
137
|
+
- Fix Discord messages not getting pushed if no torrent client selected
|
|
138
|
+
- Fix adding too many torrents in one go
|
|
139
|
+
|
|
140
|
+
## [0.4.1] - 2025-07-31
|
|
141
|
+
|
|
142
|
+
- Add PyYAML to pyproject.toml
|
|
143
|
+
- Added support for AnimeTosho
|
|
144
|
+
|
|
145
|
+
## [0.4.0] - 2025-07-31
|
|
146
|
+
|
|
147
|
+
- Added ignore_movies_in_radarr for SeaDexSonarr, which will skip movies flagged as Specials in Sonarr that already exist in Radarr
|
|
148
|
+
- More robust config when parameters added
|
|
149
|
+
- Build Docker for every main update
|
|
150
|
+
- Fix crash when AniDB mapping contains no text
|
|
151
|
+
- Use IMDb for finding AniList mappings as well
|
|
152
|
+
- Initial support for other trackers
|
|
153
|
+
- Better handle Discord notifications and log messages when torrent already in client
|
|
154
|
+
- Map potentially weird episodes SeaDexSonarr if in Season 0 (Specials)
|
|
155
|
+
|
|
156
|
+
## [0.3.0] - 2025-07-30
|
|
157
|
+
|
|
158
|
+
- Added scheduling in Docker mode
|
|
159
|
+
|
|
160
|
+
## [0.2.0] - 2025-07-30
|
|
161
|
+
|
|
162
|
+
- Add Docker support
|
|
163
|
+
- Move to config files, to make the call simpler
|
|
164
|
+
- Fix crash if torrent in list but not already downloaded
|
|
165
|
+
|
|
166
|
+
## [0.1.0] - 2025-07-22
|
|
167
|
+
|
|
168
|
+
- Add support for Radarr
|
|
169
|
+
|
|
170
|
+
## [0.0.3] - 2025-07-22
|
|
171
|
+
|
|
172
|
+
- Rename from seadex_sonarr to seadexarr, in preparation for Radarr support
|
|
173
|
+
- Add interactive mode, for selecting when multiple "best" options are found
|
|
174
|
+
- Add support for adding torrents to qBittorrent
|
|
175
|
+
|
|
176
|
+
## [0.0.2] - 2025-07-13
|
|
177
|
+
|
|
178
|
+
- Improved Discord messaging
|
|
179
|
+
- Catch the case where we don't find any suitable SeaDex releases
|
|
180
|
+
- Include potentially weird offset mappings via AniDB lists
|
|
181
|
+
- Add a rest time to not hit AniList rate limiting
|
|
182
|
+
|
|
183
|
+
## [0.0.1] - 2025-07-12
|
|
184
|
+
|
|
185
|
+
- Initial release
|