Sonarr profile tags support in YAML config

The user may not specify tags to assign to each release profile type in
the YAML configuration file.

See the README.md for more information.
pull/5/head
Robert Dailey 3 years ago
parent cb44ab36cb
commit 545f1ac289

@ -2,6 +2,5 @@
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/wiki" vcs="Git" />
</component>
</project>

@ -104,14 +104,37 @@ API Key, which should make using the command line interface a bit less clunky.
sonarr:
base_uri: http://localhost:8989
api_key: a95cc792074644759fefe3ccab544f6e
profile:
- type: anime
tags:
- anime
- type: web-dl
tags:
- tv
```
Note that this file is not required to be present. If it is not present, then you will be required
to specify the `--base-uri` and `--api-key` on the command line if it is needed.
Note that this file is not required to be present. If it is not present, then you will need to set
respective parameters using the equivalent command line arguments (e.g. `--base-uri` and
`--api-key`), as needed.
Lastly, there's a `--config-file` argument you can use to point to your own YAML config file if you
don't like the where the default one is located.
### Profile Settings
* **`profile`**<br>
Provide a list of settings used per each type of release profile supported in the guide (e.g.
`web-dl`, `anime`).
* **`type`**<br>
Type profile type to apply the settings to, such as adding new tags. The list of supported
profile types can be found by doing `trash.py profile -h`. Each valid choice listed under the
`type` argument can be used, just strip the `sonarr:` prefix.
* **`tags`**<br>
A list of tags to apply to the profile. Functions exactly as it would if you used the `--tags`
option to provide this list on the command line.
## Important Notices
Please be aware that this script relies on a deterministic and consistent structure of the TRaSH

@ -4,17 +4,17 @@ from app.guide.profile import types as profile_types
from app.guide.quality import types as quality_types
# class args: pass
class NoAction(argparse.Action):
class _NoAction(argparse.Action):
def __init__(self, **kwargs):
kwargs.setdefault('default', argparse.SUPPRESS)
kwargs.setdefault('nargs', 0)
super(NoAction, self).__init__(**kwargs)
super(_NoAction, self).__init__(**kwargs)
def __call__(self, parser, namespace, values, option_string=None):
pass
def add_choices_argument(parser, variable_name, help_text, choices: dict):
parser.register('action', 'none', NoAction)
def _add_choices_argument(parser, variable_name, help_text, choices: dict):
parser.register('action', 'none', _NoAction)
parser.add_argument(variable_name, help=help_text, metavar=variable_name.upper(), choices=choices.keys())
group = parser.add_argument_group(title=f'Choices for {variable_name.upper()}')
for choice,choice_help in choices.items():
@ -36,7 +36,7 @@ def setup_and_parse_args(args_override=None):
# Subcommands for 'profile'
profile_p = subparsers.add_parser('profile', help='Pages of the guide that define profiles',
parents=[parent_p])
add_choices_argument(profile_p, 'type', 'The specific guide type/page to pull data from.',
_add_choices_argument(profile_p, 'type', 'The specific guide type/page to pull data from.',
{type: data.get('cmd_help') for type, data in profile_types.items()})
# })
profile_p.add_argument('--tags', help='Tags to assign to the profiles that are created or updated. These tags will replace any existing tags when updating profiles.',
@ -47,7 +47,7 @@ def setup_and_parse_args(args_override=None):
# Subcommands for 'quality'
quality_p = subparsers.add_parser('quality', help='Pages in the guide that provide quality definitions',
parents=[parent_p])
add_choices_argument(quality_p, 'type', 'The specific guide type/page to pull data from.',
_add_choices_argument(quality_p, 'type', 'The specific guide type/page to pull data from.',
{type: data.get('cmd_help') for type, data in quality_types.items()})
return parser.parse_args(args=args_override)

@ -0,0 +1,46 @@
from pathlib import Path
import yaml
# --------------------------------------------------------------------------------------------------
def find_profile_by_name(config, profile_type):
for profile in config['profile']:
if profile['type'] == profile_type:
return profile
return None
# --------------------------------------------------------------------------------------------------
def load_config(args, logger):
if args.config_file:
config_path = Path(args.config_file)
else:
# Look for `trash.yml` in the same directory as the main (entrypoint) python script.
config_path = Path(__name__).parent / 'trash.yml'
logger.debug(f'Using configuration file: {config_path}')
if config_path.exists():
with open(config_path, 'r') as f:
config_yaml = f.read()
load_config_string(args, logger, config_yaml)
else:
logger.debug('Config file could not be loaded because it does not exist')
# --------------------------------------------------------------------------------------------------
def load_config_string(args, logger, config_yaml):
config = yaml.load(config_yaml, Loader=yaml.Loader)
server_name, type_name = args.type.split(':')
server_config = config[server_name]
if not args.base_uri:
args.base_uri = server_config['base_uri']
if not args.api_key:
args.api_key = server_config['api_key']
if args.subcommand == 'profile':
profile = find_profile_by_name(server_config, type_name)
if profile:
if args.tags is None:
args.tags = []
args.tags.extend(t for t in profile['tags'] if t not in args.tags)

@ -0,0 +1,30 @@
from inspect import cleandoc
from app import cmd
from app.logic import config
from tests.mock_logger import MockLogger
def test_config_tags():
yaml = cleandoc('''
sonarr:
base_uri: http://localhost:8989
api_key: a95cc792074644759fefe3ccab544f6e
profile:
- type: anime
tags:
- anime
- type: web-dl
tags:
- tv
''')
args = cmd.setup_and_parse_args(['profile', 'sonarr:anime'])
config.load_config_string(args, MockLogger(), yaml)
assert args.base_uri == 'http://localhost:8989'
assert args.api_key == 'a95cc792074644759fefe3ccab544f6e'
assert args.tags == ['anime']
args = cmd.setup_and_parse_args(['profile', 'sonarr:web-dl'])
config.load_config_string(args, MockLogger(), yaml)
assert args.tags == ['tv']

@ -1,44 +1,15 @@
import requests
from pathlib import Path
import yaml
from app.logic import sonarr
from app.logic import sonarr, config
from app.cmd import setup_and_parse_args
from app.logger import Logger
from app.trash_error import TrashError
# --------------------------------------------------------------------------------------------------
def load_config(args, logger):
if args.config_file:
config_path = Path(args.config_file)
else:
# Look for `trash.yml` in the same directory as the python script.
config_path = Path(__name__).parent / 'trash.yml'
logger.debug(f'Using configuration file: {config_path}')
if config_path.exists():
config = None
with open(config_path, 'r') as f:
config = yaml.load(f, Loader=yaml.Loader)
# TODO: Determine whether to use sonarr or radarr configs?
sonarr_config = config['sonarr']
if not args.base_uri:
args.base_uri = sonarr_config['base_uri']
if not args.api_key:
args.api_key = sonarr_config['api_key']
else:
logger.debug('Config file could not be loaded because it does not exist')
# --------------------------------------------------------------------------------------------------
def main():
args = setup_and_parse_args()
logger = Logger(args)
load_config(args, logger)
config.load_config(args, logger)
if args.subcommand == 'profile':
if args.type.startswith('sonarr:'):

Loading…
Cancel
Save