Repository navigation
v0.73.0: Missing details filled in; sources rated Adult only, AniList's pace and engine passwords - #273
Merged
Conversation
…ount limited below 18 (rebuild of #256) Admin → Sources → a source → Age rating: Automatic leaves it to the source's extension, Adult only makes the whole source adult whatever the extension declares -- the one way a built-in or added site can be rated. - The rating is the 18+ lists' existing adult_sources, now a permission as well as a surfacing filter: sourceAllowedFor refuses a rated source to an account limited below 18 exactly as it refuses a flagged one, everywhere it is asked (latest, popular, detail, add, preview, the fan-outs, icons, archive, Find). Held in memory because the check is synchronous: loaded at boot, replaced on every write and every read of the lists; a capped account's request reads it first if nothing has yet. - PUT /api/admin/sources/:id/age-rating {ageRating: 18 | null}, one atomic jsonb statement, audited source.age_rating; 409 too_many past 200 (said code rating.tooMany). The overview reports ageRating and defaultAgeRating. - No "Mixed": cancelling an extension's adult flag would lift the age cap for a whole site (the #130 ruling). - The 18+ filter's source chips go: the list they saved is a permission now, so it is set on the source, and the section says where. Sources ticked there become refused to capped accounts: said in the upgrade note. - Tests: sourceAdultRating.int drives the five by-id routes as a capped account before and after the rating, each reintroduced; the preview note says why that step holds by the age_limited rule as well. - 8 new strings, translated in all eight languages. Co-Authored-By: Squeaks72 <Squeaks72@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ilds of #257 and #245) Admin → Settings → Library housekeeping → Fill in missing details, off by default: the nightly repair's ninth step (`details`) gives a series with no description, genres or author of its own the ones another place has, and a series with no chapters yet a cover. - Its own layer, series_auto_details, read only where the series' own value (lib_series, the scan) and the admin's edit (series_overrides) are both empty: lib/autoDetailsSql.ts is the one expression for the series source, OPDS, the Komga authors and the 18+ filter (which judges the genres a series shows), and the hero rule counts all three. #257 wrote into series_overrides: it shadowed better data a later scan brought, refilled genres cleared on purpose (`{}`), and could change what Show 18+ hides. - AniList first (#245, ported AniList-first): one batched Media(id_in:) request per fifty series linked there with a checked link, in libraries whose lookups are on, in English. No Kitsu or MangaUpdates call. mediaById reads through readCapped. - Then, as stepNames does: at most REPAIR_DETAILS_MAX (15) series that are kept updated, their own source and then the ones they follow in their language, only usable sources (standing, then blockedNow right before), each lookup bounded by the source's budget and the series by a minute; text through cleanDescription and cleanGenres. - A series asked waits 30 days (sources_at, anilist_at); a manual follow asks at once. Counters, a Tasks line, the limits and the estimate. Switching it off deletes the layer and puts back any cover it set. Forget purges it. - Behaviour tests (autoDetails.int): off by default, the order and the cleaning, below the scan, `{}` kept, the cooldown and language rules, monitored only, the 18+ filter, AniList's one batch, the month's wait, the manual follow over HTTP, the take-back. Three reintroduced. - 5 new strings, translated in all eight languages. Co-Authored-By: Squeaks72 <Squeaks72@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd the desktop's changes every launch - Unraid: the engine template publishes its port on the bridge network (Uchiyomi reaches it at the server's address), so a new install starts with AUTH_MODE basic_auth, AUTH_USERNAME uchiyomi and a required, masked AUTH_PASSWORD; the Uchiyomi template's SUWAYOMI_USERNAME defaults to the same user. The three variables have been in the template since its first version, so an existing install keeps its own values (Unraid adds missing variables, never changes a value). Checked on v2.4.2366: no credentials 401, the pair 200. docs/extensions.md "A password on the engine" says how an existing install turns it on; INSTALL.md and the in-app Unraid steps ask for the password (1 new string, translated in all eight languages); releasePipeline pins the defaults. - Desktop: the engine's basic-auth pair is made with each launch's Supervisor and held in memory only, handed to the engine (environment) and the bff (SUWAYOMI_*); secrets.json keeps the database password and drops the old pair. shell.supervisor proves a second launch gets a new pair, reintroduced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, a 429 waited out, a wait never an error The owner connected AniList and the backfill pushed fourteen series, met a 429, dropped the push and left "anilist 429" on Profile → Connections. AniList limits each address (90 a minute, 30 while degraded, as its X-RateLimit-Limit says), and every AniList request this server makes counts against that one number, while each caller paced itself alone: 2.4 s per user's push lane (two calls a push), 2.2 s between batch pages. - lib/anilistLimit.ts: every AniList GraphQL request goes through anilistFetch -- the tracker calls, the scores, art, Discover's lookups and trending, the reading directions, the related works and the missing details. It spaces requests 60 s / (limit - 2) apart once AniList has stated its limit, holds every caller on a 429 until Retry-After (else X-RateLimit-Reset, else a minute) and on a spent quota, then makes the request again. Each attempt's timeout starts with the attempt. A caller someone waits on (art behind an image, Connect, Test, the import, recommendations, a rail) is answered AniListBusy at once rather than held past 15 s; a push or a batch waits up to ten minutes and five retries. The push lanes keep their order with no extra gap for AniList. - A 429 that outlasts the retries is a pace, not an error: last_error 'rate_limited' (and the old "anilist 429" rows), served as slowedDown with no lastError, said on Connections as "Syncing slowly: AniList asks us to wait" in the help's own colour. The next push that lands clears it, as before; needsReconnect never reads it. - lib/trackerPace.ts holds that one reading, so Health's Tracker sync card (v0.72.0) does not list a member whose tracker only asked us to wait. - anilistQuota.int (virtual clock, a scripted AniList stating 30 a minute): a 40-series backfill through the route stays at 30 or under in any minute and pushes every series; a 429 is waited out for its Retry-After and the same push lands with nothing written; an endless 429 reads slowedDown, stays off Health's Tracker sync card and clears; a person is told "busy" at once. Each reintroduced. trackerVerdicts and trackerRecs start each case with a fresh quota. - 1 new string, translated in all eight languages. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he app does elsewhere, and four fixes in three more languages
- Arabic: the source path reads right to left (◂), "accounts limited below 18" names the age limit the way the rest of
the app does (حدّ عمرها), and "At most {limit} sources" no longer uses the 11-99 number form for a limit of 200.
- Russian: an age rating is set (задаётся), not scored, and the limit is a возрастное ограничение, as elsewhere.
- Japanese: the sources a series follows are フォロー中, as everywhere else in the app.
- Chinese: the details result line counts 部作品 like the lines beside it.
- Portuguese (Brazil): "nos pede para esperar", in the register the rest of the file uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…gine passwords @Squeaks72 is credited for #257, #245 and #256. The upgrade note says what changes for sources that were ticked as adult under the 18+ filter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A series with no description, genres or author can have them filled in, a whole source can be rated Adult only, AniList sync waits when AniList asks instead of giving up, and a new Unraid extension engine asks for a password. #257, #245 and #256 are @Squeaks72's, rebuilt on the app's own parts and credited as co-author.
Missing details (#257, #245)
details, with counters, a Tasks line andREPAIR_DETAILS_MAX(15).series_auto_details, below the scan and never intoseries_overrides. Every read is override > scan > filled in (autoDetailsSql.ts), the 18+ filter included, and genres cleared on purpose ({}) stay cleared.Media(id_in:)request, read through readCapped. No Kitsu or MangaUpdates calls.blockedNow), each lookup on the source's own budget, text through cleanDescription and cleanGenres. A series with no chapters gets a cover. A miss waits 30 days; following a source by hand asks at once.Adult only (#256)
PUT /api/admin/sources/:id/age-rating(18ornull), on the source's sheet as Automatic | Adult only. It is stored in the existing adult-sources list, which becomes a permission: an account limited below 18 is refused the source everywhere an extension-flagged one is, by id too (latest, popular, detail, add, preview, each tested and reintroduced). No Mixed.One AniList quota
lib/anilistLimit.ts: every AniList GraphQL request (trackers, scores, art, Discover, reading directions, related works, details) shares one per-server limiter, spaced by AniList's liveX-RateLimit-Limitand holding onRetry-After,X-RateLimit-Resetor a spent quota. A push waits and sends the same push again; a person or an image is told AniList is busy at once.Engine sign-in
Not in this release: #245's Kitsu and MangaUpdates lookups, and #256's Mixed.
Checks (local, before pushing)
🤖 Generated with Claude Code