Closed JWWolstenholme closed 1 month ago
This one is a gray area. While an empty file is indeed a valid TOML, it is not a valid remap rules file (today). We require that there be at least an empty [[rules]]
section.
But I agree that this is a pretty arbitrary restriction since we allow empty rules
anyway. Fixed in latest commit.
Describe the bug
If you have created a
remap_rules.toml
file and you leave it completely blank or full of exclusively commented lines, vlc scrobbling will no longer work andtrakts init
will error. Probably other errors as well.According to this issue, an empty toml file is still valid.
Desktop (please complete the following information):
Windows 11 Pro 23H2 22631.3880
3.12.4
VLC 3.0.20
1.7.0-beta.1
To Reproduce
Steps to reproduce the behavior:
remap_rules.toml
file (or comment all lines).trakts start --restart
trakts init
ortrakts test vlc -vvv
Console output
Click to see console output
``` C:\Users\redacted>trakts init This will guide you through the setup of the scrobbler. If you wish to quit at any point, press Ctrl+C or Cmd+C ValidationError 1 validation error for RemapFile rules Field required [type=missing, input_value={}, input_type=dict] For further information visit https://errors.pydantic.dev/2.8/v/missing at pipx\venvs\trakt-scrobbler\Lib\site-packages\pydantic\main.py:568 in model_validate 564│ The validated model instance. 565│ """ 566│ # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks 567│ __tracebackhide__ = True → 568│ return cls.__pydantic_validator__.validate_python( 569│ obj, strict=strict, from_attributes=from_attributes, context=context 570│ ) 571│ 572│ @classmethod C:\Users\redacted>trakts test vlc -vvv Stack trace: 12 pipx\venvs\trakt-scrobbler\Lib\site-packages\clikit\console_application.py:131 in run 129│ parsed_args = resolved_command.args 130│ → 131│ status_code = command.handle(parsed_args, io) 132│ except KeyboardInterrupt: 133│ status_code = 1 11 pipx\venvs\trakt-scrobbler\Lib\site-packages\clikit\api\command\command.py:120 in handle 118│ def handle(self, args, io): # type: (Args, IO) -> int 119│ try: → 120│ status_code = self._do_handle(args, io) 121│ except KeyboardInterrupt: 122│ if io.is_debug(): 10 pipx\venvs\trakt-scrobbler\Lib\site-packages\clikit\api\command\command.py:171 in _do_handle 169│ handler_method = self._config.handler_method 170│ → 171│ return getattr(handler, handler_method)(args, io, self) 172│ 173│ def __repr__(self): # type: () -> str 9 pipx\venvs\trakt-scrobbler\Lib\site-packages\cleo\commands\command.py:92 in wrap_handle 90│ self._command = command 91│ → 92│ return self.handle() 93│ 94│ def handle(self): # type: () -> Optional[int] 8 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\commands\test.py:112 in handle 110│ def handle(self): 111│ try: → 112│ return self._handle() 113│ except SystemExit as e: 114│ if not self.io.is_debug(): 7 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\commands\test.py:87 in _handle 85│ def _handle(self): 86│ name = self.argument("player") → 87│ Mon = self.get_monitor(name) 88│ 89│ self.add_log_handler() 6 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\commands\test.py:20 in get_monitor 18│ import confuse 19│ from trakt_scrobbler import config → 20│ from trakt_scrobbler.player_monitors import collect_monitors 21│ all_monitors = collect_monitors() 22│ monitors = {Mon.name: Mon for Mon in all_monitors if isinstance(Mon.name, str)} 5 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\player_monitors\__init__.py:4 in
2│ from pathlib import Path
3│ from importlib import import_module
→ 4│ from .monitor import Monitor
5│
6│
4 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\player_monitors\monitor.py:8 in
6│ import requests
7│ from trakt_scrobbler import config, logger
→ 8│ from trakt_scrobbler.file_info import get_media_info
9│ from trakt_scrobbler.notifier import notify
10│ from trakt_scrobbler.utils import AutoloadError, ResumableTimer
3 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\file_info.py:9 in
7│ import guessit
8│ from trakt_scrobbler import config, logger
→ 9│ from trakt_scrobbler.mediainfo_remap import apply_remap_rules
10│ from trakt_scrobbler.utils import RegexPat, cleanup_encoding, is_url
11│ from urlmatch import BadMatchPattern, urlmatch
2 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\mediainfo_remap.py:301 in
299│
300│
→ 301│ rules = read_file(REMAP_FILE_PATH)
302│ if rules:
303│ logger.debug(f"Read {len(rules)} remap {pluralize(len(rules), 'rule')} from {REMAP_FILE_PATH}")
1 pipx\venvs\trakt-scrobbler\Lib\site-packages\trakt_scrobbler\mediainfo_remap.py:298 in read_file
296│ logger.exception(f"Invalid TOML in remap_rules file at {file}. Ignoring.")
297│ return []
→ 298│ return RemapFile.model_validate(data).rules
299│
300│
ValidationError
1 validation error for RemapFile
rules
Field required [type=missing, input_value={}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.8/v/missing
at pipx\venvs\trakt-scrobbler\Lib\site-packages\pydantic\main.py:568 in model_validate
564│ The validated model instance.
565│ """
566│ # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks
567│ __tracebackhide__ = True
→ 568│ return cls.__pydantic_validator__.validate_python(
569│ obj, strict=strict, from_attributes=from_attributes, context=context
570│ )
571│
572│ @classmethod
```