- match_bangumi_in_list: also accept a torrent whose rebuilt title equals
the stored title_raw (#1103, #1114)
- download_bangumi / collect_season: drop items whose season or type
conflicts with the bangumi (#1105)
- request_url: swap in a fresh shared client on PoolTimeout without
closing the old one (#1104)
- classic parser: Unicode Roman numeral season, strip fullwidth dash
wrapper (#1108)
- Docker HEALTHCHECK: healthcheck.py reads the configured WebUI port and
probes IPv4 then IPv6 loopback (#1106)
- scheduler: non-positive interval falls back to 1s; deploy docs cap
container logs at 10 MB x 3 (#1117)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KU9GqKzULrNb7MN5T9TYix
The star history chart in the README has been broken for a while due to GitHub's stargazer API restrictions, so visitors no longer see an up-to-date chart. Update the chart image and link to a working mirror at star-history.dera.page so the graph renders correctly again. The chart was originally added in e9367e3.
Empty sensitive fields were masked to '********' in GET /config, so the
UI showed a phantom password where none was set. Worse, 3.2.3/3.2.4
masked without restoring on save, so users who saved config on those
versions had the literal sentinel written into stored proxy/downloader
credentials, breaking authentication until manually cleared.
- _sanitize_dict now masks only non-empty values.
- Settings._migrate_old_config scrubs literal '********' sentinels from
sensitive fields on load (original values are unrecoverable), logging
a warning so users know to re-enter real secrets.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WTfJZ3EzCpY8SLhzXT6Sf
BangumiDatabase.delete_all() issued a bare DELETE FROM bangumi while
torrent.bangumi_id and aria2_gid.bangumi_id rows still referenced it;
with PRAGMA foreign_keys=ON the whole reset rolled back with
IntegrityError, and the surviving torrent dedup rows made re-added
bangumi skip episodes as already downloaded. Delete bangumi-linked
torrent records (same semantics as delete_rule) and detach aria2_gid
mappings before the table wipe.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WTfJZ3EzCpY8SLhzXT6Sf
Subtitle groups sometimes release TV specials without an episode number
or any special/movie marker (e.g. LoliHouse's ONE PIECE HEROINES). The
Preview engine's admission policy already accepts such evidence-backed
single releases as eps_collect bangumi, but the classic engine's legacy
Episode projection rejected them outright, so default installs silently
skipped the torrent.
Align classic admission with the Preview persistence policy for exactly
this shape (no episode, unknown media type, admissible under
persistence_target). The frozen legacy Episode contract and its golden
corpus stay untouched; numbered legacy rejections (e.g. fractional
episodes) keep their behavior.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WTfJZ3EzCpY8SLhzXT6Sf
Download-complete notifications were silently dropped when sendPhoto
failed: post_form returned None on any error and the provider crashed
on resp.status_code, with no text fallback. HTTP rejections were also
logged as "Cannot connect", hiding the real cause.
- save_image now records the poster's source URL in a .url sidecar;
Telegram prefers sendPhoto with that URL (server-side fetch), falls
back to local multipart upload, then to a plain text message.
- load_image returns None instead of raising when the cached file is
missing.
- post_url/post_form log HTTP status and response body separately from
connection errors.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WTfJZ3EzCpY8SLhzXT6Sf
Deleting a bangumi disables its orphan standalone RSS feed (#1053), but
re-subscribing the same feed hit the duplicate-URL early return in
RSSDatabase.add() and never reset enabled, so the rebuilt bangumi
silently stopped updating. Re-enable the existing row and report it as
a successful add.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019WTfJZ3EzCpY8SLhzXT6Sf
Replaces the monolithic regex-based parser with a multi-stage tokenizer
pipeline (normalize, tokenize, classify, resolve). Fixes multiple parsing
bugs: Atlas format (#986), VTuber/Lv2 title splits (#798, #766),
Pre-episode format (#794), western S01E05 format (#764), and separator
dash leaking into titles (#819).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add detection and handling for anime movies (剧场版/劇場版) as a
separate entity from TV series. Previously, movies in RSS feeds were
either parsed as episode 0 or skipped entirely.
- Add TokenKind.MOVIE and movie keyword/pattern detection in tokenizer
- Add is_movie flag to Episode dataclass
- Create Movie SQLModel, MovieDatabase with CRUD + TTL cache
- Add migration v10 to create movie table
- Route TitleParser.raw_parser() to return Movie or Bangumi
- Update RSS analyser/engine for movie-aware parsing and downloads
- Add movie save path (no Season subfolder) and rename logic
- Add Movie REST API endpoints (get/update/delete/disable/enable)
- Add 11 tests for movie marker detection and non-movie regression
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>