Skip to content

Commit

Permalink
fix(daemon): Broken handling of empty/None keys
Browse files Browse the repository at this point in the history
  • Loading branch information
rpatterson committed Oct 30, 2023
1 parent 6c4c7e7 commit b42d3d2
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 7 deletions.
18 changes: 18 additions & 0 deletions newsfragments/+config-empty-keys.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Fix handling of empty top-level keys in the configuration file::

DEBUG:prunerr.runner:Sub-command `exec` completed in 89.50181317329407s
Traceback (most recent call last):
File "/usr/local/bin/prunerr", line 8, in <module>
sys.exit(main())
^^^^^^
File "/usr/local/lib/python3.11/site-packages/prunerr/__init__.py", line 241, in main
_main(args=args)
File "/usr/local/lib/python3.11/site-packages/prunerr/__init__.py", line 288, in _main
if (result := parsed_args.command(runner, **command_kwargs)) is not None:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/prunerr/__init__.py", line 181, in daemon
runner.daemon(*args, **kwargs)
File "/usr/local/lib/python3.11/site-packages/prunerr/runner.py", line 337, in daemon
poll = self.config.get("daemon", {}).get("poll", 60)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'
18 changes: 14 additions & 4 deletions src/prunerr/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ def validate(self) -> dict:
with self.config_file.open(encoding="utf-8") as config_opened:
self.config = yaml.safe_load(config_opened)

# Avoid issues with empty keys having a `None` value in YAML:
for top_key in self.example_confg.keys():
if top_key in self.config and self.config[top_key] is None:
logger.debug(
"Top-level configuration key is empty: %s",
top_key,
)
self.config[top_key] = {}

# Raise helpful errors for required values:
if not self.config.get("download-clients", {}).get("urls"):
raise PrunerrValidationError(
Expand All @@ -81,6 +90,10 @@ def validate(self) -> dict:
"min-download-time-margin",
self.example_confg["download-clients"]["min-download-time-margin"],
)
self.config.setdefault("daemon", {}).setdefault(
"poll",
self.example_confg["daemon"]["poll"],
)

return self.config

Expand Down Expand Up @@ -356,10 +369,7 @@ def daemon(self):
logger.debug("Sub-command `exec` completed in %ss", time.time() - start)

# Determine the poll interval before clearing the config
poll = self.config.get("daemon", {}).get(
"poll",
self.example_confg["daemon"]["poll"],
)
poll = self.config["daemon"]["poll"]

# Free any memory possible between daemon loops
self.clear()
Expand Down
11 changes: 11 additions & 0 deletions src/prunerr/tests/home/daemon/.config/prunerr-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2023 Ross Patterson <me@rpatterson.net>
#
# SPDX-License-Identifier: MIT

daemon:
poll: 1
servarrs:
download-clients:
max-download-bandwidth: 100
min-download-time-margin: 3600
indexers:
2 changes: 0 additions & 2 deletions src/prunerr/tests/home/daemon/.config/prunerr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
# SPDX-License-Identifier: MIT

daemon:
# Cover the `time.sleep(1)` part of the `daemon` loop.
poll: 1
servarrs:
Sonarr:
url: "http://localhost:8989"
Expand Down
6 changes: 5 additions & 1 deletion src/prunerr/tests/test_daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from unittest import mock

import prunerr.downloadclient
import prunerr

from .. import tests

Expand Down Expand Up @@ -64,6 +64,10 @@ def mock_exit_daemon_response(


@mock.patch.dict(os.environ, ENV)
@mock.patch(
"prunerr.runner.PrunerrRunner.EXAMPLE_CONFIG",
HOME / ".config" / "prunerr-example.yml",
)
class PrunerrDaemonTests(tests.PrunerrTestCase):
"""
Tests covering the Prunerr `daemon` sub-command.
Expand Down

0 comments on commit b42d3d2

Please sign in to comment.