mxmarx / lidarr-beets Goto Github PK
View Code? Open in Web Editor NEWlidarr script for grabbing gazelle metadata and running beets
lidarr script for grabbing gazelle metadata and running beets
Hello! I am trying to run this on Unraid through the built in dockerman. The folder settings are correct, mapped to /beets, and linux permissions have been set to ugo+rwx recursively on both folders. Still, I'm getting the following error and would love some advice:
2024-02-07 21:21:41.1|Warn|LidarrErrorPipeline|FluentValidation.ValidationException: Validation failed:
-- : An error occurred trying to start process '/beets/beets-lidarr.sh' with working directory '/app/lidarr/bin'. Permission denied
[v2.0.7.3849] FluentValidation.ValidationException: Validation failed:
-- : An error occurred trying to start process '/beets/beets-lidarr.sh' with working directory '/app/lidarr/bin'. Permission denied
at Lidarr.Api.V1.ProviderControllerBase`4.VerifyValidationResult(ValidationResult validationResult, Boolean includeWarnings) in ./Lidarr.Api.V1/ProviderControllerBase.cs:line 281
at Lidarr.Api.V1.ProviderControllerBase`4.Test(TProviderDefinition definition, Boolean includeWarnings) in ./Lidarr.Api.V1/ProviderControllerBase.cs:line 267
at Lidarr.Api.V1.ProviderControllerBase`4.CreateProvider(TProviderResource providerResource, Boolean forceSave) in ./Lidarr.Api.V1/ProviderControllerBase.cs:line 77
at lambda_method146(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Lidarr.Http.Middleware.BufferingMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/BufferingMiddleware.cs:line 28
at Lidarr.Http.Middleware.IfModifiedMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/IfModifiedMiddleware.cs:line 41
at Lidarr.Http.Middleware.CacheHeaderMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/CacheHeaderMiddleware.cs:line 33
at Lidarr.Http.Middleware.StartingUpMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/StartingUpMiddleware.cs:line 38
at Lidarr.Http.Middleware.UrlBaseMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/UrlBaseMiddleware.cs:line 27
at Lidarr.Http.Middleware.VersionMiddleware.InvokeAsync(HttpContext context) in ./Lidarr.Http/Middleware/VersionMiddleware.cs:line 29
at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
I enabled beets verbose mode as I was trying to enable copying instead of hard linking the files after processing and I saw we aren't specifying the plugin path within the config.yml. I'm also seeing the following errors repeatedly and was wondering if they were of concern:
Edit: Are we leveraging a beets contained within Lidarr and not requiring a separate container? I may have misunderstood that part when I had put the scripts with my existing beets database and mounted it to /beets. If a separate beets container is not required, this may not be of concern and can likely be closed.
Thanks!
06/27/2023 10:43:37 AM
user configuration: /config/config.yaml
06/27/2023 10:43:37 AM
data directory: /config
06/27/2023 10:43:37 AM
plugin paths:
06/27/2023 10:43:38 AM
** error loading plugin originquery:
06/27/2023 10:43:38 AM
Traceback (most recent call last):
06/27/2023 10:43:38 AM
File "/usr/lib/python3.10/site-packages/beets/plugins.py", line 268, in load_plugins
06/27/2023 10:43:38 AM
namespace = __import__(modname, None, None)
06/27/2023 10:43:38 AM
ModuleNotFoundError: No module named 'beetsplug.originquery'
06/27/2023 10:43:38 AM
06/27/2023 10:43:38 AM
lyrics: Disabling google source: no API key configured.
06/27/2023 10:43:38 AM
ImageMagick version check failed: [Errno 2] No such file or directory: 'magick'
06/27/2023 10:43:38 AM
ImageMagick version check failed: [Errno 2] No such file or directory: 'convert'
06/27/2023 10:43:38 AM
artresizer: method is (1, (0,))
06/27/2023 10:43:38 AM
embedart: ImageMagick 6.8.7 or higher not installed; 'compare_threshold' option ignored
06/27/2023 10:43:38 AM
Sending event: pluginload
06/27/2023 10:43:38 AM
library database: /config/library.db
06/27/2023 10:43:38 AM
library directory: /music
06/27/2023 10:43:38 AM
Sending event: library_opened
06/27/2023 10:43:38 AM
error: unknown command 'web'
My compose file:
# Lidarr - Music Automated Acquisition
lidarr:
image: lscr.io/linuxserver/lidarr:develop
container_name: lidarr
<<: *common-apps
volumes:
- $DOCKERDIR/lidarr:/config
- $DOCKERDIR/beets:/beets
- $MEDIADIR:/mnt/media
environment:
<<: *default-env
DOCKER_MODS: linuxserver/mods:universal-package-install
INSTALL_PIP_PACKAGES: git+https://github.com/beetbox/beets.git|git+https://github.com/MxMarx/gazelle-origin@orpheus|git+https://github.com/MxMarx/beets-originquery|pyacoustid|beetcamp|pylast|python3-discogs-client
INSTALL_PACKAGES: git|ffmpeg|flac|imagemagick
API_KEY_RED: xxxxxxxx
API_KEY_OPS: xxxxxxxx
labels:
- traefik.enable=true
## HTTP Routers Auth Bypass
- traefik.http.routers.lidarr-bypass.entrypoints=https
- traefik.http.routers.lidarr-bypass.rule=Host(`lidarr.$DOMAINNAME`) && (Headers(`X-Api-Key`, `$LIDARR_API_KEY`) || Query(`apikey`, `$LIDARR_API_KEY`))
- traefik.http.routers.lidarr-bypass.priority=20
## HTTP Routers
- traefik.http.routers.lidarr.entrypoints=https
- traefik.http.routers.lidarr.rule=Host(`lidarr.$DOMAINNAME`)
- traefik.http.routers.lidarr.priority=10
## Middlewares
- traefik.http.routers.lidarr.middlewares=chain-authelia@file
- traefik.http.routers.lidarr-bypass.middlewares=chain-no-auth@file
## HTTP Services
- traefik.http.routers.lidarr.service=lidarr
- traefik.http.routers.lidarr-bypass.service=lidarr
- traefik.http.services.lidarr.loadbalancer.server.port=8686
# Beets - Music Tagging/Organization
beets:
image: lscr.io/linuxserver/beets
container_name: beets
<<: *common-apps
volumes:
- $DOCKERDIR/beets:/config
- $MEDIADIR/music:/music
environment:
<<: *default-env
Would it be possible to add support for https://github.com/x1ppy/freezetag such that before the music files are re-tagged and modified by beets, the original version is frozen and mounted to replace the seeding copy, allowing beets to write instead of copy, but not break the seeded files via hardlink?
Hi. Now that I have found and configured beets-lidarr, I am in the process of reimporting my entire music library into Lidarr with beets tagging on import.
Out of the 100+ albums I've thrown at it so far, there have been a small handful of albums that stops beets-lidarr in its tracks, and stops the import process altogether until I restart Lidarr. After restarting, Lidarr and the import process continues until Lidarr tries again to import one of these same specific albums.
Here is the log from one of these specific album:
(NOTE it gets hung on "Looking for origin data on RED". the "Traceback" line comes up immediatly after restarting)
Starting auto-beets. Good luck!
╔═══════════════╤═══════════════════╗
║ artist_name │ album_title ║
║───────────────┼───────────────────║
║ Steven Wilson │ The Harmony Codex ║
╚═══════════════╧═══════════════════╝
2024-06-09,18:37:22 INFO Missing API key for ops
2024-06-09,18:37:22 INFO Found API key for red
2024-06-09,18:37:22 INFO Found API key for lidarr
2024-06-09,18:37:22 WARNING Can't find the grab event in history!
2024-06-09,18:37:22 INFO album path = /data/media/music/Steven Wilson/(2023) The Harmony Codex
2024-06-09,18:37:22 INFO torrent url = []
2024-06-09,18:37:22 INFO torrent hash = 9C734F4CC9202E096BB0B7B643476D7A3463CF1C
2024-06-09,18:37:22 WARNING Couldn't find the tracker url, trying RED
2024-06-09,18:37:22 INFO Looking for origin data on RED
2024-06-09,18:53:08 WARNING gazelle-origin-RED: Traceback (most recent call last):
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 234, in handle_input_torrent
info = self.api.get_torrent_info(**parsed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/core.py", line 70, in get_torrent_info
info = self.request('torrent', hash=hash, id=id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/core.py", line 44, in request
return self._get_parsed_response(params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/core.py", line 51, in _get_parsed_response
raise GazelleAPIError('request',
gazelleorigin.core.GazelleAPIError: Could not retrieve origin data. Try again later. (status 400)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/lsiopy/bin/gazelle-origin", line 8, in <module>
sys.exit(main())
^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 264, in main
gazelle_origin.run()
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 160, in run
self.handle_input_torrent(torrent)
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 236, in handle_input_torrent
if self.handle_invalid() == "stop":
^^^^^^^^^^^^^^^^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 152, in handle_invalid
result = self.ask_invalid()
^^^^^^^^^^^^^^^^^^
File "/lsiopy/lib/python3.12/site-packages/gazelleorigin/__main__.py", line 139, in ask_invalid
do_this = input("Your choice: ")
^^^^^^^^^^^^^^^^^^^^^^
EOFError: EOF when reading a line
2024-06-09,18:56:15 INFO
Otherwise this has been a fantastic script and I very much appreciate your work sharing this with the community. Thanks!
If there is already a release in Lidarr with an existing origin-*.yaml file, and that release is replaced with a different release, the previously existing origin file remains and the beets tags the new, different release with the metadata from the previous one.
Would be better if beets-lidarr checks if the existing origin file matches what is being imported, or if it just starts a fresh origin file every time.
Thanks!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.