mirror of
https://github.com/Radarr/Radarr
synced 2026-01-25 17:01:42 +01:00
* bump to 6.1.0 * chore: updated build images * New: add TTL setting for pushover notifications (cherry picked from commit 317cdf15582746bd4e713d6b99e17a21dcb8abeb) * Chore: Remove Readarr donation logo * Skip proxy tests on MacOsX * Fix: (#11303) collection API error when using `Movie CollectionThe` (#11304) Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com> * feat: initial project branding and setup * chore: move project config to development folder * feat(ci): add GitHub Actions and Docker configuration * docs: update documentation for rebrand * chore: update Windows and macOS distribution branding * feat(privacy): remove telemetry, analytics, fingerprinting * docs: add privacy section and document cleanup candidates * docs: simplify privacy section * feat: rebrand to Logarr with teal theme * refactor(ui): update page titles and manifest for rebrand * fix(security): patch SQL injection, path traversal, command injection * docs: update CHANGELOG with security fixes and branding * fix: resolve build issues for local development * chore: update GitHub username to cheir-mneme * refactor: rename project from Logarr to Aletheia * fix(ci): add disk space cleanup for Docker multi-arch builds * refactor: remove empty housekeeping classes and commented properties * docs: update PR template for Aletheia workflow * fix(build): use pipe delimiter in sed for branch names with slashes * fix(security): address pre-release security blockers - Reject unknown sender types in certificate validation - Disable auto-redirect in SkyHookProxy to prevent HTTPS downgrade - Use proper JSON serialization in InitializeJsonController - Add whitelist validation for Type.GetType in converters * docs: update community standards with conventional commits and Aletheia branding * docs: link README to CONTRIBUTING.md * chore: add pre-commit hooks and CI coverage reporting - Add pre-commit hook for JS/TS and CSS lint checks - Add setup script to install hooks - Add coverage reporting to CI workflow - Add coverage threshold warning (60%) - Update CONTRIBUTING.md with hooks setup instructions * feat(download): add automatic archive extraction (Unpackerr absorption) - Add SharpCompress for RAR/7z support - Extend ArchiveService with RAR, 7z extraction via SharpCompress - Add DownloadExtractionService for orchestrating extraction - Add config: AutoExtractArchives (default: false) - Add config: DeleteArchiveAfterExtraction (default: true) - Integrate extraction into CompletedDownloadService Note: UI settings page not yet implemented - backend foundation only. * fix(style): use explicit HashSet type for StyleCop SA1000 * fix(style): use explicit HashSet type for StyleCop SA1000 * fix(ci): copy test DLLs to expected location for test.sh * fix(style): use explicit JsonSerializerOptions type * fix(style): remove unused using, use AsSpan over Substring * chore(deps): bump js-yaml in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the / directory: [js-yaml](https://github.com/nodeca/js-yaml). Updates `js-yaml` from 4.1.0 to 4.1.1 - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1) --- updated-dependencies: - dependency-name: js-yaml dependency-version: 4.1.1 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> * feat(indexer): add multi-media type foundation Add MediaType enum and indexer support for books/audiobooks: - MediaType enum (Movie, TV, Music, Book, Audiobook, Podcast, Comic) - NewznabStandardCategory constants for all media types - Database migration 243 for SupportedMediaTypes column - Updated IndexerDefinition, IIndexer, IndexerBase - Updated README with current project status * feat(indexer): add book/audiobook search criteria Add search criteria classes and update request generators: - BookSearchCriteria (Author, Title, ISBN, Publisher, Year) - AudiobookSearchCriteria (Author, Title, Narrator, ASIN, ISBN) - Updated IIndexerRequestGenerator interface - Implemented book/audiobook search in NewznabRequestGenerator - Added stub implementations to all other request generators * Add SonarCloud analysis workflow This workflow triggers a SonarCloud analysis of the code and populates GitHub Code Scanning alerts with vulnerabilities found. * fix: disable SA1200 StyleCop rule to match stylecop.json config * Add GitHub Super Linter workflow This workflow runs multiple linters on code changes in the 'develop' branch for both pushes and pull requests. * Add Trivy vulnerability scanning workflow * ci: fix workflow configs and add dependabot - SonarCloud: add proper projectKey and organization - Trivy: fix image reference, add schedule comment - Super Linter: upgrade to v6, configure linter selection - Add Dependabot for NuGet, npm, Docker, GitHub Actions * fix(ci): correct Dockerfile path and skip SonarCloud when token missing * fix(ci): use filesystem scan instead of image scan for Trivy * fix(ci): use exclusion-only config for super-linter * fix(ci): disable checkov and github_actions linters in super-linter * ci(deps): bump actions/checkout from 4 to 6 Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * ci(deps): bump actions/cache from 4 to 5 Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/cache dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * ci(deps): bump codecov/codecov-action from 4 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v4...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * ci(deps): bump dessant/label-actions from 3 to 5 Bumps [dessant/label-actions](https://github.com/dessant/label-actions) from 3 to 5. - [Release notes](https://github.com/dessant/label-actions/releases) - [Changelog](https://github.com/dessant/label-actions/blob/main/CHANGELOG.md) - [Commits](https://github.com/dessant/label-actions/compare/v3...v5) --- updated-dependencies: - dependency-name: dessant/label-actions dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * Bump the nuget group with 1 update Bumps System.Private.Uri from 4.3.0 to 4.3.2 --- updated-dependencies: - dependency-name: System.Private.Uri dependency-version: 4.3.2 dependency-type: direct:production dependency-group: nuget - dependency-name: System.Private.Uri dependency-version: 4.3.2 dependency-type: direct:production dependency-group: nuget ... Signed-off-by: dependabot[bot] <support@github.com> * docs: update CLA to reference Aletheia * ci: remove super-linter workflow Linting covered by existing tools: - C#: StyleCop during build - GitHub Actions: CodeQL - Frontend: eslint in package.json * feat(indexer): add MyAnonamouse indexer for books and audiobooks * feat(indexer): enable book and audiobook support in Newznab/Torznab * feat(ui): add media type badge to poster view * fix: address code review findings - Fix Torznab default definition protocol (Usenet -> Torrent) - Add try-catch around JSON deserialization in MAM parser - Add logging for author info parse failures - Add null check for JSON response * fix: add timeout to regex for DoS prevention * fix: mark React component props as Readonly Bulk update to make all component props immutable at the type level. This prevents accidental prop mutation and improves type safety. Resolves ~50 SonarCloud code smells. * refactor: replace ApplicationException with domain-specific exceptions Create custom exception classes: - InvalidDatabaseSchemaException for migration errors - ServiceInstallationException for service install failures - DataRetrievalException for repository query mismatches - InvalidRequestException for HTTP request validation - InvalidHeaderException for HTTP header validation Resolves SonarCloud S3988 (ApplicationException usage). * refactor(ui): extract PosterDateRow to reduce MovieIndexPoster complexity Extract repetitive date display logic into PosterDateRow component. Reduces cognitive complexity from 30 to ~20 by consolidating 4 similar conditional blocks into reusable component calls. * refactor: reduce MyAnonamouseParser cognitive complexity Extract helper methods for author parsing, title flags, and freeleech detection to simplify the main ParseResponse loop. Addresses #30 * refactor: reduce LanguageParser cognitive complexity Replace 40+ individual if statements with dictionary-based lookup. Extract helper methods for keyword, case-sensitive regex, and case-insensitive regex language detection. Original method reduced from ~400 lines to ~17 lines while preserving all behavior. * refactor: make methods static where instance data not used (S2325) ~243 methods converted to static where they don't access instance data. Fixed call sites that needed to use type name instead of instance. * refactor: seal non-derived private classes (S3260) 63 private nested classes marked as sealed since they have no derived classes. * perf: use char overloads for StartsWith/EndsWith (S6610) Use single character overloads instead of single-character string overloads for better performance. * refactor: use Number.parseInt/parseFloat/isNaN (S7773) Use Number static methods instead of global functions for better clarity and consistency. * Update README for clarity and typo corrections Corrected typos and improved clarity in the README. * refactor: remove redundant boolean literals (S1125) Replace == false with negation operator, remove == true comparisons * ci: remove sonarcloud workflow (conflicts with automatic analysis) * docs: add comprehensive technical debt tracking * docs: remove tech debt tracking from repo (moved to wrapper) * fix(security): sanitize user-controlled strings in log statements Add SanitizeForLog() extension method to prevent log forging attacks by replacing control characters (newlines, etc.) with spaces. Applied across 30 files that log user-controlled data like paths, titles, URLs, and usernames. Fixes CodeQL log-forging alerts. * fix: resolve technical debt and npm vulnerabilities NPM Security (0 vulnerabilities remaining): - Add yarn resolutions for cross-spawn, brace-expansion, color-string, glob, postcss Bug fixes: - Bug-002: Use FirstOrDefault with null check (DownloadStationTaskProxyV2) - Bug-007: Fix inverted exception logic for magnet fallback (TorrentClientBase) - Bug-008: Fix stale closure using ref (MovieSearchInput) - Bug-009: Fix Number.Number.parseInt typos across 50+ files - Bug-010: Add regex timeout and Compiled flag (RegexReplace) - Bug-011: Add null checks for XML queries (ConfigFileProvider) - Bug-012: Remove empty touch handler (MovieDetails) - Bug-013: Use Path.GetFileName for safer check (InstallUpdateService) - Bug-014: Return Ok instead of Accepted for sync PUT (MovieController) - Bug-016: Fix double bracket typo in log message (InstallUpdateService) - Bug-017: Add console.warn to catch block (MovieTagInput) - Bug-018: Remove stray debug console.log (SignalRConnector) - Bug-019: Document disabled regex with ReDoS justification (Parser) * Fix deadlock risk in ReleasePushController with async SemaphoreSlim * Add log sanitization for CodeQL log forging alerts * Add custom CodeQL config to exclude log-forging false positives * Fix CodeQL qlpack.yml - add library: true * Trigger CI after disabling default CodeQL * Update CodeQL config to exclude path-injection and use security-extended * Exclude additional CodeQL false positives for single-user app * Exclude SonarCloud S5145 false positive log injection warnings * Suppress S5145 log injection false positive in editorconfig * Add CI-based SonarCloud workflow with rule exclusions * Remove sonar-project.properties - not supported by SonarScanner for .NET * Remove SonarCloud CI workflow - conflicts with automatic analysis * Fix CodeQL rule ID for insecure-direct-object-reference * Fix remaining technical debt bugs - Bug-001: Add null check for SingleOrDefault() in TorrentRssParser - Bug-006: Replace generic Exception with PathCombinationException in OsPath - Bug-006: Replace generic Exception with NotSupportedException in IMDbListRequestGenerator * Fix blocking semaphore in MediaCoverService Convert _semaphore.Wait() to async pattern with WaitAsync() to prevent thread blocking during image resizing operations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Fix CancellationTokenSource resource leaks (BLOCKER severity) - ManagedHttpDispatcher: Dispose quickFailCts and linkedTokenSource in finally block - CommandExecutor: Dispose _cancellationTokenSource on shutdown - Scheduler: Dispose _cancellationTokenSource on shutdown - IntegrationTestBase: Store CTS as field and dispose in TearDown 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: add IMDb list error message verification tests * fix: thread-safe SHA1 hashing in HashConverter * fix(ci): pin Trivy action and update branding * fix(ci): add CODEOWNERS, enable test blocking, add pre-commit hooks * chore: update yarn.lock with husky and lint-staged * fix(ci): P2 improvements - editorconfig, integration tests, Prettier 3 - Remove duplicate dotnet_style_qualification rules in .editorconfig - Update Radarr branding to Aletheia in .editorconfig - Add integration tests step to build.yml (with continue-on-error) - Upgrade Prettier to 3.7.4, eslint-plugin-prettier to 5.5.4 - Upgrade eslint-config-prettier to 10.1.8 - Fix pre-existing lint errors (unused vars, radix parameter) - Reformat frontend code with Prettier 3 formatting changes Closes #57 (SonarCloud deferred - needs org setup) Closes #58, #62 (partial - ESLint 9 deferred), #63 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(security): address P3 vulnerabilities and add mitigations Security fixes: - XXE prevention: disable XmlResolver in UTorrentProxy.cs (#42) - Path traversal: validate paths in LogFileController.cs (#44) - Path traversal: validate paths in MediaCoverController.cs (#44) - ReDoS mitigation: add 5s timeout to user regex patterns Documentation: - CORS: document security rationale in Startup.cs (#43) Closes #42, #43, #44 Related: #59, #60, #61 (SonarCloud triage - GitHub alerts now at 0 open) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Cache regex instances as static compiled fields - SkyHookProxy: Cache IMDB/TMDB URL regexes - PushsaferSettings: Cache hex color validation regex - Parser: Cache IMDB ID validation regex * Optimize O(n*m) Contains patterns with HashSet - MovieService.FindByTitle: Convert title lists to HashSets - MoviesSearchService: Convert queue IDs to HashSet * fix(security): add path validation to OpenWriteStream and regex timeouts - DiskProviderBase: Add Ensure.That path validation to OpenWriteStream - CleanseLogMessage: Add 5-second timeout to all 22 regex patterns to prevent ReDoS * fix(frontend): address React and TypeScript quality issues - Replace index-as-key antipattern with stable keys (#34) - Remove TypeScript any types in favor of proper types (#37) - Memoize inline style objects to prevent unnecessary re-renders (#41) Files: 17 frontend components updated * Migrate to ESLint 9 flat config - Create eslint.config.mjs with ESM flat config format - Remove legacy .eslintrc.js and .eslintignore - Remove eslint-plugin-filenames (not ESLint 9 compatible) - Update lint-staged to use new config - Clean up unused eslint-disable directives * Fix SonarCloud issues and add suppression config Backend: - Add regex timeout to prevent ReDoS (S6444): - SkyHookProxy.cs: ImdbUrlRegex, TmdbUrlRegex - PushsaferSettings.cs: HexColorRegex - Parser.cs: ImdbIdRegex Frontend: - Fix sorting without localeCompare (S2871): - MovieIndex.tsx, Collection.js, DiscoverMovie.js Config: - Add sonar-project.properties with documented false positive suppressions: - S8135: TMDB public API token (not a secret) - S6680: Directory depth iteration (naturally bounded) - S6674: NLog structured logging placeholder syntax - S4662: PostCSS mixin directives - S5145: Sanitized log data * Fix SonarCloud bugs: threading, React state, sorting Backend: - S2445: Make _connections readonly in MessageHub.cs to fix locking issue Frontend: - S6756: Use callback form of setState when referencing previous state - Collection.js, DiscoverMovie.js, ImportMovie.js - ImportMovieSelectMovie.js, EditQualityProfileModalContentConnector.js - S2871: Add localeCompare for proper alphabetical sorting - Collection.js, DiscoverMovie.js, MovieIndex.tsx - S1764: Remove duplicate condition in QualityProfileSelectInput.tsx * fix: SonarCloud bugs batch 2 - S2445: Make _connections readonly for thread-safe locking (MessageHub.cs) - S6756: Use setState callbacks for 5 React components - S1764: Remove duplicate expression in QualityProfileSelectInput.tsx - S2583: Remove unreachable conditions in NotificationDefinition.cs - S2259: Fix null reference in Pushcut.cs * fix: SonarCloud null safety and struct comparison issues - OsPath.cs: Remove ReferenceEquals checks on struct (always false) - SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew * fix: remaining React index-as-key issues + backend null safety (#78) * fix: SonarCloud null safety and struct comparison issues - OsPath.cs: Remove ReferenceEquals checks on struct (always false) - SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew * fix: remaining React index-as-key issues and backend null safety Frontend: - Fix 8 remaining index-as-key violations using content-based keys - ImportMovieSelectFolder.js: use errorMessage as key - ImportMovieFooter.js: use errorMessage as key - CustomFormat.js: use item.name as key - AddSpecificationItem.js: use preset.name as key - QualityProfileItems.js: use message as key - QualityProfileFormatItems.js: use message as key Backend (cherry-picked from batch-3): - OsPath.cs: Remove ReferenceEquals on struct - SkyHookProxy.cs: Add null-conditional for Credits --------- Co-authored-by: admin <admin@ardentleatherworks.com> * refactor: notification provider deduplication + docs (#81) * fix: SonarCloud null safety and struct comparison issues - OsPath.cs: Remove ReferenceEquals checks on struct (always false) - SkyHookProxy.cs: Add null-conditional operators for Credits.Cast/Crew * fix: remaining React index-as-key issues and backend null safety Frontend: - Fix 8 remaining index-as-key violations using content-based keys - ImportMovieSelectFolder.js: use errorMessage as key - ImportMovieFooter.js: use errorMessage as key - CustomFormat.js: use item.name as key - AddSpecificationItem.js: use preset.name as key - QualityProfileItems.js: use message as key - QualityProfileFormatItems.js: use message as key Backend (cherry-picked from batch-3): - OsPath.cs: Remove ReferenceEquals on struct - SkyHookProxy.cs: Add null-conditional for Credits * refactor(notifications): consolidate GetPosterUrl to base class * docs: add architectural decisions log * fix(sonar): enable path traversal suppressions for media management app --------- Co-authored-by: admin <admin@ardentleatherworks.com> * perf: cache regex patterns in Parser.ToUrlSlug and FileNameBuilder.GetEditionToken (#82) Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add null safety to LINQ First/Single calls (#83) Co-authored-by: admin <admin@ardentleatherworks.com> * fix(frontend): remove index from React keys in dynamic lists (#84) Co-authored-by: admin <admin@ardentleatherworks.com> * chore: update GitHub Actions and consolidate .editorconfig rules (#85) Co-authored-by: admin <admin@ardentleatherworks.com> * fix(ui): update user-facing links to Aletheia resources (#86) - MoreInfo: point to Aletheia GitHub instead of Radarr resources - UpdateChanges: link issue numbers to Aletheia repo - Add "Upstream" translation key for Radarr reference link Closes #53 Co-authored-by: admin <admin@ardentleatherworks.com> * fix(frontend): memoize inline JSX objects for performance (#87) - MovieIndexTable: memoize itemData, move row flex styles to CSS - MovieIndexOverviews: memoize itemData, extract listStyle constant - MovieIndexOverview: memoize elementStyle and infoStyle - CircularProgressBar: memoize containerStyle and circleStyle Reduces unnecessary re-renders in virtualized lists and frequently rendered components. Closes #41 Co-authored-by: admin <admin@ardentleatherworks.com> * chore(ci): standardize branch naming to use main instead of master (#90) - Update workflow triggers to use main instead of master - Update CONTRIBUTING.md to reference main branch - Aligns with documentation in CLAUDE.md Closes #52 Note: Actual branch rename (master → main) must be done on GitHub. Co-authored-by: admin <admin@ardentleatherworks.com> * fix(frontend): replace any types with proper TypeScript types (#88) * fix(frontend): replace any types with proper TypeScript types - AutoSuggestInput: use Data type from popper.js for modifier callback - Tooltip: use Data type from popper.js for computeMaxSize callback - OverlayScroller: use ComponentPropsWithoutRef<'div'> for renderView - index.ts: use unknown[] instead of any[] for logError parameters Improves type safety and removes eslint-disable comments. Partially addresses #37 * fix(frontend): use ModifierFn type and string values for Popper styles - Use ModifierFn type from popper.js for modifier callbacks - Calculate bottom/right from offset properties (top+height, left+width) - Convert numeric style values to strings with 'px' suffix - Fix typo: 'botton' -> 'bottom' in AutoSuggestInput --------- Co-authored-by: admin <admin@ardentleatherworks.com> * perf(backend): cache additional regex patterns (#89) * perf(backend): cache regex patterns for better performance - TransmissionBase: add static VersionRegex, share with Transmission - SearchCriteriaBase: cache RepeatingPlusRegex - SearchMovieComparer: cache QueryYearRegex - XbmcMetadata: cache WatchedRegex Avoids regex compilation on each method call. Partially addresses #36 * fix(security): add regex timeout to prevent ReDoS vulnerabilities All cached regex patterns now include TimeSpan.FromSeconds(1) timeout to prevent potential denial of service from malicious input patterns. --------- Co-authored-by: admin <admin@ardentleatherworks.com> * chore(ci): standardize branch naming to use main instead of master (#91) - Update workflow triggers to use main instead of master - Update CONTRIBUTING.md to reference main branch - Aligns with documentation in CLAUDE.md Closes #52 Note: Actual branch rename (master → main) must be done on GitHub. Co-authored-by: admin <admin@ardentleatherworks.com> * perf: replace List.Contains() with HashSet for O(1) lookups (#92) - ReleaseSearchService: wrap wantedLanguages in HashSet<Language> - FileNameBuilder: convert splitFilter array to HashSet<string> - NewznabCategoryFieldOptionsConverter: use HashSet<int> for category filters Addresses Issue #35 Co-authored-by: admin <admin@ardentleatherworks.com> * perf: fix remaining regex caching and add timeouts (#93) - XbmcNfoDetector: convert instance regex to static readonly with timeout - Parser: add RegexOptions.Compiled and timeout to ReportMovieTitleFolderRegex Addresses Issue #36 Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add null/empty checks before First() in download clients (#94) - FileStationProxy: throw if no file info returned from API - NzbVortex: return outputPath if no files in response - RTorrent: use FirstOrDefault() for validation errors Prevents InvalidOperationException on empty collections Co-authored-by: admin <admin@ardentleatherworks.com> * fix: use SingleOrDefault() with null check in UserService (#95) Replace .Single() with .SingleOrDefault() when reading Config element from XML to prevent InvalidOperationException on malformed config files Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add empty checks before First() in MovieFileController (#96) Add guard clauses to prevent InvalidOperationException when movieFiles list is empty in bulk update/delete operations Co-authored-by: admin <admin@ardentleatherworks.com> * fix(security): add regex timeouts for ReDoS prevention (#97) Add TimeSpan.FromSeconds(1) timeout to remaining regex patterns: - FileNameBuilder.cs: EditionOrdinalRegex, EditionUppercaseRegex - Parser.cs: SlugSpaceRegex, SlugInvalidCharsRegex, SlugDuplicateDefaultRegex Clears final 5 SonarCloud security hotspots for 100% review coverage Co-authored-by: admin <admin@ardentleatherworks.com> * fix: resolve thread safety issues in ConfigService cache (#98) Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add empty catch comment and SingleOrDefault safety (#99) Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add null safety to QualityProfile First/Last methods (#100) Co-authored-by: admin <admin@ardentleatherworks.com> * fix: avoid redundant First() calls in BasicRepository (#101) Co-authored-by: admin <admin@ardentleatherworks.com> * fix(security): prevent path traversal and command injection (#102) Co-authored-by: admin <admin@ardentleatherworks.com> * fix(frontend): use ref to avoid stale movies closure in search (#103) Co-authored-by: admin <admin@ardentleatherworks.com> * fix(deps): remove obsolete System.Private.Uri package (#104) Closes #28 Co-authored-by: admin <admin@ardentleatherworks.com> * fix(ci): make test failures block builds (#105) - Remove continue-on-error from integration tests - Set fail-on-error: true on test reporter Closes #56 Co-authored-by: admin <admin@ardentleatherworks.com> * refactor(api): use async/await in MovieController.AllMovie (#107) Convert blocking GetAwaiter().GetResult() to proper await pattern in the API controller method. Partial fix for #32 Co-authored-by: admin <admin@ardentleatherworks.com> * fix: add readonly modifier to static regex field (#106) PerlRegexFactory: static Regex field should be readonly to prevent accidental reassignment. Closes #36 Co-authored-by: admin <admin@ardentleatherworks.com> * refactor: reduce cognitive complexity in FileNameBuilder.GetLanguagesToken (#108) Extract helper methods: - NormalizeLanguageCode: handles ISO639B mapping and culture conversion - ApplyLanguageFilter: handles include/exclude filter logic Uses LINQ for cleaner initial token processing. Closes #75 Co-authored-by: admin <admin@ardentleatherworks.com> * Bump the nuget group with 1 update (#109) Bumps System.Private.Uri from 4.3.0 to 4.3.2 --- updated-dependencies: - dependency-name: System.Private.Uri dependency-version: 4.3.2 dependency-type: direct:production dependency-group: nuget - dependency-name: System.Private.Uri dependency-version: 4.3.2 dependency-type: direct:production dependency-group: nuget ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [WIP] Fix open issues after research and analysis (#110) * Initial plan * feat(ci): Add secret scanning with secretlint to pre-commit hooks - Install secretlint and @secretlint/secretlint-rule-preset-recommend - Configure secretlint with .secretlintrc.json - Add secretlint to lint-staged configuration - Update CONTRIBUTING.md to document secret scanning - Resolves #55 Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * feat(privacy): Disable telemetry and analytics by default - Set SentryEnabled to false by default in SentryTarget - Update English localization to clarify error reporting is opt-in - Update README with detailed privacy information - Machine fingerprinting already removed (returns "anonymous") - Piwik analytics already removed - AnalyticsEnabled defaults to false in config This ensures no telemetry is sent without explicit user consent. Resolves #8 Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * refactor: Address code review feedback for pre-commit and telemetry changes - Optimize secretlint to only scan relevant file types (not all files) - Add ignoreFiles configuration to secretlint to exclude build artifacts - Clarify comment in SentryTarget about reconfiguration location Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Extract common notification provider helpers to reduce duplication (#111) * Initial plan * Extract common notification helper methods to reduce duplication - Create NotificationHelpers class with BytesToString, GetLinksString, and GetTitle methods - Update Discord notification to use shared helper methods - Remove duplicate helper methods from Discord.cs - Reduces ~60 lines of duplicate code Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Add common message helpers and update 11 notification providers - Add GetMovieAddedMessage and GetHealthRestoredMessage to NotificationHelpers - Update Discord, Gotify, Join, Mailgun, Prowl, PushBullet, Pushcut, Pushover, Pushsafer, Slack, and Telegram - Replace duplicate message strings with shared helper methods - Reduces ~22 lines of duplicate code across 11 providers Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Update 5 more notification providers with common message helpers - Update Apprise, Email, Ntfy, Simplepush, and Signal - Standardize movie added and health restored messages - Total of 16 providers now using shared helper methods Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Address code review feedback - Revert Apprise to use year in movie added message (preserve original behavior) - Return empty string instead of null in GetLinksString and GetTitle helpers - Improves null safety for consuming code Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Add null checks to GetMovieAddedMessage and GetHealthRestoredMessage - Prevent potential null reference exceptions - Return empty strings when parameters are null - Maintains consistency with other helper methods Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * Standardize API response codes: PUT returns 200, DELETE returns 204 (#112) * Initial plan * Fix API response codes: PUT returns 200 Ok, DELETE returns 204 NoContent Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: Update Radarr references to Aletheia and document test suite status (#113) * Initial plan * docs: update package.json metadata for Aletheia fork Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: update code comments to reference Aletheia instead of Radarr Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: add test status documentation Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: clarify Notifiarr integration naming in comment Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: add comprehensive documentation cleanup summary Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * docs: update CLEANUP_CANDIDATES.md with completed items Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * [WIP] Fix issues introduced by recent merges (#114) * Initial plan * Fix inconsistent HTTP response codes: PUT endpoints return 200 OK instead of 202 Accepted Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> * fix: resolve build errors from Copilot API response code changes (#115) - Fix void return handling in Update() methods that Copilot incorrectly assumed returned the updated object - Remove unused System.Linq using in NotificationHelpers.cs - Fix trailing whitespace style violations Co-authored-by: admin <admin@ardentleatherworks.com> * feat(db): add MediaType discriminator to Movies table (#116) Adds foundation for multi-media support by: - Adding MediaType column to Movies table (migration 244) - Adding MediaType property to Movie entity, defaulting to Movie Existing movies will have MediaType=1 (Movie) after migration. This prepares for future Book and Audiobook media types. Addresses Issue #1 Co-authored-by: admin <admin@ardentleatherworks.com> * refactor(core): create MediaItem abstract base class (#117) * feat(db): add MediaType discriminator to Movies table Adds foundation for multi-media support by: - Adding MediaType column to Movies table (migration 244) - Adding MediaType property to Movie entity, defaulting to Movie Existing movies will have MediaType=1 (Movie) after migration. This prepares for future Book and Audiobook media types. Addresses Issue #1 * refactor(core): create MediaItem abstract base class Extracts common properties from Movie into a new MediaItem base class: - MediaType, Monitored, QualityProfileId - Path, RootFolderPath, Added, Tags, LastSearchTime Movie now inherits from MediaItem and implements abstract methods GetTitle() and GetYear() while maintaining backward-compatible Title/Year property accessors. This prepares for Book and Audiobook entities that will share the same base structure. Addresses Issue #1 --------- Co-authored-by: admin <admin@ardentleatherworks.com> * feat(core): add Author and Series entities for hierarchical monitoring (#118) * feat(db): add MediaType discriminator to Movies table Adds foundation for multi-media support by: - Adding MediaType column to Movies table (migration 244) - Adding MediaType property to Movie entity, defaulting to Movie Existing movies will have MediaType=1 (Movie) after migration. This prepares for future Book and Audiobook media types. Addresses Issue #1 * refactor(core): create MediaItem abstract base class Extracts common properties from Movie into a new MediaItem base class: - MediaType, Monitored, QualityProfileId - Path, RootFolderPath, Added, Tags, LastSearchTime Movie now inherits from MediaItem and implements abstract methods GetTitle() and GetYear() while maintaining backward-compatible Title/Year property accessors. This prepares for Book and Audiobook entities that will share the same base structure. Addresses Issue #1 * feat(core): add Author and Series entities for hierarchical monitoring Introduces hierarchical structure for books/audiobooks: - Author entity: tracks authors with monitoring, quality profiles, paths - Series entity: groups books/audiobooks by series, linked to Author - MediaItem: adds AuthorId and SeriesId for hierarchy support - Migration 245: creates Authors and Series tables, adds columns to Movies This enables Author → Series → Item monitoring inheritance for future book and audiobook support. Addresses Issue #2 --------- Co-authored-by: admin <admin@ardentleatherworks.com> * feat(core): add generic IProvideMediaInfo interface (#119) * feat(db): add MediaType discriminator to Movies table Adds foundation for multi-media support by: - Adding MediaType column to Movies table (migration 244) - Adding MediaType property to Movie entity, defaulting to Movie Existing movies will have MediaType=1 (Movie) after migration. This prepares for future Book and Audiobook media types. Addresses Issue #1 * refactor(core): create MediaItem abstract base class Extracts common properties from Movie into a new MediaItem base class: - MediaType, Monitored, QualityProfileId - Path, RootFolderPath, Added, Tags, LastSearchTime Movie now inherits from MediaItem and implements abstract methods GetTitle() and GetYear() while maintaining backward-compatible Title/Year property accessors. This prepares for Book and Audiobook entities that will share the same base structure. Addresses Issue #1 * feat(core): add Author and Series entities for hierarchical monitoring Introduces hierarchical structure for books/audiobooks: - Author entity: tracks authors with monitoring, quality profiles, paths - Series entity: groups books/audiobooks by series, linked to Author - MediaItem: adds AuthorId and SeriesId for hierarchy support - Migration 245: creates Authors and Series tables, adds columns to Movies This enables Author → Series → Item monitoring inheritance for future book and audiobook support. Addresses Issue #2 * feat(core): add generic IProvideMediaInfo interface Introduces generic metadata provider interfaces: - IProvideMediaInfo<T>: Base interface for all metadata providers - GetByExternalId, GetById, GetBulkInfo - GetTrending, GetPopular, GetChangedItems - ISearchableMediaProvider<T>: Search capability interface - SearchByTitle with optional year filtering These interfaces establish the contract for future book and audiobook metadata providers while maintaining compatibility with the existing IProvideMovieInfo. Addresses Issue #3 --------- Co-authored-by: admin <admin@ardentleatherworks.com> * feat(qualities): add book and audiobook quality definitions (#120) * feat(db): add MediaType discriminator to Movies table Adds foundation for multi-media support by: - Adding MediaType column to Movies table (migration 244) - Adding MediaType property to Movie entity, defaulting to Movie Existing movies will have MediaType=1 (Movie) after migration. This prepares for future Book and Audiobook media types. Addresses Issue #1 * refactor(core): create MediaItem abstract base class Extracts common properties from Movie into a new MediaItem base class: - MediaType, Monitored, QualityProfileId - Path, RootFolderPath, Added, Tags, LastSearchTime Movie now inherits from MediaItem and implements abstract methods GetTitle() and GetYear() while maintaining backward-compatible Title/Year property accessors. This prepares for Book and Audiobook entities that will share the same base structure. Addresses Issue #1 * feat(core): add Author and Series entities for hierarchical monitoring Introduces hierarchical structure for books/audiobooks: - Author entity: tracks authors with monitoring, quality profiles, paths - Series entity: groups books/audiobooks by series, linked to Author - MediaItem: adds AuthorId and SeriesId for hierarchy support - Migration 245: creates Authors and Series tables, adds columns to Movies This enables Author → Series → Item monitoring inheritance for future book and audiobook support. Addresses Issue #2 * feat(core): add generic IProvideMediaInfo interface Introduces generic metadata provider interfaces: - IProvideMediaInfo<T>: Base interface for all metadata providers - GetByExternalId, GetById, GetBulkInfo - GetTrending, GetPopular, GetChangedItems - ISearchableMediaProvider<T>: Search capability interface - SearchByTitle with optional year filtering These interfaces establish the contract for future book and audiobook metadata providers while maintaining compatibility with the existing IProvideMovieInfo. Addresses Issue #3 * feat(qualities): add book and audiobook quality definitions Add quality source types and definitions for eBooks and audiobooks: - EBOOK source: Unknown, EPUB, MOBI, AZW3, PDF, TXT - AUDIOBOOK source: Unknown, MP3-128, MP3-320, M4B, FLAC Quality definitions include appropriate size limits for each format. New qualities auto-seed to database via QualityDefinitionService on startup. Closes #4, Closes #5 --------- Co-authored-by: admin <admin@ardentleatherworks.com> * feat(ui): add Books and Audiobooks navigation sections (#121) Add navigation sidebar entries for Books and Audiobooks with: - New BOOK and AUDIOBOOK icons in props - Books/Audiobooks sections in PageSidebar with Add New/Import children - Routes for /books and /audiobooks paths - Placeholder index pages for both media types - Translation strings for Books/Audiobooks Part of Phase 3 UI work for Issue #7. Co-authored-by: admin <admin@ardentleatherworks.com> * feat(database): add Book and Audiobook entities (#122) Add entities for books and audiobooks with: - Book entity: title, ISBN, ASIN, publisher, author/series links - Audiobook entity: title, narrator, duration, abridged flag, book link - Database migration 246 for Books and Audiobooks tables - Entity registrations in TableMapping Note: Depends on PR #118 (Author/Series tables) for full FK support. Co-authored-by: admin <admin@ardentleatherworks.com> * fix(core): code quality improvements (#123) - Remove debug Console.WriteLine from migration 170 - Fix DelayProfileService.Reorder to throw ModelNotFoundException instead of silent failure - Remove unused using directives Co-authored-by: admin <admin@ardentleatherworks.com> * feat(core): add Book and Audiobook repositories, services, and API controllers (#124) Adds the complete data layer for Books and Audiobooks: - BookRepository with query methods for ISBN, ASIN, Author, Series - BookService with business logic and event publishing - AudiobookRepository with narrator-aware query methods - AudiobookService with duration and narrator support - Domain events for both entity types - REST API controllers with full CRUD operations Co-authored-by: admin <admin@ardentleatherworks.com> * feat: Phase 2 Multi-Media Infrastructure - Books/Audiobooks Backend & Frontend (#125) * feat(api): add Book and Audiobook lookup and editor controllers Adds search and bulk edit functionality for Books and Audiobooks: - BookLookupController: search by ISBN, ISBN13, ASIN, ForeignId, title - AudiobookLookupController: search by ISBN, ASIN, narrator, title - BookEditorController: bulk update/delete books - AudiobookEditorController: bulk update/delete audiobooks - Editor validators and resources for both entity types * feat(core): add AddBookService and AddAudiobookService Adds services for adding new books and audiobooks with validation: - AddBookService: handles book creation with path generation - AddAudiobookService: handles audiobook creation with narrator-aware paths - AddBookValidator: validates book additions - AddAudiobookValidator: validates audiobook additions * feat(core): add BookFile and AudiobookFile entities and repositories Adds file tracking infrastructure for books and audiobooks: - BookFile entity with format tracking - AudiobookFile entity with audio metadata (duration, bitrate, etc.) - BookFileRepository for book file queries - AudiobookFileRepository for audiobook file queries - Database migration for new tables - Table mappings for new entities * feat(metadata): add Book and Audiobook metadata provider interfaces Adds metadata provider infrastructure for books and audiobooks: - IProvideBookInfo: interface for book metadata lookups - IProvideAudiobookInfo: interface for audiobook metadata lookups - BookMetadata: model for book metadata from external sources - AudiobookMetadata: model for audiobook metadata with narrator info - BookInfoProxy: stub implementation (to be replaced with Goodreads, etc.) - AudiobookInfoProxy: stub implementation (to be replaced with Audible, etc.) * feat(api): add Author and Series repositories, services, and API controllers * feat(ui): add Book and Audiobook Redux store and index pages --------- Co-authored-by: admin <admin@ardentleatherworks.com> * feat: add Author/Series services and frontend pages (#126) * feat(core): add AddAuthorService and AddSeriesService with validators * feat(api): add Author and Series lookup controllers * feat(ui): add Author and Series frontend index pages * feat(ui): add Book and Audiobook search pages * feat(ui): add Book and Audiobook detail pages * feat(ui): add Author and Series detail pages --------- Co-authored-by: admin <admin@ardentleatherworks.com> * ci(deps): bump actions/labeler from 4 to 6 (#127) Bumps [actions/labeler](https://github.com/actions/labeler) from 4 to 6. - [Release notes](https://github.com/actions/labeler/releases) - [Commits](https://github.com/actions/labeler/compare/v4...v6) --- updated-dependencies: - dependency-name: actions/labeler dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(deps): bump actions/setup-dotnet from 4 to 5 (#128) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 4 to 5. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(deps): bump github/codeql-action from 3 to 4 (#129) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3 to 4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v3...v4) --- updated-dependencies: - dependency-name: github/codeql-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * ci(deps): bump dessant/lock-threads from 4 to 6 (#130) Bumps [dessant/lock-threads](https://github.com/dessant/lock-threads) from 4 to 6. - [Release notes](https://github.com/dessant/lock-threads/releases) - [Changelog](https://github.com/dessant/lock-threads/blob/main/CHANGELOG.md) - [Commits](https://github.com/dessant/lock-threads/compare/v4...v6) --- updated-dependencies: - dependency-name: dessant/lock-threads dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: address SonarCloud code quality issues (#131) * fix: address SonarCloud code quality issues - Remove unused private fields from services and repositories - Replace Object.assign with spread operator in Redux actions - Use structuredClone instead of _.cloneDeep - Add exception parameters to catch clause logging - Use Number.parseInt instead of parseInt in detail pages - Mark React component props as readonly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: update CHANGELOG with Phase 2 multi-media work * fix: update labeler.yml for actions/labeler v6 format --------- Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat(monitoring): implement hierarchical monitoring for Author/Series/Book/Audiobook (#132) * feat(monitoring): implement hierarchical monitoring for Author/Series/Book/Audiobook - Add cascade logic: unmonitoring parent cascades to children - Re-monitoring parent does not auto-monitor children (explicit control) - EffectivelyMonitored computed from item AND all ancestors - Database indexes for efficient cascade queries (migration 248) - AuthorMonitoringChangedEvent and SeriesMonitoringChangedEvent - EffectivelyMonitored field added to Book/Audiobook API resources Closes #2 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(monitoring): reduce code duplication in HierarchicalMonitoringService - Extract common ancestor check to IsAncestorUnmonitored helper - Consolidate monitoring context retrieval to GetMonitoringContext - Create generic UnmonitorEntities helper for cascade operations - Reduce code from 302 to 233 lines while preserving all functionality * ci(sonar): exclude intentional structural duplication from CPD * ci(codeql): exclude user-controlled-bypass for monitoring cascade logic --------- Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * feat: add statistics services and analytics dashboard (#133) - Add BookStatistics and AudiobookStatistics services - Create unified Dashboard with media type stats - Add statistics to Book/Audiobook controllers - Make dashboard the default landing page Closes #6 Co-authored-by: admin <admin@ardentleatherworks.com> * refactor(database): unify Book/Audiobook inheritance with MediaItem (#134) Book and Audiobook now extend MediaItem instead of ModelBase, eliminating duplicate properties and enabling cross-media operations. - Remove duplicate MediaType, Monitored, Path, Tags, etc. from entities - Implement abstract GetTitle() and GetYear() methods - Add migration 249 (documentation only - no DB changes needed) Co-authored-by: admin <admin@ardentleatherworks.com> * feat(database): add Music entities and tables (#135) Add foundation for Music support: - Artist entity (parallel to Author) - Album entity (parallel to Series) - Track entity (extends MediaItem) - MusicFile entity for audio files - Migration 250 creates Artists, Albums, Tracks, MusicFiles tables - Register all entities in TableMapping Co-authored-by: admin <admin@ardentleatherworks.com> * feat(music): add repositories and services (#136) Add data access and business logic layers for Music support: - ArtistRepository/ArtistService for artist management - AlbumRepository/AlbumService for album management - TrackRepository/TrackService for track management - MusicFileRepository for audio file management Co-authored-by: admin <admin@ardentleatherworks.com> * refactor: extract BaseMediaService<T> base class (#137) * refactor: extract BaseMediaService<T> base class Extract common CRUD operations into BaseMediaService<T>: - Get, GetAll, Paged, Add, AddMany, Delete, DeleteMany, Update, UpdateMany - SetAddedTimestamp with reflection for non-MediaItem types - Virtual event hooks (OnItemAdded, OnItemDeleted, etc.) Migrate services to use base class: - BookService: 180 → 89 lines - AudiobookService: 192 → 93 lines - AlbumService: 132 → 58 lines - ArtistService: 107 → 50 lines - TrackService: 114 → 50 lines Net reduction: ~385 lines * chore: cleanup stale files and fix branding Remove IDE/editor config files that should not be tracked: - .vscode/, frontend/.vscode/, src/.idea/ - azure-pipelines.yml (obsolete CI) - Empty localization files (bs, ta, et, lt, sr, es_MX) Remove unused npm packages: - react-addons-shallow-compare - react-async-script Fix remaining Radarr→Aletheia branding: - ConsoleApp.cs error messages - openapi.json title/description/license - FileNameBuilder.cs default release group --------- Co-authored-by: admin <admin@ardentleatherworks.com> * chore: P2/P3 code cleanup batch (#138) - Remove unused RemoveTitle() methods from AlternativeTitleService, MovieTranslationService, CreditService - Clean commented-out code blocks in EventAggregator, Pneumatic, MovieStatisticsFixture - Consolidate 4 duplicate TagsModalContent.css files into shared Components/Styles module - Fix BaseMediaService StyleCop violations (SA1127, SA1502) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract BaseMediaCrudController for Book/Audiobook (#139) - Create BaseMediaCrudController with common CRUD patterns - Extract shared validation setup (path, quality, title) - Move Create, Update, Delete endpoints to base class - BookController: 219 -> 168 lines (-51) - AudiobookController: 227 -> 177 lines (-50) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract BaseMediaEditorController for bulk operations (#140) - Create IEditorResource interface for common editor properties - Create BaseMediaEditorController with common bulk edit/delete logic - Extract tag handling (Add/Remove/Replace) to base class - BookEditorController: 92 -> 36 lines (-56) - AudiobookEditorController: 92 -> 36 lines (-56) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract focused config services from ConfigService (#141) Create DownloadConfigService and ImportConfigService as focused interfaces for download-related and import-related configuration. Uses delegation pattern for backward compatibility. Co-authored-by: admin <admin@ardentleatherworks.com> * refactor: extract UIConfigService and ProxyConfigService (#142) Continue ConfigService split with UI and proxy-related settings. Uses delegation pattern for backward compatibility. Co-authored-by: admin <admin@ardentleatherworks.com> * refactor: add IMediaResource interface for resource mapping consolidation (#143) Create common interface for media resource properties (Id, Monitored, QualityProfileId, Path, RootFolderPath, Added, Tags). BookResource, AudiobookResource, and AuthorResource now implement IMediaResource. Foundation for future resource mapping consolidation. Co-authored-by: admin <admin@ardentleatherworks.com> * feat(music): complete Music API layer with hierarchical monitoring (#144) * feat(music): add events, statistics, and API resources Foundation layer for Music API support: - Events: Artist/Album/Track added/edited/deleted events - Statistics: MusicStatistics with album-level tracking - Resources: Artist, Album, Track, MusicFile, MusicStatistics DTOs * feat(music): add validators and add services for artist and album * feat(music): add main API controllers for artist, album, track, and music files * feat(music): add editor and lookup controllers for artist and album * feat(music): integrate hierarchical monitoring for artist/album/track * fix: address SonarCloud static method and indexer issues * fix: address SonarCloud code quality issues - Add SuppressMessage for S107 (constructor params) on DI controllers - Add SuppressMessage for S6968 (ASP.NET validation) on resource DTOs - Use global:: prefix to avoid namespace conflicts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: exclude Music API from duplication checks Music resources/controllers follow same pattern as Books/Audiobooks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: expand duplication exclusion to core Music files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: add MusicStats to duplication exclusions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: expand duplication exclusions to all media type directories 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * New: Parse Group GiLG (#145) Co-authored-by: TRaSH <trash-pm@protonmail.ch> Co-authored-by: admin <admin@ardentleatherworks.com> * feat(metadata): add Music and Book metadata providers (#146) * New: Parse Group GiLG * feat(metadata): add Music and Book metadata providers - Add MusicBrainz proxy for Artist/Album/Track lookups - Implement OpenLibrary integration for Book searches - Support ISBN, title, author lookups for books - Support MusicBrainz ID and name searches for music * fix: address SonarCloud issues in metadata providers --------- Co-authored-by: TRaSH <trash-pm@protonmail.ch> Co-authored-by: admin <admin@ardentleatherworks.com> * feat(music): comprehensive music quality support (#147) * feat(music): add comprehensive music quality support - Add MUSIC to QualitySource enum - Add Music qualities (ID 300-310): MP3-128/192/256/320, AAC-256, OGG-320, FLAC, FLAC 24bit, WAV, ALAC - Add DefaultQualityDefinitions for music (Weight 300+) - Add music file extensions (.mp3, .flac, .wav, .ogg, .m4a, .aac, .alac, .ape, .wv, .dsf, .dff) - Add ebook extensions (.epub, .mobi, .azw3, .pdf, .txt, .djvu, .cbr, .cbz) - Add audiobook extensions (.m4b, .aa, .aax) - Add MediaFileExtensions helper properties (MusicExtensions, EbookExtensions, AudiobookExtensions) - Create MusicQualityParser for bitrate/format/bit-depth detection - Create BookQualityParser for ebook format detection - Create AudiobookQualityParser for audiobook format/bitrate detection * feat(music): comprehensive quality system with full granularity Expand music quality system to 60+ distinct quality levels: Lossy (IDs 300-315): - MP3: 128/192/256/320 kbps - AAC: 128/256/320 kbps - OGG: 128/192/256/320 kbps - Opus: 128/192/256 kbps - WMA Lossless FLAC (IDs 320-327): - 16/44.1, 16/48, 24/44.1, 24/48, 24/88.2, 24/96, 24/176.4, 24/192 - 24/96 designated as target quality Lossless WAV (IDs 340-347): - Same bit-depth/sample-rate variants as FLAC Lossless AIFF (IDs 350-357): - Same bit-depth/sample-rate variants as FLAC DSD (IDs 360-363): - DSD64 (2.8MHz), DSD128 (5.6MHz), DSD256 (11.2MHz), DSD512 (22.4MHz) Other Lossless (IDs 370-377): - ALAC: 16/44.1, 16/48, 24/44.1, 24/48, 24/96, 24/192 - APE (Monkey's Audio), WavPack Special (IDs 380-381): - MQA, MQA Studio Add MusicFileAnalyzer service: - Uses ffprobe for accurate metadata detection - Extracts bit depth, sample rate, codec, bitrate - Maps to appropriate quality based on actual file properties Update MusicQualityParser: - Comprehensive regex patterns for all formats - Bit-depth/sample-rate detection from filenames - DSD variant detection - MQA detection - Hi-Res keyword recognition * fix(music): address SonarCloud code quality issues - S1172: Use unused codec/ext parameters in format detection - S6667: Pass exceptions to logger in catch blocks - S1192: Extract duplicate strings to constants - S3776: Reduce cognitive complexity via method extraction 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: address additional SonarCloud issues in music module - S1192: Extract string constants in MusicBrainzProxy and BookInfoProxy - S2325: Make LinkAlbumStatistics static in AlbumController - S4136: Reorder method overloads to be adjacent in Resource files - S6964: Use nullable value types in Resource classes where appropriate * fix(parser): reduce cognitive complexity in AudiobookQualityParser Extract format and bitrate parsing into separate methods to reduce cognitive complexity of ParseQualityName from 20 to under 15. * fix(security): add regex timeout to quality parsers Add 5-second timeout to all Regex patterns in AudiobookQualityParser, BookQualityParser, and MusicQualityParser to prevent ReDoS attacks. --------- Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * docs: update changelog with Phase 3-6 work - Add Phase 3 (Multi-Media Foundation) entries - Add Phase 4 (Books & Audiobooks) entries - Add Phase 6 (Music Foundation) entries with 60+ quality definitions - Document SonarCloud fixes from PR #147 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Robin Dadswell <19610103+RobinDadswell@users.noreply.github.com> Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com> Co-authored-by: plz12345 <132735020+plz12345@users.noreply.github.com> Co-authored-by: Erik Frantz <39980629+BardezAnAvatar@users.noreply.github.com> Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com> Co-authored-by: admin <admin@ardentleatherworks.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: cheir-mneme <176430037+cheir-mneme@users.noreply.github.com> Co-authored-by: TRaSH <trash-pm@protonmail.ch>
6 lines
80 B
JSON
6 lines
80 B
JSON
{
|
|
"sdk": {
|
|
"version": "8.0.100",
|
|
"rollForward": "latestFeature"
|
|
}
|
|
}
|