Skip to content

Backport bug fixes from NemesisHubris/litfinder (addresses #999, #956, #1010, #1021, #1025, #1040)#1066

Merged
calibrain merged 12 commits into
calibrain:mainfrom
spin-drift:upstream-bug-fixes
Jun 15, 2026
Merged

Backport bug fixes from NemesisHubris/litfinder (addresses #999, #956, #1010, #1021, #1025, #1040)#1066
calibrain merged 12 commits into
calibrain:mainfrom
spin-drift:upstream-bug-fixes

Conversation

@spin-drift

Copy link
Copy Markdown
Contributor

Backport bug fixes from NemesisHubris/litfinder

Forwards a curated set of bug fixes from NemesisHubris/litfinder — a community fork of this project — that address open issues here. All commits preserve original authorship via git cherry-pick; this PR is a backport rather than original work. Each fix has been reviewed locally, lint/format-cleaned to match this repo's existing ruff config, and verified with the test suite. Rebrand strings, license switches, and features have been deliberately excluded.

Upstream issues addressed

Additional fixes (no open issue but clear bugs)

  • fix: Python 2 except syntax across 27 filesexcept X, Y: is a SyntaxError in Python 3 and prevents affected modules from importing at runtime. Mechanical sweep to except (X, Y):.
  • fix(abb): info hash validation with magnet fallback — adds SHA-1/SHA-256 hex validation on extracted info hashes; falls back to scanning the full page for a magnet link (e.g. posted in comments) when the table value is malformed. Also extends the exact-phrase fallback to manual queries and defaults the ABB listing language to en when missing, preventing valid results from being hidden by the language filter. Includes a small test-fixture fix (test(abb): use valid hex info hashes in scraper test fixtures) since the existing fixtures used non-hex placeholders that the new validation correctly rejects.
  • fix: Anna's Archive title parser — handles nested edition spans and filters lgli catalog descriptor entries (e.g. "Book/Online Audio") that were polluting search results.

Deliberately not included

Verification

  • Backend: 1879 passed, 96 skipped (1 preexisting failure on seleniumbase-dependent test in local venv; runs fine in the standard Docker image with the browser extra)
  • Lint, format, dead-code: all clean against this repo's existing ruff/vulture config
  • One follow-up cleanup commit (style: ruff lint and format fixes for ported commits) brings the cherry-picked code into compliance with this repo's ruff settings — no behavior changes there

Etiquette / credit

Per-commit authorship preserved by cherry-pick. The only edits to the original commits are:

  • fix: three upstream bugs — Apprise rebrand strings reverted to "Shelfmark" (noted in commit body, original author retained as Co-Authored-By via cherry-pick)
  • One follow-up style: commit for ruff config alignment

Big thanks to @NemesisHubris for the original work in LitFinder; this PR exists to make sure these fixes reach Shelfmark's wider user base. Happy to revise scope, split into smaller PRs, or split off the Py2 cleanup separately if that's preferable.

NemesisHubris and others added 12 commits June 14, 2026 01:39
- Add info hash validation with magnet link fallback in scraper
- Extend exact-phrase fallback to manual queries, not just auto-generated ones
- Default language to 'en' when ABB listing has no language field, preventing
  valid results from being hidden by the language filter
The fix(abb) port (f189a5f) added SHA-1/SHA-256 hex validation on info
hashes. The existing test fixtures used 'ABC123DEF456GHI789...' and
'ABC 123 DEF 456', neither of which is valid hex — pre-fix they passed
trivially, post-fix they (correctly) fail validation.

Replaced with valid 40-char hex strings; assertions still match on the
partial 'ABC123DEF456' prefix so the cleanup-behavior assertion is
preserved.
…k label, notification proxy

- calibrain#999: strip query string/fragment from mirror URLs in normalize_http_url
  so appending search paths doesn't produce malformed URLs
- calibrain#1025: add RTORRENT_AUDIOBOOK_LABEL setting; falls back to book label if unset
- calibrain#956: inject configured proxy env vars before Apprise dispatch so
  Telegram/Discord notifications respect the app proxy setting

Cherry-picked from NemesisHubris/litfinder@8e854f9 with the Apprise app_id,
description, and logo-URL strings reverted from "LitFinder" back to "Shelfmark".

Co-Authored-By: NemesisHubris <155838970+NemesisHubris@users.noreply.github.com>
Cover the specific scenarios that were broken:
- normalize_http_url: 5 cases for query/fragment stripping (calibrain#999)
- RTorrentClient: audiobook label selection and book-label fallback (calibrain#1025)
- TransmissionClient: stopped status treated as complete (seeding ratio fix)
- _apprise_proxy_env: http/socks5 proxy injection and env-var preservation (calibrain#956)

These tests would catch any future regression to the exact failure modes
that motivated each fix.
All instances of `except X, Y:` (Python 2 syntax) replaced with
`except (X, Y):` (Python 3). These were SyntaxErrors that would
prevent the affected modules from importing at runtime.
…fails

validate_destination() now tracks whether it created the directory
itself. If the write probe then fails, the empty directory is removed
so nothing is orphaned on disk.
handleCancel only called fetchStatus(), leaving a gap where the item
had left the live queue but not yet appeared in the DB snapshot.
Both are now refreshed in parallel so cancelled items stay visible.
…t infinite loop

_extract_slow_download_url was calling _get_download_url recursively
after each countdown wait with no depth limit. Pages that repeatedly
return a countdown (common through Tor) caused an infinite loop.

Now retries are bounded by _AA_COUNTDOWN_MAX_RETRIES (3). Also fixed
tor.sh rotation_monitor sending pkill -HUP twice in one cycle when
DNS resolution failed.
When DIRECT_DOWNLOAD_LANGUAGE_FROM_PATH is enabled, parse the file
path column in AA search results (e.g. lgli/N:\...\[BD FR] Book.cbz)
to infer language when AA's own metadata is missing or unknown.

Detection priority:
1. Explicit bracket tags: [FR], [BD FR], [En]
2. Keyed markers: "BD FR", "language: fr"
3. Full language names: "french", "deutsch"
4. Loose 2-3 char codes (ambiguous ones like "en"/"de" require
   bracket or key context to avoid false positives)

When enabled with a language filter, the server-side &lang= parameter
is suppressed and filtering is done locally so lgli files without AA
language metadata are not excluded before the path can be inspected.

Also relaxes _parse_search_result_row to only require title + format,
allowing sparse lgli rows (missing author/publisher/year) to pass through.
…age titles

AA changed their HTML structure — related-edition titles are now nested as
child spans inside the main title span. Using get_text() on the outer span
concatenated everything into a single garbled string. Fix extracts only the
direct NavigableString children. Adds a filter to skip lgli catalog-format
descriptor entries like "Book/Online Audio".
Aligns the cherry-picked commits with this repo's existing ruff config:
- SIM105 → contextlib.suppress(OSError) in destination.py cleanup path
- RET504 → inline final return in direct_download._normalize_candidate
- S105 → noqa on token == "all" (language sentinel, not a credential)
- Q000 + I001 + F401 → auto-fixed by ruff --fix
- ruff format on 30 files that drifted

No behavior changes.
@calibrain calibrain merged commit aba1a68 into calibrain:main Jun 15, 2026
10 checks passed
@calibrain

Copy link
Copy Markdown
Owner

Thank you so much for the contribution !
Great work on the backport !

doonga pushed a commit to greyrock-labs/home-ops that referenced this pull request Jun 15, 2026
….3.1) (#291)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/calibrain/shelfmark](https://github.com/calibrain/shelfmark) | patch | `v1.3.0` → `v1.3.1` |

---

### Release Notes

<details>
<summary>calibrain/shelfmark (ghcr.io/calibrain/shelfmark)</summary>

### [`v1.3.1`](https://github.com/calibrain/shelfmark/releases/tag/v1.3.1)

[Compare Source](calibrain/shelfmark@v1.3.1...v1.3.1)

##### What's Changed

- Update readme by [@&#8203;alexhb1](https://github.com/alexhb1) in [#&#8203;1000](calibrain/shelfmark#1000)
- Bump gunicorn from 25.3.0 to 26.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;990](calibrain/shelfmark#990)
- Bump the gh-actions group across 1 directory with 6 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1044](calibrain/shelfmark#1044)
- Bump the docker-base-image-digests group across 1 directory with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1015](calibrain/shelfmark#1015)
- Bump qbittorrent-api from 2025.11.1 to 2026.5.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;991](calibrain/shelfmark#991)
- Bump the npm-deps group across 1 directory with 14 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1043](calibrain/shelfmark#1043)
- Bump the python-deps group across 1 directory with 8 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1049](calibrain/shelfmark#1049)
- fix(transmission): handle completion when seed ratio is 0 by [@&#8203;cfoucher](https://github.com/cfoucher) in [#&#8203;1023](calibrain/shelfmark#1023)
- Fix CI/CD issues by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1052](calibrain/shelfmark#1052)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1051](calibrain/shelfmark#1051)
- Bump the python-deps group across 1 directory with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1054](calibrain/shelfmark#1054)
- Add `content_type=combined` URL parameter and `FORCE_COMBINED_SEARCH` user setting by [@&#8203;spin-drift](https://github.com/spin-drift) in [#&#8203;1058](calibrain/shelfmark#1058)
- Bump the gh-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1057](calibrain/shelfmark#1057)
- Bump the npm-deps group in /src/frontend with 6 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1056](calibrain/shelfmark#1056)
- Update dependabot.yml by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1060](calibrain/shelfmark#1060)
- Make IRC less spammy and require a bot name for search by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1065](calibrain/shelfmark#1065)
- Bump [@&#8203;types/node](https://github.com/types/node) from 25.9.2 to 25.9.3 in /src/frontend in the npm-deps group by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1063](calibrain/shelfmark#1063)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1064](calibrain/shelfmark#1064)
- Bump node from `2bdb65e` to `fb71d01` in the docker-base-image-digests group by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1061](calibrain/shelfmark#1061)
- fix: "No files found." check produces false positives when AA returns results alongside that string by [@&#8203;bullitt186](https://github.com/bullitt186) in [#&#8203;1067](calibrain/shelfmark#1067)
- Backport bug fixes from NemesisHubris/litfinder (addresses [#&#8203;999](calibrain/shelfmark#999), [#&#8203;956](calibrain/shelfmark#956), [#&#8203;1010](calibrain/shelfmark#1010), [#&#8203;1021](calibrain/shelfmark#1021), [#&#8203;1025](calibrain/shelfmark#1025), [#&#8203;1040](calibrain/shelfmark#1040)) by [@&#8203;spin-drift](https://github.com/spin-drift) in [#&#8203;1066](calibrain/shelfmark#1066)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1068](calibrain/shelfmark#1068)

##### New Contributors

- [@&#8203;cfoucher](https://github.com/cfoucher) made their first contribution in [#&#8203;1023](calibrain/shelfmark#1023)
- [@&#8203;spin-drift](https://github.com/spin-drift) made their first contribution in [#&#8203;1058](calibrain/shelfmark#1058)
- [@&#8203;bullitt186](https://github.com/bullitt186) made their first contribution in [#&#8203;1067](calibrain/shelfmark#1067)

**Full Changelog**: <calibrain/shelfmark@v1.3.0...v1.3.1>

### [`v1.3.1`](https://github.com/calibrain/shelfmark/releases/tag/v1.3.1)

[Compare Source](calibrain/shelfmark@v1.3.0...v1.3.1)

##### What's Changed

- Update readme by [@&#8203;alexhb1](https://github.com/alexhb1) in [#&#8203;1000](calibrain/shelfmark#1000)
- Bump gunicorn from 25.3.0 to 26.0.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;990](calibrain/shelfmark#990)
- Bump the gh-actions group across 1 directory with 6 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1044](calibrain/shelfmark#1044)
- Bump the docker-base-image-digests group across 1 directory with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1015](calibrain/shelfmark#1015)
- Bump qbittorrent-api from 2025.11.1 to 2026.5.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;991](calibrain/shelfmark#991)
- Bump the npm-deps group across 1 directory with 14 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1043](calibrain/shelfmark#1043)
- Bump the python-deps group across 1 directory with 8 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1049](calibrain/shelfmark#1049)
- fix(transmission): handle completion when seed ratio is 0 by [@&#8203;cfoucher](https://github.com/cfoucher) in [#&#8203;1023](calibrain/shelfmark#1023)
- Fix CI/CD issues by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1052](calibrain/shelfmark#1052)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1051](calibrain/shelfmark#1051)
- Bump the python-deps group across 1 directory with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1054](calibrain/shelfmark#1054)
- Add `content_type=combined` URL parameter and `FORCE_COMBINED_SEARCH` user setting by [@&#8203;spin-drift](https://github.com/spin-drift) in [#&#8203;1058](calibrain/shelfmark#1058)
- Bump the gh-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1057](calibrain/shelfmark#1057)
- Bump the npm-deps group in /src/frontend with 6 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1056](calibrain/shelfmark#1056)
- Update dependabot.yml by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1060](calibrain/shelfmark#1060)
- Make IRC less spammy and require a bot name for search by [@&#8203;calibrain](https://github.com/calibrain) in [#&#8203;1065](calibrain/shelfmark#1065)
- Bump [@&#8203;types/node](https://github.com/types/node) from 25.9.2 to 25.9.3 in /src/frontend in the npm-deps group by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1063](calibrain/shelfmark#1063)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1064](calibrain/shelfmark#1064)
- Bump node from `2bdb65e` to `fb71d01` in the docker-base-image-digests group by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1061](calibrain/shelfmark#1061)
- fix: "No files found." check produces false positives when AA returns results alongside that string by [@&#8203;bullitt186](https://github.com/bullitt186) in [#&#8203;1067](calibrain/shelfmark#1067)
- Backport bug fixes from NemesisHubris/litfinder (addresses [#&#8203;999](calibrain/shelfmark#999), [#&#8203;956](calibrain/shelfmark#956), [#&#8203;1010](calibrain/shelfmark#1010), [#&#8203;1021](calibrain/shelfmark#1021), [#&#8203;1025](calibrain/shelfmark#1025), [#&#8203;1040](calibrain/shelfmark#1040)) by [@&#8203;spin-drift](https://github.com/spin-drift) in [#&#8203;1066](calibrain/shelfmark#1066)
- Bump the python-deps group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;1068](calibrain/shelfmark#1068)

##### New Contributors

- [@&#8203;cfoucher](https://github.com/cfoucher) made their first contribution in [#&#8203;1023](calibrain/shelfmark#1023)
- [@&#8203;spin-drift](https://github.com/spin-drift) made their first contribution in [#&#8203;1058](calibrain/shelfmark#1058)
- [@&#8203;bullitt186](https://github.com/bullitt186) made their first contribution in [#&#8203;1067](calibrain/shelfmark#1067)

**Full Changelog**: <calibrain/shelfmark@v1.3.0...v1.3.1>

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMjIuMSIsInVwZGF0ZWRJblZlciI6IjQzLjIyMi4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19-->

Reviewed-on: https://git.greyrock.io/greyrock-labs/home-ops/pulls/291
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants