Giter Site home page Giter Site logo

buildarr / buildarr-prowlarr Goto Github PK

View Code? Open in Web Editor NEW
0.0 0.0 0.0 271 KB

Prowlarr indexer manager plugin for Buildarr

Home Page: https://buildarr.github.io/plugins/prowlarr

License: GNU General Public License v3.0

Python 100.00%
buildarr prowlarr sonarr

buildarr-prowlarr's Introduction

Welcome to Buildarr!

Docker Version PyPI PyPI - Python Version GitHub Test Status

This is Buildarr, a solution to automating deployment and configuration of your *Arr stack.

Have you spent many hours getting your setup for one or more linked Sonarr/Radarr/Prowlarr instances just right, only to have no way to reproduce this setup apart from UI screenshots and database backups?

Buildarr aims to alleviate those concerns by using a static configuration file to store settings for all your *Arr applications, and automatically configure them as defined. It can just once using an ad-hoc user command, or as a service to keep your application configurations up to date. Buildarr runs idempotently, only making changes to your instance if they are required.

It can also automatically retrieve optimal configuration values from TRaSH-Guides for many things such as quality definitions and release profiles, so not only is there no need to manually input them into your configuration, Buildarr will also continually keep them up to date for you.

The full documentation for Buildarr is available here.

Similar projects

Buildarr attempts to fulfill some of the needs of users of the following projects.

  • Bobarr - An all-in-one package containing Sonarr, Radarr, Jackett etc
    • Still requires manual configuration of many components, and there is no way to store the configuration as code.
  • Flemmarr - Uses API parameters stored in YAML configuration files to push configuration changes to Sonarr, Radarr, Lidarr etc
    • Requires users to comprehensively learn how the APIs of each application work, going through often poor documentation.
    • Since the values are machine-oriented, configuration files are difficult to write and understand.
    • Does not support idempotent updates (at this time).
  • Recyclarr - Automatically syncs recommended TRaSH-Guides settings to Sonarr/Radarr instances
    • Buildarr has support for this built-in, and in the case of Sonarr release profiles, supports the same filtering syntax.

Installation

Buildarr is available on Docker Hub as a Docker image.

$ docker pull callum027/buildarr:latest

All available plugins at the time of release are bundled into the official Docker container for Buildarr, so you can manage instances of those types right away.

Buildarr can also be installed using pip. Python 3.8 or later is required. Windows is natively supported.

As of version 0.4.0, the Python package for Buildarr no longer includes plugins for applications. In order to use Buildarr to manage an application instance, you will also need to install its corresponding plugin.

$ python3 -m venv buildarr-venv
$ . buildarr-venv/bin/activate
$ python3 -m pip install buildarr

You can deploy Buildarr as a service within a Docker Compose environment, or use configuration management tools such as Ansible to automatically deploy it.

For more information, check the installation instructions.

Plugins

Buildarr supports external plugins to allow additional applications to be supported.

At the time of this release the following plugins are available:

For more information on installing plugins, check the plugin documentation.

Configuration

Buildarr uses YAML as its configuration file format. By default, Buildarr looks for buildarr.yml in the current directory.

It contains not only the settings for Buildarr itself, but also the application instances to be managed. Multiple instances of the same application type can be defined (for example, a common use case would be separate Sonarr instances for HD TV shows, 4K TV shows, and anime).

Any configuration on the remote instance not explicitly defined in the Buildarr configuration is not modified.

For more information on how Buildarr uses configuration and how to configure Buildarr itself, check the configuration documentation.

Here is an example of a simple Buildarr configuration that changes some settings on a Sonarr instance:

---
# buildarr.yml
# Buildarr example configuration file.

# Buildarr configuration (all settings have sane default values)
buildarr:
  watch_config: true
  update_days:
    - "monday"
    - "tuesday"
    - "wednesday"
    - "thursday"
    - "friday"
    - "saturday"
    - "sunday"
  update_times:
    - "03:00"

# Sonarr instance configuration
sonarr:
  hostname: "localhost"
  port: 8989
  protocol: "http"
  settings:
    # General settings (all options supported except for changing the API key)
    general:
      host:
        instance_name: "Sonarr (Buildarr Example)"

If you have an already configured application instance, its configuration can be dumped. For example, to get the configuration of a Sonarr instance, this can be done using the following command (Buildarr will prompt for your API key):

$ docker run -it --rm callum027/buildarr:latest sonarr dump-config http://sonarr.example.com:8989

Once you have this configuration, you can insert it into buildarr.yml and ensure this configuration is maintained.

Running Buildarr

Once you have a valid configuration file, you can try Buildarr on your local machine using the Docker image.

The following command will mount the current folder into the Docker container so buildarr.yml can be read, and start Buildarr in daemon mode.

$ docker run -d --name buildarr -v $(pwd):/config -e PUID=$(id -u) -e PGID=$(id -g) callum027/buildarr:latest

If installed using pip, simply run the buildarr CLI command.

$ buildarr daemon

On startup, Buildarr daemon will do an initial sync with the defined instances, updating their configuration immediately. After this initial run, Buildarr will wake up at the scheduled times to periodically run updates as required.

2023-11-12 10:00:29,220 buildarr:1 buildarr.cli.daemon [INFO] Buildarr version 0.7.0 (log level: INFO)
2023-11-12 10:00:29,220 buildarr:1 buildarr.cli.daemon [INFO] Loading configuration file '/config/buildarr.yml'
2023-11-12 10:00:29,775 buildarr:1 buildarr.cli.daemon [INFO] Finished loading configuration file
2023-11-12 10:00:29,775 buildarr:1 buildarr.cli.daemon [INFO] Daemon configuration:
2023-11-12 10:00:29,776 buildarr:1 buildarr.cli.daemon [INFO]  - Watch configuration files: No
2023-11-12 10:00:29,776 buildarr:1 buildarr.cli.daemon [INFO]  - Update at:
2023-11-12 10:00:29,776 buildarr:1 buildarr.cli.daemon [INFO]    - Monday 03:00
2023-11-12 10:00:29,776 buildarr:1 buildarr.cli.daemon [INFO]    - Tuesday 03:00
2023-11-12 10:00:29,777 buildarr:1 buildarr.cli.daemon [INFO]    - Wednesday 03:00
2023-11-12 10:00:29,777 buildarr:1 buildarr.cli.daemon [INFO]    - Thursday 03:00
2023-11-12 10:00:29,778 buildarr:1 buildarr.cli.daemon [INFO]    - Friday 03:00
2023-11-12 10:00:29,778 buildarr:1 buildarr.cli.daemon [INFO]    - Saturday 03:00
2023-11-12 10:00:29,778 buildarr:1 buildarr.cli.daemon [INFO]    - Sunday 03:00
2023-11-12 10:00:29,778 buildarr:1 buildarr.cli.daemon [INFO] Scheduling update jobs
2023-11-12 10:00:29,779 buildarr:1 buildarr.cli.daemon [INFO] Finished scheduling update jobs
2023-11-12 10:00:29,779 buildarr:1 buildarr.cli.daemon [INFO] Config file monitoring is already disabled
2023-11-12 10:00:29,779 buildarr:1 buildarr.cli.daemon [INFO] Applying initial configuration
2023-11-12 10:00:29,932 buildarr:1 buildarr.cli.run [INFO] Loaded plugins: jellyseerr (0.3.0), prowlarr (0.5.0), radarr (0.2.0), sonarr (0.6.0)
2023-11-12 10:00:29,932 buildarr:1 buildarr.cli.run [INFO] Loading instance configurations
2023-11-12 10:00:29,973 buildarr:1 buildarr.cli.run [INFO] Finished loading instance configurations
2023-11-12 10:00:29,973 buildarr:1 buildarr.cli.run [INFO] Running with plugins: prowlarr, sonarr, radarr, jellyseerr
2023-11-12 10:00:29,973 buildarr:1 buildarr.cli.run [INFO] Resolving instance dependencies
2023-11-12 10:00:29,973 buildarr:1 buildarr.cli.run [INFO] Finished resolving instance dependencies
2023-11-12 10:00:29,973 buildarr:1 buildarr.cli.run [INFO] Fetching TRaSH metadata
2023-11-12 10:00:36,723 buildarr:1 buildarr.cli.run [INFO] Finished fetching TRaSH metadata
2023-11-12 10:00:36,723 buildarr:1 buildarr.cli.run [INFO] Rendering instance configuration dynamic attributes
2023-11-12 10:00:36,739 buildarr:1 buildarr.cli.run [INFO] Finished rendering instance configuration dynamic attributes
2023-11-12 10:00:37,273 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Fetching instance secrets
2023-11-12 10:00:37,273 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Finished fetching instance secrets
2023-11-12 10:00:37,273 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Running connection test
2023-11-12 10:00:37,343 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Connection test successful
2023-11-12 10:00:38,112 buildarr:1 buildarr.cli.run [INFO] Performing post-initialisation configuration render
2023-11-12 10:00:39,292 buildarr:1 buildarr.cli.run [INFO] Finished performing post-initialisation configuration render
2023-11-12 10:00:39,292 buildarr:1 buildarr.cli.run [INFO] Updating configuration on remote instances
2023-11-12 10:00:39,292 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Fetching remote configuration to check if updates are required
2023-11-12 10:00:39,738 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Finished fetching remote configuration
2023-11-12 10:00:39,810 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Updating remote configuration
2023-11-12 10:00:39,850 buildarr:1 buildarr.config.base [INFO] <sonarr> (default) sonarr.settings.general.host.instance_name: 'Sonarr' -> 'Sonarr (Buildarr Example)'
2023-11-12 10:00:39,933 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Remote configuration successfully updated
2023-11-12 10:00:40,574 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Finished updating remote configuration
2023-11-12 10:00:49,722 buildarr:1 buildarr.cli.run [INFO] Finished updating configuration on remote instances
2023-11-12 10:00:49,722 buildarr:1 buildarr.cli.run [INFO] Deleting unmanaged/unused resources on remote instances
2023-11-12 10:00:52,579 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Refetching remote configuration to delete unused resources
2023-11-12 10:00:52,714 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Finished refetching remote configuration
2023-11-12 10:00:52,771 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Deleting unmanaged/unused resources on the remote instance
2023-11-12 10:00:52,843 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Remote configuration is clean
2023-11-12 10:00:52,843 buildarr:1 buildarr.cli.run [INFO] <sonarr> (default) Finished deleting unmanaged/unused resources on the remote instance
2023-11-12 10:00:52,843 buildarr:1 buildarr.cli.run [INFO] Finished deleting unmanaged/unused resources on remote instances
2023-11-12 10:00:52,843 buildarr:1 buildarr.cli.run [INFO] Deleting downloaded TRaSH metadata
2023-11-12 10:00:52,873 buildarr:1 buildarr.cli.run [INFO] Finished deleting downloaded TRaSH metadata
2023-11-12 10:00:52,874 buildarr:1 buildarr.cli.daemon [INFO] Finished applying initial configuration
2023-11-12 10:00:52,874 buildarr:1 buildarr.cli.daemon [INFO] Setting up signal handlers
2023-11-12 10:00:52,875 buildarr:1 buildarr.cli.daemon [INFO] Finished setting up signal handlers
2023-11-12 10:00:52,875 buildarr:1 buildarr.cli.daemon [INFO] The next run will be at 2023-11-13 03:00
2023-11-12 10:00:52,875 buildarr:1 buildarr.cli.daemon [INFO] Buildarr ready.

For more information on how to interfact with Buildarr, check the usage documentation.

To-do list

  • Test updates for all available attributes in the existing Sonarr plugin
  • Unit tests and code coverage
  • Split Sonarr plugin to its own repository (completed in version 0.4.0)
  • Create plugins for the following applications:
  • Instance linking (e.g. Prowlarr-to-Sonarr/Radarr) and dependency resolution (added in version 0.3.0)
  • Stable plugin API between major versions
  • Auto-generation of Docker Compose environment files reflecting the Buildarr configuration (added in version 0.4.0)

Contributions

Buildarr is still early in development, and even currently implemented features still require testing and fixing. There are so many possible configurations to cover that I simply cannot feasibly test every feature at this time.

If you encounter an issue or error while using Buildarr, please do a Buildarr ad-hoc run with verbose log output by executing buildarr --log-level DEBUG run and making an issue on our GitHub repository explaining the issue and attaching the output. (Please ensure that any API keys or other sensitive information are obfuscated before submitting.)

$ docker run -d --name buildarr -v $(pwd):/config -e PUID=$(id -u) -e PGID=$(id -g) callum027/buildarr:latest --log-level DEBUG run

Bug reports and pull requests for Buildarr itself are welcome in the Buildarr base package repository. For reporting issues and making contributions to application plugins, check out their repositories:

For developers looking to make a contribution to this project, thank you! Documentation of the internal APIs is still in the works, so for now, the best way to learn how Buildarr works is to clone the project and have a look at the comments and docstrings.

Pre-commit hooks are configured for this project. In this pre-commit hook, Black, Ruff and Mypy are run to automatically format source files, ensure grammatical correctness and variable type consistency.

To enable them, ensure the pre-commit Python package is installed in your local environment and run the following command:

$ pre-commit install

Poetry is used to manage the Python package definition and dependencies in this project.

If you're looking to develop a new plugin for adding support for a new application, please develop it as a new package and configure entry points in your Python package definitions to allow Buildarr to load your plugin.

Setuptools setup.py entry point definition example:

from setuptools import setup

setup(
    # ...,
    entry_points={
        "buildarr.plugins": [
            "example = buildarr_example.plugin:ExamplePlugin",
        ],
    },
)

Setuptools setup.cfg entry point definition example:

[options.entry_points]
buildarr.plugins =
    example = buildarr_example.plugin:ExamplePlugin

Setuptools pyproject.toml entry point definition example:

[project.entry-points."buildarr.plugins"]
"example" = "buildarr_example.plugin:ExamplePlugin"

Poetry plugin definition example:

[tool.poetry.plugins."buildarr.plugins"]
"example" = "buildarr_example.plugin:ExamplePlugin"

buildarr-prowlarr's People

Contributors

callum027 avatar

Watchers

 avatar

buildarr-prowlarr's Issues

ValueError: <AuthenticationType.EXTERNAL: 'external'> is not a valid AuthenticationMethod

According to the docs AuthenticationMethod should be set to External if authentication should be disabled but this value is not supported by buildarr.

https://wiki.servarr.com/prowlarr/faq#authentication-method

Note that this value comes from the remote config and is accepted by prowlarr:

2023-11-05 14:38:37,349 buildarr:1 buildarr.cli.daemon [INFO] Buildarr version 0.6.1 (log level: INFO)
2023-11-05 14:38:37,349 buildarr:1 buildarr.cli.daemon [INFO] Loading configuration file '/config/buildarr.yml'
2023-11-05 14:38:37,377 buildarr:1 buildarr.cli.daemon [INFO] Finished loading configuration file
2023-11-05 14:38:37,377 buildarr:1 buildarr.cli.daemon [INFO] Daemon configuration:
2023-11-05 14:38:37,377 buildarr:1 buildarr.cli.daemon [INFO]  - Watch configuration files: Yes
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]  - Configuration files to watch:
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - /config/buildarr.yml
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - /prowlarr/prowlarr.yaml
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]  - Update at:
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Monday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Tuesday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Wednesday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Thursday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Friday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Saturday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO]    - Sunday 03:00
2023-11-05 14:38:37,378 buildarr:1 buildarr.cli.daemon [INFO] Scheduling update jobs
2023-11-05 14:38:37,379 buildarr:1 buildarr.cli.daemon [INFO] Finished scheduling update jobs
2023-11-05 14:38:37,379 buildarr:1 buildarr.cli.daemon [INFO] Enabling config file monitoring
2023-11-05 14:38:37,379 buildarr:1 buildarr.cli.daemon [INFO] Finished enabling config file monitoring
2023-11-05 14:38:37,379 buildarr:1 buildarr.cli.daemon [INFO] Applying initial configuration
2023-11-05 14:38:37,386 buildarr:1 buildarr.cli.run [INFO] Loaded plugins: jellyseerr (0.2.0), prowlarr (0.4.0), radarr (0.1.1), sonarr (0.5.4)
2023-11-05 14:38:37,386 buildarr:1 buildarr.cli.run [INFO] Loading instance configurations
2023-11-05 14:38:37,387 buildarr:1 buildarr.cli.run [INFO] Finished loading instance configurations
2023-11-05 14:38:37,387 buildarr:1 buildarr.cli.run [INFO] Running with plugins: prowlarr
2023-11-05 14:38:37,388 buildarr:1 buildarr.cli.run [INFO] Resolving instance dependencies
2023-11-05 14:38:37,388 buildarr:1 buildarr.cli.run [INFO] Finished resolving instance dependencies
2023-11-05 14:38:37,388 buildarr:1 buildarr.cli.run [INFO] Rendering instance configuration dynamic attributes
2023-11-05 14:38:37,388 buildarr:1 buildarr.cli.run [INFO] Finished rendering instance configuration dynamic attributes
2023-11-05 14:38:37,388 buildarr:1 buildarr.cli.run [INFO] Loading secrets file from '/secrets/secrets.json'
2023-11-05 14:38:37,389 buildarr:1 buildarr.cli.run [INFO] Finished loading secrets file
2023-11-05 14:38:37,389 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Checking secrets
2023-11-05 14:38:37,393 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Connection test successful using cached secrets
2023-11-05 14:38:37,393 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Finished checking secrets
2023-11-05 14:38:37,393 buildarr:1 buildarr.cli.run [INFO] Saving updated secrets file to '/secrets/secrets.json'
2023-11-05 14:38:37,394 buildarr:1 buildarr.cli.run [INFO] Finished saving updated secrets file
2023-11-05 14:38:37,394 buildarr:1 buildarr.cli.run [INFO] Performing post-initialisation configuration render
2023-11-05 14:38:37,394 buildarr:1 buildarr.cli.run [INFO] Finished performing post-initialisation configuration render
2023-11-05 14:38:37,394 buildarr:1 buildarr.cli.run [INFO] Updating configuration on remote instances
2023-11-05 14:38:37,394 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Fetching remote configuration to check if updates are required
Traceback (most recent call last):
  File "/usr/local/bin/buildarr", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 568, in daemon
    ).start()
      ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 113, in start
    self._initial_run()
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 226, in _initial_run
    run_apply(secrets_file_path=self._secrets_file_path)
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/run.py", line 287, in _run
    remote_instance_config = manager.from_remote(instance_config, instance_secrets)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/manager/__init__.py", line 171, in from_remote
    return instance_config.from_remote(secrets)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/__init__.py", line 157, in from_remote
    settings=ProwlarrSettings.from_remote(secrets),
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 85, in from_remote
    fields[field_name] = field.type_.from_remote(secrets)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/general.py", line 585, in from_remote
    security=SecurityGeneralSettings._from_remote(remote_attrs),
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/general.py", line 107, in _from_remote
    return cls(**cls.get_local_attrs(cls._remote_map, remote_attrs))
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 243, in get_local_attrs
    local_attrs[attr_name] = decoder(remote_attr)
                             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 195, in <lambda>
    lambda v: cls._decode_attr(attr_name, v),
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 714, in _decode_attr
    return cls._decode_attr_(cls.__fields__[attr_name].outer_type_, value)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 740, in _decode_attr_
    return type_tree[-1](value)
           ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 712, in __call__
    return cls.__new__(cls, value)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/enum.py", line 1135, in __new__
    raise ve_exc
ValueError: <AuthenticationType.EXTERNAL: 'external'> is not a valid AuthenticationMethod

Tag v0.5.0

Checklist:

  1. Set milestone to v0.5.0
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.4.3..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #50
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6839538877
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6839546136
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.3.1

Checklist:

  1. Set milestone to v0.3.1
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.3.0..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #23
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6128973991
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6128979262
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Radarr app setting create: TypeError: 'ApplicationResource' object is not a mapping

While trying to create the radarr app setting in prowlarr I'm getting the following error:

2023-11-05 14:42:11,944 buildarr:1 buildarr.cli.daemon [INFO] Buildarr version 0.6.1 (log level: INFO)
2023-11-05 14:42:11,944 buildarr:1 buildarr.cli.daemon [INFO] Loading configuration file '/config/buildarr.yml'
2023-11-05 14:42:11,972 buildarr:1 buildarr.cli.daemon [INFO] Finished loading configuration file
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO] Daemon configuration:
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]  - Watch configuration files: Yes
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]  - Configuration files to watch:
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - /config/buildarr.yml
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - /prowlarr/prowlarr.yaml
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]  - Update at:
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Monday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Tuesday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Wednesday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Thursday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Friday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Saturday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO]    - Sunday 03:00
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO] Scheduling update jobs
2023-11-05 14:42:11,973 buildarr:1 buildarr.cli.daemon [INFO] Finished scheduling update jobs
2023-11-05 14:42:11,974 buildarr:1 buildarr.cli.daemon [INFO] Enabling config file monitoring
2023-11-05 14:42:11,974 buildarr:1 buildarr.cli.daemon [INFO] Finished enabling config file monitoring
2023-11-05 14:42:11,974 buildarr:1 buildarr.cli.daemon [INFO] Applying initial configuration
2023-11-05 14:42:11,981 buildarr:1 buildarr.cli.run [INFO] Loaded plugins: jellyseerr (0.2.0), prowlarr (0.4.0), radarr (0.1.1), sonarr (0.5.4)
2023-11-05 14:42:11,981 buildarr:1 buildarr.cli.run [INFO] Loading instance configurations
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Finished loading instance configurations
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Running with plugins: prowlarr
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Resolving instance dependencies
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Finished resolving instance dependencies
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Rendering instance configuration dynamic attributes
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Finished rendering instance configuration dynamic attributes
2023-11-05 14:42:11,983 buildarr:1 buildarr.cli.run [INFO] Loading secrets file from '/secrets/secrets.json'
2023-11-05 14:42:11,984 buildarr:1 buildarr.cli.run [INFO] Secrets file does not exist, will create new file
2023-11-05 14:42:11,984 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Checking secrets
2023-11-05 14:42:11,984 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Connection test failed using cached secrets (or not cached), fetching secrets
2023-11-05 14:42:11,988 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Connection test successful using fetched secrets
2023-11-05 14:42:11,988 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Finished checking secrets
2023-11-05 14:42:11,988 buildarr:1 buildarr.cli.run [INFO] Saving updated secrets file to '/secrets/secrets.json'
2023-11-05 14:42:11,989 buildarr:1 buildarr.cli.run [INFO] Finished saving updated secrets file
2023-11-05 14:42:11,989 buildarr:1 buildarr.cli.run [INFO] Performing post-initialisation configuration render
2023-11-05 14:42:11,989 buildarr:1 buildarr.cli.run [INFO] Finished performing post-initialisation configuration render
2023-11-05 14:42:11,989 buildarr:1 buildarr.cli.run [INFO] Updating configuration on remote instances
2023-11-05 14:42:11,989 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Fetching remote configuration to check if updates are required
2023-11-05 14:42:12,036 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Finished fetching remote configuration
2023-11-05 14:42:12,044 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (default) Updating remote configuration
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].prowlarr_url: 'http://prowlarr.prowlarr' -> (created)
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].base_url: 'http://radarr.radarr' -> (created)
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].sync_level: 'full-sync' -> (created)
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].sync_categories: {'movies/sd', 'movies/hd', 'movies/other', 'movies/foreign', 'movies', 'movies/dvd', 'movies/bluray', 'movies/uhd', 'movies/web-dl', 'movies/3d'} -> (created)
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].tags: set() -> (created)
2023-11-05 14:42:12,060 buildarr:1 buildarr.config.base [INFO] <prowlarr> (default) prowlarr.settings.apps.applications.definitions['Radarr'].api_key: '**********' -> (created)
Traceback (most recent call last):
  File "/usr/local/bin/buildarr", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 568, in daemon
    ).start()
      ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 113, in start
    self._initial_run()
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 226, in _initial_run
    run_apply(secrets_file_path=self._secrets_file_path)
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/run.py", line 300, in _run
    if manager.update_remote(
       ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/manager/__init__.py", line 192, in update_remote
    return local_instance_config.update_remote(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 272, in update_remote
    if isinstance(field, ConfigBase) and field.update_remote(
                                         ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/__init__.py", line 70, in update_remote
    self.apps.update_remote(
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 272, in update_remote
    if isinstance(field, ConfigBase) and field.update_remote(
                                         ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 740, in update_remote
    local_application._create_remote(
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 207, in _create_remote
    remote_attrs = {"name": application_name, **api_schema, **set_attrs}
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'ApplicationResource' object is not a mapping

Note that no application is created in Prowlarr. Does radarr actually need to exist for the config the successfully push? I know this is required in the Prowlarr UI but I hoped this would not be the case through buildarr/ the api.

Tag v0.3.0

Checklist:

  1. Set milestone to v0.3.0
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.2.0..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #17
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6127176687
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6127184711
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.4.1

Checklist:

  1. Set milestone to v0.4.1
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.4.0..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #33
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6759277345
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6759282873
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

dump config key error on categories

Error when dumping existing config:

Traceback (most recent call last):
  File "/usr/local/bin/buildarr", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/cli.py", line 81, in dump_config
    .from_remote(
     ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/manager/__init__.py", line 171, in from_remote
    return instance_config.from_remote(secrets)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/__init__.py", line 157, in from_remote
    settings=ProwlarrSettings.from_remote(secrets),
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 85, in from_remote
    fields[field_name] = field.type_.from_remote(secrets)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 85, in from_remote
    fields[field_name] = field.type_.from_remote(secrets)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 684, in from_remote
    definitions={
                ^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 687, in <dictcomp>
    ]._from_remote(
      ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 162, in _from_remote
    **cls.get_local_attrs(
      ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 243, in get_local_attrs
    local_attrs[attr_name] = decoder(remote_attr)
                             ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 120, in <lambda>
    "decoder": lambda v: cls._sync_categories_decoder(category_ids, v),
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 143, in _sync_categories_decoder
    return set(category_names[category_id] for category_id in api_sync_categories)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/apps/applications.py", line 143, in <genexpr>
    return set(category_names[category_id] for category_id in api_sync_categories)
               ~~~~~~~~~~~~~~^^^^^^^^^^^^^
KeyError: 2000

API content:

[
  {
    "syncLevel": "fullSync",
    "name": "Radarr",
    "fields": [
      {
        "order": 0,
        "name": "prowlarrUrl",
        "label": "Prowlarr Server",
        "helpText": "Prowlarr server URL as Radarr sees it, including http(s)://, port, and urlbase if needed",
        "value": "http://prowlarr:9696",
        "type": "textbox",
        "advanced": false,
        "placeholder": "http://localhost:9696",
        "isFloat": false
      },
      {
        "order": 1,
        "name": "baseUrl",
        "label": "Radarr Server",
        "helpText": "URL used to connect to Radarr server, including http(s)://, port, and urlbase if required",
        "value": "http://radarr:7878",
        "type": "textbox",
        "advanced": false,
        "placeholder": "http://localhost:7878",
        "isFloat": false
      },
      {
        "order": 2,
        "name": "apiKey",
        "label": "API Key",
        "helpText": "The ApiKey generated by Radarr in Settings/General",
        "value": "",
        "type": "textbox",
        "advanced": false,
        "isFloat": false
      },
      {
        "order": 3,
        "name": "syncCategories",
        "label": "Sync Categories",
        "helpText": "Only Indexers that support these categories will be synced",
        "value": [
          2000,
          2010,
          2020,
          2030,
          2040,
          2045,
          2050,
          2060,
          2070,
          2080
        ],
        "type": "select",
        "advanced": true,
        "selectOptions": [
          {
            "value": 0,
            "name": "Other",
            "order": 0,
            "hint": "(0)"
          },
          {
            "value": 10,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(10)",
            "parentValue": 0
          },
          {
            "value": 20,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(20)",
            "parentValue": 0
          },
          {
            "value": 1000,
            "name": "Console",
            "order": 0,
            "hint": "(1000)"
          },
          {
            "value": 1010,
            "name": "Console/NDS",
            "order": 0,
            "hint": "(1010)",
            "parentValue": 1000
          },
          {
            "value": 1020,
            "name": "Console/PSP",
            "order": 0,
            "hint": "(1020)",
            "parentValue": 1000
          },
          {
            "value": 1030,
            "name": "Console/Wii",
            "order": 0,
            "hint": "(1030)",
            "parentValue": 1000
          },
          {
            "value": 1040,
            "name": "Console/XBox",
            "order": 0,
            "hint": "(1040)",
            "parentValue": 1000
          },
          {
            "value": 1050,
            "name": "Console/XBox 360",
            "order": 0,
            "hint": "(1050)",
            "parentValue": 1000
          },
          {
            "value": 1060,
            "name": "Console/Wiiware",
            "order": 0,
            "hint": "(1060)",
            "parentValue": 1000
          },
          {
            "value": 1070,
            "name": "Console/XBox 360 DLC",
            "order": 0,
            "hint": "(1070)",
            "parentValue": 1000
          },
          {
            "value": 1080,
            "name": "Console/PS3",
            "order": 0,
            "hint": "(1080)",
            "parentValue": 1000
          },
          {
            "value": 1090,
            "name": "Console/Other",
            "order": 0,
            "hint": "(1090)",
            "parentValue": 1000
          },
          {
            "value": 1110,
            "name": "Console/3DS",
            "order": 0,
            "hint": "(1110)",
            "parentValue": 1000
          },
          {
            "value": 1120,
            "name": "Console/PS Vita",
            "order": 0,
            "hint": "(1120)",
            "parentValue": 1000
          },
          {
            "value": 1130,
            "name": "Console/WiiU",
            "order": 0,
            "hint": "(1130)",
            "parentValue": 1000
          },
          {
            "value": 1140,
            "name": "Console/XBox One",
            "order": 0,
            "hint": "(1140)",
            "parentValue": 1000
          },
          {
            "value": 1180,
            "name": "Console/PS4",
            "order": 0,
            "hint": "(1180)",
            "parentValue": 1000
          },
          {
            "value": 2000,
            "name": "Movies",
            "order": 0,
            "hint": "(2000)"
          },
          {
            "value": 2010,
            "name": "Movies/Foreign",
            "order": 0,
            "hint": "(2010)",
            "parentValue": 2000
          },
          {
            "value": 2020,
            "name": "Movies/Other",
            "order": 0,
            "hint": "(2020)",
            "parentValue": 2000
          },
          {
            "value": 2030,
            "name": "Movies/SD",
            "order": 0,
            "hint": "(2030)",
            "parentValue": 2000
          },
          {
            "value": 2040,
            "name": "Movies/HD",
            "order": 0,
            "hint": "(2040)",
            "parentValue": 2000
          },
          {
            "value": 2045,
            "name": "Movies/UHD",
            "order": 0,
            "hint": "(2045)",
            "parentValue": 2000
          },
          {
            "value": 2050,
            "name": "Movies/BluRay",
            "order": 0,
            "hint": "(2050)",
            "parentValue": 2000
          },
          {
            "value": 2060,
            "name": "Movies/3D",
            "order": 0,
            "hint": "(2060)",
            "parentValue": 2000
          },
          {
            "value": 2070,
            "name": "Movies/DVD",
            "order": 0,
            "hint": "(2070)",
            "parentValue": 2000
          },
          {
            "value": 2080,
            "name": "Movies/WEB-DL",
            "order": 0,
            "hint": "(2080)",
            "parentValue": 2000
          },
          {
            "value": 2090,
            "name": "Movies/x265",
            "order": 0,
            "hint": "(2090)",
            "parentValue": 2000
          },
          {
            "value": 3000,
            "name": "Audio",
            "order": 0,
            "hint": "(3000)"
          },
          {
            "value": 3010,
            "name": "Audio/MP3",
            "order": 0,
            "hint": "(3010)",
            "parentValue": 3000
          },
          {
            "value": 3020,
            "name": "Audio/Video",
            "order": 0,
            "hint": "(3020)",
            "parentValue": 3000
          },
          {
            "value": 3030,
            "name": "Audio/Audiobook",
            "order": 0,
            "hint": "(3030)",
            "parentValue": 3000
          },
          {
            "value": 3040,
            "name": "Audio/Lossless",
            "order": 0,
            "hint": "(3040)",
            "parentValue": 3000
          },
          {
            "value": 3050,
            "name": "Audio/Other",
            "order": 0,
            "hint": "(3050)",
            "parentValue": 3000
          },
          {
            "value": 3060,
            "name": "Audio/Foreign",
            "order": 0,
            "hint": "(3060)",
            "parentValue": 3000
          },
          {
            "value": 4000,
            "name": "PC",
            "order": 0,
            "hint": "(4000)"
          },
          {
            "value": 4010,
            "name": "PC/0day",
            "order": 0,
            "hint": "(4010)",
            "parentValue": 4000
          },
          {
            "value": 4020,
            "name": "PC/ISO",
            "order": 0,
            "hint": "(4020)",
            "parentValue": 4000
          },
          {
            "value": 4030,
            "name": "PC/Mac",
            "order": 0,
            "hint": "(4030)",
            "parentValue": 4000
          },
          {
            "value": 4040,
            "name": "PC/Mobile-Other",
            "order": 0,
            "hint": "(4040)",
            "parentValue": 4000
          },
          {
            "value": 4050,
            "name": "PC/Games",
            "order": 0,
            "hint": "(4050)",
            "parentValue": 4000
          },
          {
            "value": 4060,
            "name": "PC/Mobile-iOS",
            "order": 0,
            "hint": "(4060)",
            "parentValue": 4000
          },
          {
            "value": 4070,
            "name": "PC/Mobile-Android",
            "order": 0,
            "hint": "(4070)",
            "parentValue": 4000
          },
          {
            "value": 5000,
            "name": "TV",
            "order": 0,
            "hint": "(5000)"
          },
          {
            "value": 5010,
            "name": "TV/WEB-DL",
            "order": 0,
            "hint": "(5010)",
            "parentValue": 5000
          },
          {
            "value": 5020,
            "name": "TV/Foreign",
            "order": 0,
            "hint": "(5020)",
            "parentValue": 5000
          },
          {
            "value": 5030,
            "name": "TV/SD",
            "order": 0,
            "hint": "(5030)",
            "parentValue": 5000
          },
          {
            "value": 5040,
            "name": "TV/HD",
            "order": 0,
            "hint": "(5040)",
            "parentValue": 5000
          },
          {
            "value": 5045,
            "name": "TV/UHD",
            "order": 0,
            "hint": "(5045)",
            "parentValue": 5000
          },
          {
            "value": 5050,
            "name": "TV/Other",
            "order": 0,
            "hint": "(5050)",
            "parentValue": 5000
          },
          {
            "value": 5060,
            "name": "TV/Sport",
            "order": 0,
            "hint": "(5060)",
            "parentValue": 5000
          },
          {
            "value": 5070,
            "name": "TV/Anime",
            "order": 0,
            "hint": "(5070)",
            "parentValue": 5000
          },
          {
            "value": 5080,
            "name": "TV/Documentary",
            "order": 0,
            "hint": "(5080)",
            "parentValue": 5000
          },
          {
            "value": 5090,
            "name": "TV/x265",
            "order": 0,
            "hint": "(5090)",
            "parentValue": 5000
          },
          {
            "value": 6000,
            "name": "XXX",
            "order": 0,
            "hint": "(6000)"
          },
          {
            "value": 6010,
            "name": "XXX/DVD",
            "order": 0,
            "hint": "(6010)",
            "parentValue": 6000
          },
          {
            "value": 6020,
            "name": "XXX/WMV",
            "order": 0,
            "hint": "(6020)",
            "parentValue": 6000
          },
          {
            "value": 6030,
            "name": "XXX/XviD",
            "order": 0,
            "hint": "(6030)",
            "parentValue": 6000
          },
          {
            "value": 6040,
            "name": "XXX/x264",
            "order": 0,
            "hint": "(6040)",
            "parentValue": 6000
          },
          {
            "value": 6045,
            "name": "XXX/UHD",
            "order": 0,
            "hint": "(6045)",
            "parentValue": 6000
          },
          {
            "value": 6050,
            "name": "XXX/Pack",
            "order": 0,
            "hint": "(6050)",
            "parentValue": 6000
          },
          {
            "value": 6060,
            "name": "XXX/ImageSet",
            "order": 0,
            "hint": "(6060)",
            "parentValue": 6000
          },
          {
            "value": 6070,
            "name": "XXX/Other",
            "order": 0,
            "hint": "(6070)",
            "parentValue": 6000
          },
          {
            "value": 6080,
            "name": "XXX/SD",
            "order": 0,
            "hint": "(6080)",
            "parentValue": 6000
          },
          {
            "value": 6090,
            "name": "XXX/WEB-DL",
            "order": 0,
            "hint": "(6090)",
            "parentValue": 6000
          },
          {
            "value": 7000,
            "name": "Books",
            "order": 0,
            "hint": "(7000)"
          },
          {
            "value": 7010,
            "name": "Books/Mags",
            "order": 0,
            "hint": "(7010)",
            "parentValue": 7000
          },
          {
            "value": 7020,
            "name": "Books/EBook",
            "order": 0,
            "hint": "(7020)",
            "parentValue": 7000
          },
          {
            "value": 7030,
            "name": "Books/Comics",
            "order": 0,
            "hint": "(7030)",
            "parentValue": 7000
          },
          {
            "value": 7040,
            "name": "Books/Technical",
            "order": 0,
            "hint": "(7040)",
            "parentValue": 7000
          },
          {
            "value": 7050,
            "name": "Books/Other",
            "order": 0,
            "hint": "(7050)",
            "parentValue": 7000
          },
          {
            "value": 7060,
            "name": "Books/Foreign",
            "order": 0,
            "hint": "(7060)",
            "parentValue": 7000
          },
          {
            "value": 8000,
            "name": "Other",
            "order": 0,
            "hint": "(8000)"
          },
          {
            "value": 8010,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(8010)",
            "parentValue": 8000
          },
          {
            "value": 8020,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(8020)",
            "parentValue": 8000
          }
        ],
        "isFloat": false
      }
    ],
    "implementationName": "Radarr",
    "implementation": "Radarr",
    "configContract": "RadarrSettings",
    "infoLink": "https://wiki.servarr.com/prowlarr/supported#radarr",
    "tags": [],
    "id": 1
  },
  {
    "syncLevel": "fullSync",
    "name": "Sonarr",
    "fields": [
      {
        "order": 0,
        "name": "prowlarrUrl",
        "label": "Prowlarr Server",
        "helpText": "Prowlarr server URL as Sonarr sees it, including http(s)://, port, and urlbase if needed",
        "value": "http://prowlarr:9696",
        "type": "textbox",
        "advanced": false,
        "placeholder": "http://localhost:9696",
        "isFloat": false
      },
      {
        "order": 1,
        "name": "baseUrl",
        "label": "Sonarr Server",
        "helpText": "URL used to connect to Sonarr server, including http(s)://, port, and urlbase if required",
        "value": "http://sonarr:8989",
        "type": "textbox",
        "advanced": false,
        "placeholder": "http://localhost:8989",
        "isFloat": false
      },
      {
        "order": 2,
        "name": "apiKey",
        "label": "API Key",
        "helpText": "The ApiKey generated by Sonarr in Settings/General",
        "value": "",
        "type": "textbox",
        "advanced": false,
        "isFloat": false
      },
      {
        "order": 3,
        "name": "syncCategories",
        "label": "Sync Categories",
        "helpText": "Only Indexers that support these categories will be synced",
        "value": [
          5000,
          5010,
          5020,
          5030,
          5040,
          5045,
          5050,
          5070
        ],
        "type": "select",
        "advanced": true,
        "selectOptions": [
          {
            "value": 0,
            "name": "Other",
            "order": 0,
            "hint": "(0)"
          },
          {
            "value": 10,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(10)",
            "parentValue": 0
          },
          {
            "value": 20,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(20)",
            "parentValue": 0
          },
          {
            "value": 1000,
            "name": "Console",
            "order": 0,
            "hint": "(1000)"
          },
          {
            "value": 1010,
            "name": "Console/NDS",
            "order": 0,
            "hint": "(1010)",
            "parentValue": 1000
          },
          {
            "value": 1020,
            "name": "Console/PSP",
            "order": 0,
            "hint": "(1020)",
            "parentValue": 1000
          },
          {
            "value": 1030,
            "name": "Console/Wii",
            "order": 0,
            "hint": "(1030)",
            "parentValue": 1000
          },
          {
            "value": 1040,
            "name": "Console/XBox",
            "order": 0,
            "hint": "(1040)",
            "parentValue": 1000
          },
          {
            "value": 1050,
            "name": "Console/XBox 360",
            "order": 0,
            "hint": "(1050)",
            "parentValue": 1000
          },
          {
            "value": 1060,
            "name": "Console/Wiiware",
            "order": 0,
            "hint": "(1060)",
            "parentValue": 1000
          },
          {
            "value": 1070,
            "name": "Console/XBox 360 DLC",
            "order": 0,
            "hint": "(1070)",
            "parentValue": 1000
          },
          {
            "value": 1080,
            "name": "Console/PS3",
            "order": 0,
            "hint": "(1080)",
            "parentValue": 1000
          },
          {
            "value": 1090,
            "name": "Console/Other",
            "order": 0,
            "hint": "(1090)",
            "parentValue": 1000
          },
          {
            "value": 1110,
            "name": "Console/3DS",
            "order": 0,
            "hint": "(1110)",
            "parentValue": 1000
          },
          {
            "value": 1120,
            "name": "Console/PS Vita",
            "order": 0,
            "hint": "(1120)",
            "parentValue": 1000
          },
          {
            "value": 1130,
            "name": "Console/WiiU",
            "order": 0,
            "hint": "(1130)",
            "parentValue": 1000
          },
          {
            "value": 1140,
            "name": "Console/XBox One",
            "order": 0,
            "hint": "(1140)",
            "parentValue": 1000
          },
          {
            "value": 1180,
            "name": "Console/PS4",
            "order": 0,
            "hint": "(1180)",
            "parentValue": 1000
          },
          {
            "value": 2000,
            "name": "Movies",
            "order": 0,
            "hint": "(2000)"
          },
          {
            "value": 2010,
            "name": "Movies/Foreign",
            "order": 0,
            "hint": "(2010)",
            "parentValue": 2000
          },
          {
            "value": 2020,
            "name": "Movies/Other",
            "order": 0,
            "hint": "(2020)",
            "parentValue": 2000
          },
          {
            "value": 2030,
            "name": "Movies/SD",
            "order": 0,
            "hint": "(2030)",
            "parentValue": 2000
          },
          {
            "value": 2040,
            "name": "Movies/HD",
            "order": 0,
            "hint": "(2040)",
            "parentValue": 2000
          },
          {
            "value": 2045,
            "name": "Movies/UHD",
            "order": 0,
            "hint": "(2045)",
            "parentValue": 2000
          },
          {
            "value": 2050,
            "name": "Movies/BluRay",
            "order": 0,
            "hint": "(2050)",
            "parentValue": 2000
          },
          {
            "value": 2060,
            "name": "Movies/3D",
            "order": 0,
            "hint": "(2060)",
            "parentValue": 2000
          },
          {
            "value": 2070,
            "name": "Movies/DVD",
            "order": 0,
            "hint": "(2070)",
            "parentValue": 2000
          },
          {
            "value": 2080,
            "name": "Movies/WEB-DL",
            "order": 0,
            "hint": "(2080)",
            "parentValue": 2000
          },
          {
            "value": 2090,
            "name": "Movies/x265",
            "order": 0,
            "hint": "(2090)",
            "parentValue": 2000
          },
          {
            "value": 3000,
            "name": "Audio",
            "order": 0,
            "hint": "(3000)"
          },
          {
            "value": 3010,
            "name": "Audio/MP3",
            "order": 0,
            "hint": "(3010)",
            "parentValue": 3000
          },
          {
            "value": 3020,
            "name": "Audio/Video",
            "order": 0,
            "hint": "(3020)",
            "parentValue": 3000
          },
          {
            "value": 3030,
            "name": "Audio/Audiobook",
            "order": 0,
            "hint": "(3030)",
            "parentValue": 3000
          },
          {
            "value": 3040,
            "name": "Audio/Lossless",
            "order": 0,
            "hint": "(3040)",
            "parentValue": 3000
          },
          {
            "value": 3050,
            "name": "Audio/Other",
            "order": 0,
            "hint": "(3050)",
            "parentValue": 3000
          },
          {
            "value": 3060,
            "name": "Audio/Foreign",
            "order": 0,
            "hint": "(3060)",
            "parentValue": 3000
          },
          {
            "value": 4000,
            "name": "PC",
            "order": 0,
            "hint": "(4000)"
          },
          {
            "value": 4010,
            "name": "PC/0day",
            "order": 0,
            "hint": "(4010)",
            "parentValue": 4000
          },
          {
            "value": 4020,
            "name": "PC/ISO",
            "order": 0,
            "hint": "(4020)",
            "parentValue": 4000
          },
          {
            "value": 4030,
            "name": "PC/Mac",
            "order": 0,
            "hint": "(4030)",
            "parentValue": 4000
          },
          {
            "value": 4040,
            "name": "PC/Mobile-Other",
            "order": 0,
            "hint": "(4040)",
            "parentValue": 4000
          },
          {
            "value": 4050,
            "name": "PC/Games",
            "order": 0,
            "hint": "(4050)",
            "parentValue": 4000
          },
          {
            "value": 4060,
            "name": "PC/Mobile-iOS",
            "order": 0,
            "hint": "(4060)",
            "parentValue": 4000
          },
          {
            "value": 4070,
            "name": "PC/Mobile-Android",
            "order": 0,
            "hint": "(4070)",
            "parentValue": 4000
          },
          {
            "value": 5000,
            "name": "TV",
            "order": 0,
            "hint": "(5000)"
          },
          {
            "value": 5010,
            "name": "TV/WEB-DL",
            "order": 0,
            "hint": "(5010)",
            "parentValue": 5000
          },
          {
            "value": 5020,
            "name": "TV/Foreign",
            "order": 0,
            "hint": "(5020)",
            "parentValue": 5000
          },
          {
            "value": 5030,
            "name": "TV/SD",
            "order": 0,
            "hint": "(5030)",
            "parentValue": 5000
          },
          {
            "value": 5040,
            "name": "TV/HD",
            "order": 0,
            "hint": "(5040)",
            "parentValue": 5000
          },
          {
            "value": 5045,
            "name": "TV/UHD",
            "order": 0,
            "hint": "(5045)",
            "parentValue": 5000
          },
          {
            "value": 5050,
            "name": "TV/Other",
            "order": 0,
            "hint": "(5050)",
            "parentValue": 5000
          },
          {
            "value": 5060,
            "name": "TV/Sport",
            "order": 0,
            "hint": "(5060)",
            "parentValue": 5000
          },
          {
            "value": 5070,
            "name": "TV/Anime",
            "order": 0,
            "hint": "(5070)",
            "parentValue": 5000
          },
          {
            "value": 5080,
            "name": "TV/Documentary",
            "order": 0,
            "hint": "(5080)",
            "parentValue": 5000
          },
          {
            "value": 5090,
            "name": "TV/x265",
            "order": 0,
            "hint": "(5090)",
            "parentValue": 5000
          },
          {
            "value": 6000,
            "name": "XXX",
            "order": 0,
            "hint": "(6000)"
          },
          {
            "value": 6010,
            "name": "XXX/DVD",
            "order": 0,
            "hint": "(6010)",
            "parentValue": 6000
          },
          {
            "value": 6020,
            "name": "XXX/WMV",
            "order": 0,
            "hint": "(6020)",
            "parentValue": 6000
          },
          {
            "value": 6030,
            "name": "XXX/XviD",
            "order": 0,
            "hint": "(6030)",
            "parentValue": 6000
          },
          {
            "value": 6040,
            "name": "XXX/x264",
            "order": 0,
            "hint": "(6040)",
            "parentValue": 6000
          },
          {
            "value": 6045,
            "name": "XXX/UHD",
            "order": 0,
            "hint": "(6045)",
            "parentValue": 6000
          },
          {
            "value": 6050,
            "name": "XXX/Pack",
            "order": 0,
            "hint": "(6050)",
            "parentValue": 6000
          },
          {
            "value": 6060,
            "name": "XXX/ImageSet",
            "order": 0,
            "hint": "(6060)",
            "parentValue": 6000
          },
          {
            "value": 6070,
            "name": "XXX/Other",
            "order": 0,
            "hint": "(6070)",
            "parentValue": 6000
          },
          {
            "value": 6080,
            "name": "XXX/SD",
            "order": 0,
            "hint": "(6080)",
            "parentValue": 6000
          },
          {
            "value": 6090,
            "name": "XXX/WEB-DL",
            "order": 0,
            "hint": "(6090)",
            "parentValue": 6000
          },
          {
            "value": 7000,
            "name": "Books",
            "order": 0,
            "hint": "(7000)"
          },
          {
            "value": 7010,
            "name": "Books/Mags",
            "order": 0,
            "hint": "(7010)",
            "parentValue": 7000
          },
          {
            "value": 7020,
            "name": "Books/EBook",
            "order": 0,
            "hint": "(7020)",
            "parentValue": 7000
          },
          {
            "value": 7030,
            "name": "Books/Comics",
            "order": 0,
            "hint": "(7030)",
            "parentValue": 7000
          },
          {
            "value": 7040,
            "name": "Books/Technical",
            "order": 0,
            "hint": "(7040)",
            "parentValue": 7000
          },
          {
            "value": 7050,
            "name": "Books/Other",
            "order": 0,
            "hint": "(7050)",
            "parentValue": 7000
          },
          {
            "value": 7060,
            "name": "Books/Foreign",
            "order": 0,
            "hint": "(7060)",
            "parentValue": 7000
          },
          {
            "value": 8000,
            "name": "Other",
            "order": 0,
            "hint": "(8000)"
          },
          {
            "value": 8010,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(8010)",
            "parentValue": 8000
          },
          {
            "value": 8020,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(8020)",
            "parentValue": 8000
          }
        ],
        "isFloat": false
      },
      {
        "order": 4,
        "name": "animeSyncCategories",
        "label": "Anime Sync Categories",
        "helpText": "Only Indexers that support these categories will be synced",
        "value": [
          5070
        ],
        "type": "select",
        "advanced": true,
        "selectOptions": [
          {
            "value": 0,
            "name": "Other",
            "order": 0,
            "hint": "(0)"
          },
          {
            "value": 10,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(10)",
            "parentValue": 0
          },
          {
            "value": 20,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(20)",
            "parentValue": 0
          },
          {
            "value": 1000,
            "name": "Console",
            "order": 0,
            "hint": "(1000)"
          },
          {
            "value": 1010,
            "name": "Console/NDS",
            "order": 0,
            "hint": "(1010)",
            "parentValue": 1000
          },
          {
            "value": 1020,
            "name": "Console/PSP",
            "order": 0,
            "hint": "(1020)",
            "parentValue": 1000
          },
          {
            "value": 1030,
            "name": "Console/Wii",
            "order": 0,
            "hint": "(1030)",
            "parentValue": 1000
          },
          {
            "value": 1040,
            "name": "Console/XBox",
            "order": 0,
            "hint": "(1040)",
            "parentValue": 1000
          },
          {
            "value": 1050,
            "name": "Console/XBox 360",
            "order": 0,
            "hint": "(1050)",
            "parentValue": 1000
          },
          {
            "value": 1060,
            "name": "Console/Wiiware",
            "order": 0,
            "hint": "(1060)",
            "parentValue": 1000
          },
          {
            "value": 1070,
            "name": "Console/XBox 360 DLC",
            "order": 0,
            "hint": "(1070)",
            "parentValue": 1000
          },
          {
            "value": 1080,
            "name": "Console/PS3",
            "order": 0,
            "hint": "(1080)",
            "parentValue": 1000
          },
          {
            "value": 1090,
            "name": "Console/Other",
            "order": 0,
            "hint": "(1090)",
            "parentValue": 1000
          },
          {
            "value": 1110,
            "name": "Console/3DS",
            "order": 0,
            "hint": "(1110)",
            "parentValue": 1000
          },
          {
            "value": 1120,
            "name": "Console/PS Vita",
            "order": 0,
            "hint": "(1120)",
            "parentValue": 1000
          },
          {
            "value": 1130,
            "name": "Console/WiiU",
            "order": 0,
            "hint": "(1130)",
            "parentValue": 1000
          },
          {
            "value": 1140,
            "name": "Console/XBox One",
            "order": 0,
            "hint": "(1140)",
            "parentValue": 1000
          },
          {
            "value": 1180,
            "name": "Console/PS4",
            "order": 0,
            "hint": "(1180)",
            "parentValue": 1000
          },
          {
            "value": 2000,
            "name": "Movies",
            "order": 0,
            "hint": "(2000)"
          },
          {
            "value": 2010,
            "name": "Movies/Foreign",
            "order": 0,
            "hint": "(2010)",
            "parentValue": 2000
          },
          {
            "value": 2020,
            "name": "Movies/Other",
            "order": 0,
            "hint": "(2020)",
            "parentValue": 2000
          },
          {
            "value": 2030,
            "name": "Movies/SD",
            "order": 0,
            "hint": "(2030)",
            "parentValue": 2000
          },
          {
            "value": 2040,
            "name": "Movies/HD",
            "order": 0,
            "hint": "(2040)",
            "parentValue": 2000
          },
          {
            "value": 2045,
            "name": "Movies/UHD",
            "order": 0,
            "hint": "(2045)",
            "parentValue": 2000
          },
          {
            "value": 2050,
            "name": "Movies/BluRay",
            "order": 0,
            "hint": "(2050)",
            "parentValue": 2000
          },
          {
            "value": 2060,
            "name": "Movies/3D",
            "order": 0,
            "hint": "(2060)",
            "parentValue": 2000
          },
          {
            "value": 2070,
            "name": "Movies/DVD",
            "order": 0,
            "hint": "(2070)",
            "parentValue": 2000
          },
          {
            "value": 2080,
            "name": "Movies/WEB-DL",
            "order": 0,
            "hint": "(2080)",
            "parentValue": 2000
          },
          {
            "value": 2090,
            "name": "Movies/x265",
            "order": 0,
            "hint": "(2090)",
            "parentValue": 2000
          },
          {
            "value": 3000,
            "name": "Audio",
            "order": 0,
            "hint": "(3000)"
          },
          {
            "value": 3010,
            "name": "Audio/MP3",
            "order": 0,
            "hint": "(3010)",
            "parentValue": 3000
          },
          {
            "value": 3020,
            "name": "Audio/Video",
            "order": 0,
            "hint": "(3020)",
            "parentValue": 3000
          },
          {
            "value": 3030,
            "name": "Audio/Audiobook",
            "order": 0,
            "hint": "(3030)",
            "parentValue": 3000
          },
          {
            "value": 3040,
            "name": "Audio/Lossless",
            "order": 0,
            "hint": "(3040)",
            "parentValue": 3000
          },
          {
            "value": 3050,
            "name": "Audio/Other",
            "order": 0,
            "hint": "(3050)",
            "parentValue": 3000
          },
          {
            "value": 3060,
            "name": "Audio/Foreign",
            "order": 0,
            "hint": "(3060)",
            "parentValue": 3000
          },
          {
            "value": 4000,
            "name": "PC",
            "order": 0,
            "hint": "(4000)"
          },
          {
            "value": 4010,
            "name": "PC/0day",
            "order": 0,
            "hint": "(4010)",
            "parentValue": 4000
          },
          {
            "value": 4020,
            "name": "PC/ISO",
            "order": 0,
            "hint": "(4020)",
            "parentValue": 4000
          },
          {
            "value": 4030,
            "name": "PC/Mac",
            "order": 0,
            "hint": "(4030)",
            "parentValue": 4000
          },
          {
            "value": 4040,
            "name": "PC/Mobile-Other",
            "order": 0,
            "hint": "(4040)",
            "parentValue": 4000
          },
          {
            "value": 4050,
            "name": "PC/Games",
            "order": 0,
            "hint": "(4050)",
            "parentValue": 4000
          },
          {
            "value": 4060,
            "name": "PC/Mobile-iOS",
            "order": 0,
            "hint": "(4060)",
            "parentValue": 4000
          },
          {
            "value": 4070,
            "name": "PC/Mobile-Android",
            "order": 0,
            "hint": "(4070)",
            "parentValue": 4000
          },
          {
            "value": 5000,
            "name": "TV",
            "order": 0,
            "hint": "(5000)"
          },
          {
            "value": 5010,
            "name": "TV/WEB-DL",
            "order": 0,
            "hint": "(5010)",
            "parentValue": 5000
          },
          {
            "value": 5020,
            "name": "TV/Foreign",
            "order": 0,
            "hint": "(5020)",
            "parentValue": 5000
          },
          {
            "value": 5030,
            "name": "TV/SD",
            "order": 0,
            "hint": "(5030)",
            "parentValue": 5000
          },
          {
            "value": 5040,
            "name": "TV/HD",
            "order": 0,
            "hint": "(5040)",
            "parentValue": 5000
          },
          {
            "value": 5045,
            "name": "TV/UHD",
            "order": 0,
            "hint": "(5045)",
            "parentValue": 5000
          },
          {
            "value": 5050,
            "name": "TV/Other",
            "order": 0,
            "hint": "(5050)",
            "parentValue": 5000
          },
          {
            "value": 5060,
            "name": "TV/Sport",
            "order": 0,
            "hint": "(5060)",
            "parentValue": 5000
          },
          {
            "value": 5070,
            "name": "TV/Anime",
            "order": 0,
            "hint": "(5070)",
            "parentValue": 5000
          },
          {
            "value": 5080,
            "name": "TV/Documentary",
            "order": 0,
            "hint": "(5080)",
            "parentValue": 5000
          },
          {
            "value": 5090,
            "name": "TV/x265",
            "order": 0,
            "hint": "(5090)",
            "parentValue": 5000
          },
          {
            "value": 6000,
            "name": "XXX",
            "order": 0,
            "hint": "(6000)"
          },
          {
            "value": 6010,
            "name": "XXX/DVD",
            "order": 0,
            "hint": "(6010)",
            "parentValue": 6000
          },
          {
            "value": 6020,
            "name": "XXX/WMV",
            "order": 0,
            "hint": "(6020)",
            "parentValue": 6000
          },
          {
            "value": 6030,
            "name": "XXX/XviD",
            "order": 0,
            "hint": "(6030)",
            "parentValue": 6000
          },
          {
            "value": 6040,
            "name": "XXX/x264",
            "order": 0,
            "hint": "(6040)",
            "parentValue": 6000
          },
          {
            "value": 6045,
            "name": "XXX/UHD",
            "order": 0,
            "hint": "(6045)",
            "parentValue": 6000
          },
          {
            "value": 6050,
            "name": "XXX/Pack",
            "order": 0,
            "hint": "(6050)",
            "parentValue": 6000
          },
          {
            "value": 6060,
            "name": "XXX/ImageSet",
            "order": 0,
            "hint": "(6060)",
            "parentValue": 6000
          },
          {
            "value": 6070,
            "name": "XXX/Other",
            "order": 0,
            "hint": "(6070)",
            "parentValue": 6000
          },
          {
            "value": 6080,
            "name": "XXX/SD",
            "order": 0,
            "hint": "(6080)",
            "parentValue": 6000
          },
          {
            "value": 6090,
            "name": "XXX/WEB-DL",
            "order": 0,
            "hint": "(6090)",
            "parentValue": 6000
          },
          {
            "value": 7000,
            "name": "Books",
            "order": 0,
            "hint": "(7000)"
          },
          {
            "value": 7010,
            "name": "Books/Mags",
            "order": 0,
            "hint": "(7010)",
            "parentValue": 7000
          },
          {
            "value": 7020,
            "name": "Books/EBook",
            "order": 0,
            "hint": "(7020)",
            "parentValue": 7000
          },
          {
            "value": 7030,
            "name": "Books/Comics",
            "order": 0,
            "hint": "(7030)",
            "parentValue": 7000
          },
          {
            "value": 7040,
            "name": "Books/Technical",
            "order": 0,
            "hint": "(7040)",
            "parentValue": 7000
          },
          {
            "value": 7050,
            "name": "Books/Other",
            "order": 0,
            "hint": "(7050)",
            "parentValue": 7000
          },
          {
            "value": 7060,
            "name": "Books/Foreign",
            "order": 0,
            "hint": "(7060)",
            "parentValue": 7000
          },
          {
            "value": 8000,
            "name": "Other",
            "order": 0,
            "hint": "(8000)"
          },
          {
            "value": 8010,
            "name": "Other/Misc",
            "order": 0,
            "hint": "(8010)",
            "parentValue": 8000
          },
          {
            "value": 8020,
            "name": "Other/Hashed",
            "order": 0,
            "hint": "(8020)",
            "parentValue": 8000
          }
        ],
        "isFloat": false
      },
      {
        "order": 5,
        "name": "syncAnimeStandardFormatSearch",
        "label": "Sync Anime Standard Format Search",
        "helpText": "Sync also searching for anime using the standard numbering",
        "value": false,
        "type": "checkbox",
        "advanced": true,
        "isFloat": false
      }
    ],
    "implementationName": "Sonarr",
    "implementation": "Sonarr",
    "configContract": "SonarrSettings",
    "infoLink": "https://wiki.servarr.com/prowlarr/supported#sonarr",
    "tags": [],
    "id": 2
  }
]

Add Buildarr v0.7.0 support

Incompatible changes:

  • state.secrets has been replaced with state.instance_secrets (type Mapping[str, Mapping[str, SecretsPlugin])

Tag v0.2.0

Checklist:

  1. Set milestone to v0.2.0
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.1.1..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #12
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/4711619090
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/4711624398
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.1.1

Checklist:

  1. Set milestone to v0.1.1
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.1.0..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #6
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/4644718992
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/4644736864
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Error While Trying To Access Existing Prowlarr Config

Hi! Nifty tool ๐Ÿ˜„. Always seemed odd to me that all the Arr tools were so click-ops centric. I'm looking to integrate it into my stack.

While I was trying to onboard buildarr-prowlarr, I ran into this issue any time the plugin was trying to download the existing Prowlarr config:

2023-10-18 15:13:06,493 buildarr:1 buildarr.cli.run [INFO] <prowlarr> (prowlarr) Fetching remote configuration to check if updates are required
Traceback (most recent call last):
  File "/usr/local/bin/buildarr", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 568, in daemon
    ).start()
      ^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 113, in start
    self._initial_run()
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/daemon.py", line 226, in _initial_run
    run_apply(secrets_file_path=self._secrets_file_path)
  File "/usr/local/lib/python3.11/site-packages/buildarr/cli/run.py", line 287, in _run
    remote_instance_config = manager.from_remote(instance_config, instance_secrets)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/manager/__init__.py", line 171, in from_remote
    return instance_config.from_remote(secrets)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/__init__.py", line 157, in from_remote
    settings=ProwlarrSettings.from_remote(secrets),
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 85, in from_remote
    fields[field_name] = field.type_.from_remote(secrets)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr/config/base.py", line 85, in from_remote
    fields[field_name] = field.type_.from_remote(secrets)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/indexers/indexers.py", line 654, in from_remote
    definitions[indexer.name] = Indexer._from_remote(
                                ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/buildarr_prowlarr/config/settings/indexers/indexers.py", line 280, in _from_remote
    value: Any = remote_attrs["indexerUrls"][field["value"]]
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
TypeError: list indices must be integers or slices, not str

A few items of note:

  1. This still happens even if I run the dump-config command
  2. The only configuration in my Prowlarr instance is a single indexer (OPS)
  3. I am pulling the latest version of both Prowlarr and Buildarr

Here is my builder.yml that I was trying to startup with, but I don't think the configuration affects anything since I don't think buildarr got past downloading the remote config from prowlarr. Figured I'd send it just in case:

buildarr:
  watch_config: true
  update_days:
    - "monday"
    - "tuesday"
    - "wednesday"
    - "thursday"
    - "friday"
    - "saturday"
    - "sunday"
  update_times:
    - "03:00"

prowlarr:
  # Configuration common to all prowlarr instances can be defined here.
  # settings:
  #   ...
  instances:
    # Name of the instance as referred to by prowlarr.
    # Assign instance-specific configuration to it.
    prowlarr:
      host: "host.docker.internal"
      port: 9696
      protocol: "http"
      api_key: "<redacted>"

Happy to provide any additional details or help debug. Thanks again for making this tool

Update plugin to newer Buildarr API standards

  • Move all resource deletion processing to the delete_remote stage
  • Remove all usage of BaseIntEnum
  • Get request_timeout from global state
  • Remove explicit definitions of validate_assignment

Create initial plugin

Create the Buildarr plugin for configuring and managing the Prowlarr indexer manager.

  • Use prowlarr-py to create API-compatible objects and communicate with Prowlarr instances, if possible
    • Fallback: Make direct requests to the Prowlarr API, like the Sonarr plugin does
  • Like Sonarr V4, Prowlarr is planning to enable authentication by default for the V1 release, so consider how that can be handled

Tag v0.1.0

Checklist:

  1. Set milestone to v0.1.0
  2. Get the raw changelog
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #2
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/4641942527
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://pypi.org/project/buildarr-prowlarr/0.1.0 (manually published)
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Set minimum Buildarr version to v0.6.1

The Prowlarr plugin requires Buildarr v0.6.1 when using email notification connections, due to that version containing built-in parsing support for NameEmail type attributes.

It otherwise works fine on v0.6.0, however, and on new Python installations v0.6.1 will be installed, so it is not as urgent an issue.

Tag v0.5.1

Checklist:

  1. Set milestone to v0.5.1
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.5.0..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #56
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/7066342294
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/7066347476
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.4.0

Checklist:

  1. Set milestone to v0.4.0
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.3.1..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #30
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6757385046
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6757393069
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.4.3

Checklist:

  1. Set milestone to v0.4.3
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.4.2..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #46
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6782156880
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6782168208
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Tag v0.4.2

Checklist:

  1. Set milestone to v0.4.2
  2. Get the raw changelog using the following command:
    $ git log --oneline --decorate v0.4.1..HEAD
  3. Update the tool.poetry.version field in pyproject.toml
  4. Add release notes to docs/release-notes.md
  5. Create pull request: #42
  6. Merge pull request
  7. Check that the CI pipeline passed on main: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6777982330
  8. Tag the new release
  9. Check that the release was automatically published to PyPI: https://github.com/buildarr/buildarr-prowlarr/actions/runs/6777989786
  10. Push an update to http://github.com/buildarr/buildarr-docker to release to Docker Hub
  11. Push an update to https://buildarr.github.io
  12. Close release milestone
  13. Create new release milestone
  14. Close this issue

Add support for dry runs

At the moment, the Prowlarr plugin does not handle dry runs, and carries on as it normally would.

We need to add support for this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.