Skip to content

Bug Backlog#436

Open
therobbiedavis wants to merge 22 commits intocanaryfrom
bugfix/misc-issues
Open

Bug Backlog#436
therobbiedavis wants to merge 22 commits intocanaryfrom
bugfix/misc-issues

Conversation

@therobbiedavis
Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis commented Mar 26, 2026

This PR aims to close some of the longer standing bugs and/or feature requests such as PUID/PGID support for example. See the full changes below:

Added

Fixed

  • Fixed ASIN searches in the Add New view returning zero results by restoring missing metadata fields needed for language-filtered results. (Closes unable to search for ASIN #434)
  • Fixed search failures for titles and authors containing diacritics or special characters by retrying with normalized text and using diacritic-insensitive matching. (Closes Add characters from other countries alphabets when matching audiobooks #430)
  • Fixed Audible catalog search returning irrelevant trending or popular results by correcting request parameters and headers.
  • Fixed series-only advanced search failures by improving ASIN resolution, result mapping, language filtering, fallback behavior, and empty-result handling.
  • Fixed NZBGet XML-RPC authentication by switching to an explicit Basic Auth header instead of embedded URL credentials.
  • Fixed manual import so hardlink/copy mode now correctly hardlinks primary and companion files when possible.
  • Fixed Library Import mode selection so non-move settings no longer incorrectly fall back to move.
  • Fixed MAM torrents stalling in qBittorrent due to missing tracker URLs by preserving auth cookies, injecting trackers, and repairing announce-list parsing. (Closes Tracker URL missing from torrent when added to qBittorrent (MAM) #429)
  • Fixed MAM indexer saves so redaction no longer wipes the stored MAM ID or breaks frontend JSON handling.
  • Fixed phantom duplicate-download blocking by ignoring stale completed records from disabled or removed clients and returning 409 Conflict when a download is skipped.
  • Fixed SABnzbd completed download actions so Remove and Remove and Delete now use the correct nzo_id instead of Listenarr’s internal GUID, allowing history cleanup and source-directory removal to work properly. (Closes [Bug] Remove and Delete Completed Download Action not Working as Expected in Sabnzbd #300)

Backend: Inject IFileMover into ManualImportController and use it to perform hardlink operations for "hardlink/copy" input mode (with fallback to copy for companion files). Update ManualImportRequest comment to include the new mode and adjust tests to provide a mock IFileMover.

Frontend: Add responsive CSS for top navigation and refine mobile behaviors across AddNewView and App (pagination controls, results scrolling, layout/spacing, and button sizing). Update AddNewView to conditionally render title results controls via hasTitleResultControls and improve client-side pagination layout.

Other: Default library import inputMode logic simplified to choose 'move' for Move or unset, otherwise 'hardlink/copy'. Tests updated to account for the new dependency.
Add a Changelog maintenance section to .github/CLAUDE.md with guidance on when and how to update CHANGELOG.md (unpublished vs published branches, entry format, and rules for entries). Also update CHANGELOG.md with a new 0.2.62 release containing two fixes: preserve hardlink behavior in ManualImportController by injecting IFileMover and adding the missing hardlink branch in ImportFileAsync/ImportCompanionFilesAsync; and correct Library Import view mapping so non-Move settings map to "hardlink/copy" (falling back to plain copy when hardlinking is not possible).
CallXmlRpcAsync now builds the /xmlrpc URI and sends an HttpRequestMessage with an explicit Authorization header (via BuildAuthHeader) instead of embedding credentials in the URL. This prevents HttpClient from silently stripping userinfo and ensures Basic auth is sent. The old BuildBaseUrl helper was removed. CHANGELOG updated and package versions bumped to 0.2.60 for root and frontend.
Multiple fixes to address MyAnonamouse (MAM) torrent failures, indexer redaction issues, and duplicate-download blocking.

Key changes:
- DownloadController: return 409 Conflict when a duplicate active download blocks creation.
- DownloadService: duplicate detection now excludes Completed and only considers enabled download clients; added authenticated retry logic for MAM torrent fetches (disable auto-redirect and reapply cookies) and safer handling/logging of response content and filenames.
- QbittorrentAdapter: improved post-add detection of the torrent hash (non-blocking loop), and fallback to inject tracker URLs via the addTrackers API using announce URLs extracted from the torrent file.
- ApiResponseRedactor: switch to per-field JSON redaction for AdditionalSettings and add MergeAdditionalSettings to preserve real secrets when incoming payloads contain "REDACTED" placeholders; helper to redact sensitive keys preserved structure.
- MyAnonamouseHelper: fixed bencode parsing/stream consumption bugs to avoid desynchronization when extracting announce URLs.
- Tests: updated expectation to normalize stored path using Path.GetFullPath (platform-dependent).
- CHANGELOG updated to document the fixes (MAM tracker URL, lost MAM ID, phantom duplicate check).

These changes resolve stalled MAM downloads (missing trackers / dropped auth), prevent accidental erasure of sensitive indexer fields on save, and stop invisible stale client records from permanently blocking re-downloads.
Add a set of new languages and ISO/alias mappings to the frontend language options and normalization logic (Arabic, Chinese, Czech, Danish, Dutch, Finnish, Greek, Hindi, Japanese, Korean, Norwegian, Portuguese, Spanish, Swedish, Turkish). Update normalizePreferredSearchLanguage/normalizeSearchResultLanguage behavior and unit tests to cover the new aliases and fallbacks (e.g. region codes like `br` -> portuguese, `jp` -> japanese), and add tests for unsupported values. Also update CHANGELOG to document the expanded language filter support and MAM parser recognition.
Adds Hebrew to the frontend language options and normalizations, and extends the MyAnonamouse provider with many additional ISO 639 mappings. Implements diacritic-insensitive search and matching: introduces RemoveDiacritics and HasDiacritics, retries Audible queries with diacritics stripped when needed, and switches title/author/series comparisons to CultureInfo.CompareInfo with IgnoreNonSpace to avoid filtering accented metadata. Fixes Advanced Search when only a series name is provided by using the series as a TITLE token. Adds unit tests for RemoveDiacritics and updates the changelog.
Fix series-only/series-by-name advanced searches and make Audible series results consistent with unified search paths. Changes include: resolve series ASINs by casting to SeriesLookupItem and preferring region-matching entries (with first-item fallback); guard against passing raw series names as ASINs; fetch books by series ASIN and map AudibleSearchResult items to the same Audible-shaped output via a new MapAudibleSearchResultToOutputAsync converter; apply post-fetch language filtering while treating null/empty language as acceptable; change direct product search to use "keywords" param; add diagnostic logging around series lookups and fetches; keep unfiltered results as a fallback when series metadata is missing; and remove an exposed metadataSource field from the metadata mapper. Tests updated to the new SeriesLookupItem shape and to cover region fallback, null-language preservation, series-only flows, and series filtering behavior. Also update CHANGELOG entry to reflect the broader set of fixes and behaviors.
Introduce docker-entrypoint.sh to handle PUID/PGID/UMASK, chown the config dir and drop privileges via gosu. Install gosu in both Docker runtime files, ensure /app/config/database exists, copy and chmod the entrypoint, and replace direct dotnet ENTRYPOINTs with the script. Update docker-compose to expose PUID/PGID/UMASK environment variables (remove hardcoded user) so the container can run with custom UID/GID and correct permissions.
Add login and image publishing to atcr.io across canary, nightly, and release workflows: add docker/login-action for ATCR, expose ATCR_IMAGE outputs, and include ATCR image tags when pushing. Also replace the generic DISCORD_DOCKER_UPDATE_URL webhook secret with LISTENARR_DISCORD_WEBHOOK_URL for Discord notifications. Updated files: .github/workflows/canary.yml, nightly.yml, release.yml.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d63fc7462b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Frontend: extend Audible metadata mapping to include language, subtitle, description and lengthMinutes (plus alternate-cased keys) and map them into search results so ASIN lookups no longer get dropped by language/metadata filters. Backend: prefer TorrentHash, then ClientDownloadId when resolving client-side IDs for post-download removal; add SABnzbd handling to use ClientDownloadId (nzo_id) for removal requests. Changelog: document ASIN and SABnzbd fixes. Also remove unused config/appsettings/appsettings.json.
Multiple small fixes across the project:

- docker-entrypoint.sh: default PGID to PUID when not set and skip groupmod/addgroup when PGID is 0 (root) to avoid unnecessary/root group changes in root containers.
- ApiResponseRedactor.cs: replace manual property loop with LINQ Any for a concise quick-scan, and broaden the sensitive-key check from exact "mam_id" to contains "mam" for more robust matching.
- AudibleService.cs: remove unused totalRawProducts local variable.
- DownloadService.cs: ensure HttpRequestMessage is disposed by using 'using var' for retry requests to prevent resource leaks.
Fetch completed items from SABnzbd history and append them to the active queue results so completed downloads can be discovered for import/removal. Adds a history API request (mode=history), parses history slots into QueueItem entries (nzo_id, name, category, bytes, completed timestamp), maps statuses, filters by configured category, translates remote paths via the path mapping service, and updates logging. Non-fatal parsing/fetch errors are caught and logged at debug level.
Introduce a normalized QueueSnapshot model and helpers (normalizeQueueSnapshot, createEmptyQueueSnapshot) and add QueueSnapshot/QueueClientStatus types. Update api.getQueue and SignalR handling to accept/emit a normalized snapshot (handles old array payloads too). Rework downloads store to track queue-only IDs and reconcile DB downloads with incoming queue snapshots to avoid stale duplicates/removals. Revamp ActivityView: search/filter input, grid layout, snapshot health banner, virtual scroll tuning, status label mapping, and prefer queue snapshot entries over external DB downloads when IDs conflict. Add unit tests for downloads store reconciliation and ActivityView snapshot behaviours.
Add AudiobookId propagation from DB to API and frontend queue items, enabling linked titles in the Activity and Wanted views (router links, resolved via library store) and small UI tweaks (grid height, link styles). Backend model and repo updates: Download and QueueTrackedDownload now include AudiobookId and EfDownloadRepository maps it. DownloadQueueService/DownloadService now carry AudiobookId into queue items and avoid rewriting tracker hosts; announce URLs are logged for diagnostics. Torrent/tracker handling improved: MyAnonamouseHelper gains a skip-scanner and only captures/uses real tracker announce URLs (skips url-list/web-seeds and limits regex fallback), QbittorrentAdapter filters to tracker announces before injecting, and mam_id appending is skipped for non-tracker URLs to avoid corrupting web-seeds.
Use download-client reported source file lists to reliably scope automatic imports and directory batch processing. Adds a SourceFiles property to tracked downloads and populates/translates it in qBittorrent and Transmission adapters (including path mapping and per-file translation). Completed-download processing and the background move/copy job now filter directory imports to only the files reported by the client, avoid finalizing multiple times, and select a primary imported path preferring audio files. Non-audio files are refused by ImportService and skipped by AudioFileService; MetadataRescanService removes non-audio AudiobookFile entries. FileUtils gains helpers for identifying companion files and common companion stem keys. Also propagate Language metadata from search results and DB lookups, and include language in queue enrichment. Tests added/updated to cover adapters, audio-file checks, completed-download behaviors, and directory move/copy finalization.
Add .tmp and obj2 patterns to DefaultItemExcludes (Directory.Build.props and Listenarr.Domain.csproj) to prevent temporary/extra folders from being treated as project items. In Listenarr.Domain.csproj disable automatic compile item inclusion (EnableDefaultCompileItems=false) and explicitly include Models/**/*.cs so only intended source files are compiled.
Add structured-field normalization for advanced searches and improve Audible title search behavior. Implements NormalizeStructuredAdvancedField in SearchController to strip AUTHOR:/TITLE:/ISBN:/ASIN: prefixes (returning null for empty stripped values) and applies it to advanced search requests. Update AudibleService.SearchByTitleAsync to trim input, return an empty response for blank titles, prefer a keyword/catalog search first then fall back to a title-field search if no results, and log the retry; also reuse SearchByTitleAsync from SearchByTitleAndAuthor when author is blank. Add unit tests covering the Audible title search flow and advanced search normalization.
Capture _hubContext.Clients.All into a local clientProxy and use it for SendAsync/SendCoreAsync in DownloadService and SignalRHubBroadcaster to simplify null checks and ensure consistent calls. Update tests: replace Path.Combine with Path.Join for temp file paths; make cleanup catch blocks explicit (catch Exception) with best-effort comments; use tolerant floating-point assertions (Math.Abs) for metrics verifications; and supply a real HttpClient instance when mocking AudibleService. Small robustness and compatibility improvements across services and tests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant