4388 Commits

Author SHA1 Message Date
Deluan
4d4685b8cf feat(library): implement scanner interface for triggering library scans on create/update
Signed-off-by: Deluan <deluan@navidrome.org>

# Conflicts:
#	cmd/wire_gen.go
#	cmd/wire_injectors.go

# Conflicts:
#	cmd/wire_gen.go

# Conflicts:
#	cmd/wire_gen.go
#	cmd/wire_injectors.go
2025-07-15 12:59:32 -04:00
Deluan
51ca35b0da feat(missingfiles): add library filter and display in MissingFilesList component
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
e4f660b70f feat(mediafile): add LibraryName field and update queries to include library name
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
056076cb94 feat(library): enhance LibraryCreate and LibraryEdit components with additional props and styling
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
45efa91c31 feat(library): add additional fields and restructure LibraryEdit component for enhanced statistics display
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
e8ad0d9348 feat(controller): add function to retrieve the most recent scan time across all libraries
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
80ce0df085 test(scanner): improve handling of filesystem errors and ensure warnings are returned
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
3f4744dff9 test(scanner): add tests for multi-library scanning and validation
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
62bccdd683 lint
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
0c03e10fa6 feat(library): enhance validation messages and error handling for library paths
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
2ed07414a2 simplify DeleteLibraryButton.jsx
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
a78c87be82 use utils/formatBytes
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
7db0ebb143 feat(library): improve library path validation and error handling - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
863bd4037a feat(library): enhance library validation and management with path checks and normalization - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
c6f203ddac feat(library): add library management features including create, edit, delete, and list functionalities - WIP
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
1bf921c7e3 fix migration file name
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
a1d43f9912 add total_duration column to library and update user_library table
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
e76b4c085b refactor library service to use REST repository pattern and remove CRUD operations
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
8014f70404 feat(database): add library filtering to album, folder, and media file queries
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
5feab89568 refactor(library): implement library management service and update API routes
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
836913543e feat(api): restrict access to library and config endpoints to admin users
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
29a595ddd6 feat(api): implement library management and user-library association endpoints
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
ee4c628a6b feat(database): enhance user retrieval with library associations
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:59:32 -04:00
Deluan
55cc4ab7b0 feat(database): add user_library table and library access methods
Signed-off-by: Deluan <deluan@navidrome.org>

# Conflicts:
#	tests/mock_library_repo.go
2025-07-15 12:59:32 -04:00
Deluan
adef0ea1e7 fix(plugins): resolve race condition in plugin manager registration
Fixed a race condition in the plugin manager where goroutines started during
plugin registration could concurrently access shared plugin maps while the
main registration loop was still running. The fix separates plugin registration
from background processing by collecting all plugins first, then starting
background goroutines after registration is complete.

This prevents concurrent read/write access to the plugins and adapters maps
that was causing data races detected by the Go race detector. The solution
maintains the same functionality while ensuring thread safety during the
plugin scanning and registration process.

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-15 12:58:16 -04:00
bytesingsong
b69a7652b9
chore: fix some typos in comment and logs (#4333)
Signed-off-by: bytesingsong <bytesing@icloud.com>
2025-07-13 14:31:15 -04:00
bytetigers
d8e829ad18
chore: fix function name/description in comment (#4325)
* chore: fix function in comment

Signed-off-by: bytetigers <bytetiger@icloud.com>

* Update model/metadata/persistent_ids.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Signed-off-by: bytetigers <bytetiger@icloud.com>
Co-authored-by: Deluan Quintão <github@deluan.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-07-13 14:30:58 -04:00
Deluan Quintão
5b73a4d5b7
feat(plugins): add TimeNow function to SchedulerService (#4337)
* feat: add TimeNow function to SchedulerService plugin

Added new TimeNow RPC method to the SchedulerService host service that returns
the current time in two formats: RFC3339Nano string and Unix milliseconds int64.
This provides plugins with a standardized way to get current time information
from the host system.

The implementation includes:
- TimeNowRequest/TimeNowResponse protobuf message definitions
- Go host service implementation using time.Now()
- Complete test coverage with format validation
- Generated WASM interface code for plugin communication

* feat: add LocalTimeZone field to TimeNow response

Added LocalTimeZone field to TimeNowResponse message in the SchedulerService
plugin host service. This field contains the server's local timezone name
(e.g., 'America/New_York', 'UTC') providing plugins with timezone context
alongside the existing RFC3339Nano and Unix milliseconds timestamps.

The implementation includes:
- New local_time_zone protobuf field definition
- Go implementation using time.Now().Location().String()
- Updated test coverage with timezone validation
- Generated protobuf serialization/deserialization code

* docs: update plugin README with TimeNow function documentation

Updated the plugins README.md to document the new TimeNow function in the
SchedulerService. The documentation includes detailed descriptions of the
three return formats (RFC3339Nano, UnixMilli, LocalTimeZone), practical
use cases, and a comprehensive Go code example showing how plugins can
access current time information for logging, calculations, and timezone-aware
operations.

* docs: remove wrong comment from InitRequest

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: add missing TimeNow method to namedSchedulerService

Added TimeNow method implementation to namedSchedulerService struct to satisfy the scheduler.SchedulerService interface contract. This method was recently added to the interface but the namedSchedulerService wrapper was not updated, causing compilation failures in plugin tests. The implementation is a simple pass-through to the underlying scheduler service since TimeNow doesn't require any special handling for named callbacks.

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-13 14:23:58 -04:00
Deluan
1de84dbd0c refactor(ui): replace translation key with direct character for remove action
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-12 16:55:21 -04:00
Deluan
e8a3495c70 test: suppress console.log output in eventStream test
Added console.log mock in eventStream.test.js to suppress the 'EventStream error' message that was appearing during test execution. This improves test output cleanliness by preventing the expected error logging from the eventStream error handling code from cluttering the test console output.

The mock follows the existing pattern used in the codebase for suppressing console output during tests and only affects the test environment, preserving the original logging functionality in production code.
2025-07-10 18:00:37 -03:00
Deluan
1166a0fabf fix(plugins): enhance error handling in checkErr function
Improved the error handling logic in the checkErr function to map specific error strings to their corresponding API error constants. This change ensures that errors from plugins are correctly identified and returned, enhancing the robustness of error reporting.

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-09 14:32:43 -03:00
Xabi
9e97d0a9d9
fix(ui): update Basque translation (#4309)
* Update eu.json

Added the most recent strings and tried to improve some of the older ones.

* Update eu.json - typo

just a typo
2025-07-09 00:28:38 -03:00
Kendall Garner
6730716d26
fix(scanner): lyrics tag parsing to properly handle both ID3 and aliased tags
* fix(taglib): parse both id3 and aliased tags, as lyrics appears to be mapped to lyrics-xxx

* address feedback, make confusing test more stable
2025-07-09 00:27:40 -03:00
Deluan Quintão
65961cce4b
fix(ui): replaygain for Artist Radio and Top Songs (#4328)
* Map replaygain info from getSimilarSongs2

* refactor: rename mapping function

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: Applied code review improvements

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-08 17:41:14 -03:00
Deluan Quintão
d041cb3249
fix(plugins): correct error handling in plugin initialization (#4311)
Updated the error handling logic in the plugin lifecycle manager to accurately record the success of the OnInit method. The change ensures that the metrics reflect whether the initialization was successful, improving the reliability of plugin metrics tracking. Additionally, removed the unused errorMapper interface from base_capability.go to clean up the codebase.

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-07 16:24:10 -03:00
Deluan Quintão
f1f1fd2007
refactor: streamline agents logic and remove unnecessary caching (#4298)
* refactor: enhance agent loading with structured data

Introduced a new struct, EnabledAgent, to encapsulate agent name and type
information (plugin or built-in). Updated the getEnabledAgentNames function
to return a slice of EnabledAgent instead of a slice of strings, allowing
for more detailed agent management. This change improves the clarity and
maintainability of the code by providing a structured approach to handling
enabled agents and their types.

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: remove agent caching logic

Eliminated the caching mechanism for agents, including the associated
data structures and methods. This change simplifies the agent loading
process by directly retrieving agents without caching, which is no longer
necessary for the current implementation. The removal of this logic helps
reduce complexity and improve maintainability of the codebase.

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor: replace range with slice.Contains

Signed-off-by: Deluan <deluan@navidrome.org>

* test: simplify agent name extraction in tests

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-05 10:11:35 -03:00
Deluan Quintão
66eaac2762
fix(plugins): add metrics on callbacks and improve plugin method calling (#4304)
* refactor: implement OnSchedulerCallback method in wasmSchedulerCallback

Added the OnSchedulerCallback method to the wasmSchedulerCallback struct, enabling it to handle scheduler callback events. This method constructs a SchedulerCallbackRequest and invokes the corresponding plugin method, facilitating better integration with the scheduling system. The changes improve the plugin's ability to respond to scheduled events, enhancing overall functionality.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): update executeCallback method to use callMethod

Modified the executeCallback method to accept an additional parameter,
methodName, which specifies the callback method to be executed. This change
ensures that the correct method is called for each WebSocket event,
improving the accuracy of callback execution for plugins.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): capture OnInit metrics

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): improve logging for metrics in callMethod

Updated the logging statement in the callMethod function to include the
elapsed time as a separate key in the log output. This change enhances
the clarity of the logged metrics, making it easier to analyze the
performance of plugin requests and troubleshoot any issues that may arise.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): enhance logging for schedule callback execution

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(server): streamline scrobbler stopping logic

Refactored the logic for stopping scrobbler instances when they are removed.
The new implementation introduces a `stoppableScrobbler` interface to
simplify the type assertion process, allowing for a more concise and
readable code structure. This change ensures that any scrobbler
implementing the `Stop` method is properly stopped before removal,
improving the overall reliability of the plugin management system.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): improve plugin lifecycle management and error handling

Enhanced the plugin lifecycle management by implementing error handling in the OnInit method. The changes include the addition of specific error conditions that can be returned during plugin initialization, allowing for better management of plugin states. Additionally, the unregisterPlugin method was updated to ensure proper cleanup of plugins that fail to initialize, improving overall stability and reliability of the plugin system.

Signed-off-by: Deluan <deluan@navidrome.org>

* refactor(plugins): remove unused LoadAllPlugins and related methods

Eliminated the LoadAllPlugins, LoadAllMediaAgents, and LoadAllScrobblers
methods from the manager implementation as they were not utilized in the codebase.
This cleanup reduces complexity and improves maintainability by removing
redundant code, allowing for a more streamlined plugin management process.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): update logging configuration for plugins

Configured logging for multiple plugins to remove timestamps and source file/line information, while adding specific prefixes for better identification.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): clear initialization state when unregistering a plugin

Added functionality to clear the initialization state of a plugin in the
lifecycle manager when it is unregistered. This change ensures that the
lifecycle state is accurately maintained, preventing potential issues with
plugins that may be re-registered after being unregistered. The new method
`clearInitialized` was implemented to handle this state management.

Signed-off-by: Deluan <deluan@navidrome.org>

* test: add unit tests for convertError function, rename to checkErr

Added comprehensive unit tests for the convertError function to ensure
correct behavior across various scenarios, including handling nil responses,
typed nils, and responses implementing errorResponse. These tests validate
that the function returns the expected results without panicking and
correctly wraps original errors when necessary.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(plugins): update plugin base implementation and method calls

Refactored the plugin base implementation by renaming `wasmBasePlugin` to `baseCapability` across multiple files. Updated method calls in the `wasmMediaAgent`, `wasmSchedulerCallback`, and `wasmScrobblerPlugin` to align with the new base structure. These changes improve code clarity and maintainability by standardizing the plugin architecture, ensuring consistent usage of the base capabilities across different plugin types.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(discord): handle failed connections and improve heartbeat checks

Added a new method to clean up failed connections, which cancels the heartbeat schedule, closes the WebSocket connection, and removes cache entries. Enhanced the heartbeat check to log failures and trigger the cleanup process on the first failure. These changes ensure better management of user connections and improve the overall reliability of the RPC system.

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-05 09:03:49 -03:00
Deluan Quintão
c583ff57a3
test: add translation validation system with CI integration (#4306)
* feat: add translation validation script and update JSON files

Introduced a new script `validate-translations.sh` to validate the structure
of JSON translation files against an English reference. This script checks
for missing and extra translation keys, ensuring consistency across language
files. Additionally, several JSON files were updated to include new keys
and improve existing translations, enhancing the overall localization
efforts for the application.

Signed-off-by: Deluan <deluan@navidrome.org>

* feat: enhance translation validation script

Updated the translation validation script to improve its functionality and usability. The script now validates JSON translation files against a reference English file, checking for JSON syntax, structural integrity, and reporting missing or extra keys. It also integrates with GitHub Actions for CI/CD, providing annotations for errors and warnings. Additionally, the usage instructions have been clarified, and verbose output options have been added for better debugging.

Signed-off-by: Deluan <deluan@navidrome.org>

* revert translations

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: Hungarian translation JSON structure

Signed-off-by: Deluan <deluan@navidrome.org>

* chore: update testall target in Makefile

Modified the 'testall' target in the Makefile to include 'test-i18n' in the test sequence. This change ensures that internationalization tests are run alongside other tests, improving the overall testing process and ensuring that translation-related issues are caught early in the development cycle.

Signed-off-by: Deluan <deluan@navidrome.org>

* run validation with verbose output

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-03 09:59:39 -04:00
Deluan Quintão
9b3d3d15a1
fix(plugins): report metrics for all plugin types, not only MetadataAgents (#4303)
- Add ErrNotImplemented error to plugins/api package with proper documentation
- Refactor callMethod in wasm_base_plugin to use api.ErrNotImplemented
- Improve metrics recording logic to exclude not-implemented methods
- Add better tracing and context handling for plugin calls
- Reorganize error definitions with clear documentation
2025-07-02 22:05:28 -04:00
Kendall Garner
d4f869152b
fix(scanner): read cover art from dsf, wavpak, fix wma test (#4296)
* fix(taglib): read cover art from dsf

* address feedback and alsi realize wma/wavpack are missing

* feedback

* more const char and remove unused import
2025-07-02 22:04:27 -04:00
Chris M
ee34433cc5
test: fix mpv tests on systems without /bin/bash installed - 4301 (#4302)
Not all systems have bash at `/bin/bash`. `/bin/sh` is POSIX and should
be present on all systems making this much more portable. No bash
features are currently used in the script so this change should be safe.
2025-07-02 21:55:55 -04:00
Deluan Quintão
a3d1a9dbe5
fix(plugins): silence plugin warnings and folder creation when plugins disabled (#4297)
* fix(plugins): silence repeated “Plugin not found” spam for inactive Spotify/Last.fm plugins

Navidrome was emitting a warning when the optional Spotify or
Last.fm agents weren’t enabled, filling the journal with entries like:

    level=warning msg="Plugin not found" capability=MetadataAgent name=spotify

Fixed by completely disable the plugin system when Plugins.Enabled = false.

Signed-off-by: Deluan <deluan@navidrome.org>

* style: update test description for clarity

Signed-off-by: Deluan <deluan@navidrome.org>

* fix: ensure plugin folder is created only if plugins are enabled

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-02 13:17:59 -04:00
ChekeredList71
82f490d066
fix(ui): update Hungarian translation (#4291)
* Hungarian: added new strings

new strings from the comparition of d903d3f1 and 4909232e

* Hungarian: fixed my mistakes

---------

Co-authored-by: ChekeredList71 <asd@asd.com>
2025-07-02 09:49:44 -04:00
Deluan Quintão
4909232e8f
fix(ui): update German, Greek, French, Indonesian, Russian, Swedish, Turkish translations from POEditor (#4157)
Co-authored-by: navidrome-bot <navidrome-bot@navidrome.org>
v0.57.0
2025-07-01 12:30:13 -04:00
Deluan
4096760b67 feat: support MBIDs in smart playlists
Signed-off-by: Deluan <deluan@navidrome.org>
2025-07-01 10:38:36 -04:00
Deluan
f92c807c0f chore: add pull request template
Introduced a new pull request template to standardize contributions and improve clarity in the review process. This template includes sections for description, related issues, type of change, checklist, testing instructions, and additional notes. By providing a structured format, contributors can better communicate their changes and maintainers can more easily review submissions.

Signed-off-by: Deluan <deluan@navidrome.org>
2025-06-30 17:15:42 -04:00
Deluan Quintão
bfa5b29913
feat: MBID search functionality for albums, artists and songs (#4286)
* feat(subsonic): search by MBID functionality

Updated the search methods in the mediaFileRepository, albumRepository, and artistRepository to support searching by MBID in addition to the existing query methods. This change improves the efficiency of media file, album, and artist searches, allowing for faster retrieval of records based on MBID.

Signed-off-by: Deluan <deluan@navidrome.org>

* feat(subsonic): enhance MBID search functionality for albums and artists

Updated the search functionality to support searching by MBID for both
albums and artists. The fullTextFilter function was modified to accept
additional MBID fields, allowing for more comprehensive searches. New
tests were added to ensure that the search functionality correctly
handles MBID queries, including cases for missing entries and the
includeMissing parameter. This enhancement improves the overall search
capabilities of the application, making it easier for users to find
specific media items by their unique identifiers.

Signed-off-by: Deluan <deluan@navidrome.org>

* fix(subsonic): normalize MBID to lowercase for consistent querying

Updated the MBID handling in the SQL search logic to convert the input
to lowercase before executing the query. This change ensures that
searches are case-insensitive, improving the accuracy and reliability
of the search results when querying by MBID.

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-06-30 17:11:54 -04:00
Kendall Garner
f9c7cc5348
fix(prometheus): report subsonic error code (#4282)
* fix(prometheus): report subsonic error code

* address feedback
2025-06-30 11:54:02 -04:00
Deluan Quintão
a559414ffa
chore(deps): update TagLib to 2.1.1 (#4281)
* chore: update CROSS_TAGLIB_VERSION to 2.1.1-1

* feat: add run-docker target

Introduced a new Makefile target `run-docker` that allows users to run a Navidrome Docker image with specified tags. This addition simplifies the process of launching the Docker container by handling volume mappings for configuration and music folders. The change enhances the development workflow by making it easier to test and run PR images

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-06-30 11:40:20 -04:00
Deluan Quintão
e3aec6d2a9
feat(ui): implement RecentlyAddedByModTime support for tracks (#4046) (#4279)
* fix: implement RecentlyAddedByModTime support for mediafiles

Fixes #4046 by adding recently_added sort mapping to MediaFileRepository that respects the RecentlyAddedByModTime configuration setting. Previously, this feature only worked for albums, causing inconsistent behavior when clients requested tracks sorted by 'recently added'.

Changes include:
- Add mediaFileRecentlyAddedSort() function that returns 'updated_at' when RecentlyAddedByModTime=true, 'created_at' otherwise
- Add 'recently_added' sort mapping to mediafile repository
- Add comprehensive tests to verify both configuration scenarios

This ensures consistent sorting behavior between albums and tracks when using the RecentlyAddedByModTime feature.

* fix: update createdAt field to sort by recently added

Modified the createdAt field in the SongList component to include a sortBy
attribute set to "recently_added". This change ensures that the media files
are displayed in the order they were added, improving the user experience
when browsing through recently added items.

Signed-off-by: Deluan <deluan@navidrome.org>

* better testing

Signed-off-by: Deluan <deluan@navidrome.org>

---------

Signed-off-by: Deluan <deluan@navidrome.org>
2025-06-30 09:14:35 -04:00