feat: Automatically tag Audiobookshelf items with req:<username> per requester - #232
feat: Automatically tag Audiobookshelf items with req:<username> per requester#232NichCodes wants to merge 1 commit into
Conversation
…ster Optionally writes a req:<sanitized_username> tag onto each ABS item when a completed download is matched to a request, so admins can scope per-user library access by tag. Tagging happens at match time (both the full scan and the recently-added check), tags are merged (never overwritten), and toggling the setting on backfills already-available requests via a one-time job. Usernames that sanitize to nothing are skipped rather than collapsing onto a shared bare req: tag. ABS-only; Plex backend is out of scope. Closes kikootwo#229
0267017 to
8b03dbf
Compare
|
This is similar to the first script in my PR #96 (comment) Although this one is better IMO. Only thing I'd want to "adjust" is make it able to apply this tag even if Plex is the backend. I'm still using Plex as backend JUST for user management, but actual organization/consumption of audiobooks all via ABS. |
|
I've never used ABS with Plex, so I decided not to touch it just in case I broke something I couldn't test properly. I could try to implement it, but I'd need someone else who does use it with Plex to test it out before merging. |
|
I'd be more than willing to do testing of this. I THINK it would have little to no impact, but understand wanting to test it of course! Currently I have RMAB configured to Auto-Tag audiofiles with Metadata; coerse file format for plex compatability and auto-merge chapters to M4B. As I mentioned I never actually consume the audiobooks via plex only ABS. The only real issue I can think of is when I trigger ABS to match the book and get the metadata for itself it's going to over-write any tags pushed from RMAB (at least I think it will). And I'm not totally sure how to best handle that. I think I'd need RMAB to handle the metadata 100% (which with my existing settings is almost does). Someday I'll likely "upgrade" to use ABS as my backend so I get all the correct feature set. I'm just sticking with Plex for the "easy" user management that provides. |
|
I'll wait until @kikootwo reviews the standing PRs before I take a stab at it. I'll tag you in the draft to test it once it's ready to test. |
Tag Audiobookshelf items with
req:<username>per requesterCloses #229
Summary
Adds an optional Audiobookshelf-only feature that writes a
req:<sanitized_username>tag onto each ABS library item when RMAB matches a completed download to a request. Because every request method (Web UI, API, and eventually Discord) produces aRequestwith an associated user, tagging happens at match time so all methods are covered by one path. ABS supports per-user library filtering by tag, so admins can scope what each user sees by theirreq:<username>tag.The end result is that RMAB will allow Audiobookshelf admins to easily give each user a private library by simply allowing them to see only the requests tagged with their own username (or any number of others).
How it works
audiobookshelf.tag_requester(default off) — new checkbox in Settings → Library → Audiobookshelf.req:+ username lowercased, trimmed, spaces→_, characters outside[a-z0-9_-]stripped (John Smith→req:john_smith). Usernames that sanitize to nothing (all-symbol or non-Latin) are skipped rather than collapsed onto a shared barereq:tag.media.tags, union with the new tag (dedupe),PATCH /items/:id/mediaback — so manual tags (e.g.nsfw) and other requesters' tags are preserved. Writes are skipped when nothing changes.scan-plex.processor.ts(full scan) andplex-recently-added.processor.ts(scheduled recently-added check) — a request matched by either is excluded from the other, so both must tag.backfill_requester_tagsjob that tags already-available audiobook requests.Changes
src/lib/services/audiobookshelf/api.ts—PATCHmethod,formatRequesterTag()(returns''for unusable usernames),addABSItemTags()(merge + drops empty tags).src/lib/processors/scan-plex.processor.ts,src/lib/processors/plex-recently-added.processor.ts— tag at match time, skipping empty tags.src/lib/processors/backfill-requester-tags.processor.ts— one-time backfill (new).src/lib/services/job-queue.service.ts—backfill_requester_tagsjob type, enqueue method, processor registration.src/app/api/admin/settings/route.ts(GET expose) +src/app/api/admin/settings/audiobookshelf/route.ts(save key + false→true backfill trigger).src/app/admin/settings/lib/types.ts+.../LibraryTab/AudiobookshelfSection.tsx—tagRequestersetting + checkbox.documentation/features/requester-tags.md(new),settings-pages.md,TABLEOFCONTENTS.md.Scope / non-goals
/deleteremoves the whole ABS item.availablerequests are excluded from the match loops, so no repeat API calls outside the one-time backfill.Testing
formatRequesterTagincl. empty-sanitize cases, merge / skip-no-op / empty-tag / error), match-time tagging on both the scan and recently-added paths, the backfill processor (query filter + tag/skip counts), and the false→true backfill enqueue.dockerfile.unifiedbuilds clean; fullnpm run testgreen except for pre-existing unrelated frontend page-test failures (tracked/fixed onfeature/discord-request-tags).req:<username>while preserving existing genre tags.