updates2mqtt 1.3.4__tar.gz → 1.3.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.github/workflows/pypi-publish.yml +1 -1
  2. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/PKG-INFO +9 -4
  3. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/README.md +8 -3
  4. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/pyproject.toml +1 -1
  5. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/app.py +2 -1
  6. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/config.py +18 -10
  7. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/tests/test_config.py +1 -1
  8. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/uv.lock +1 -1
  9. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.dockerignore +0 -0
  10. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.github/dependabot.yml +0 -0
  11. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.github/workflows/docker-publish.yml +0 -0
  12. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.github/workflows/python-package.yml +0 -0
  13. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.gitignore +0 -0
  14. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.hintrc +0 -0
  15. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.pre-commit-config.yaml +0 -0
  16. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.python-version +0 -0
  17. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/.safety-project.ini +0 -0
  18. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/Dockerfile +0 -0
  19. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/LICENSE +0 -0
  20. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/SECURITY.md +0 -0
  21. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/common_packages.yaml +0 -0
  22. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/conftest.py +0 -0
  23. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/docs/images/ha_mqtt_discovery.png +0 -0
  24. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/docs/images/ha_update_detail.png +0 -0
  25. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/docs/images/ha_update_page.png +0 -0
  26. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/docs/index.md +0 -0
  27. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/examples/config.yaml.maximal +0 -0
  28. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/examples/config.yaml.minimal +0 -0
  29. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/examples/docker-compose.yaml +0 -0
  30. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/mkdocs.yml +0 -0
  31. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/refresh-deps.sh +0 -0
  32. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/scripts/healthcheck.sh +0 -0
  33. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/__init__.py +0 -0
  34. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/__main__.py +0 -0
  35. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/hass_formatter.py +0 -0
  36. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/integrations/__init__.py +0 -0
  37. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/integrations/docker.py +0 -0
  38. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/integrations/git_utils.py +0 -0
  39. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/model.py +0 -0
  40. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/mqtt.py +0 -0
  41. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/src/updates2mqtt/py.typed +0 -0
  42. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/tests/__init__.py +0 -0
  43. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/tests/test_docker.py +0 -0
  44. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/tests/test_git_utils.py +0 -0
  45. {updates2mqtt-1.3.4 → updates2mqtt-1.3.5}/tests/test_mqtt.py +0 -0
@@ -30,7 +30,7 @@ jobs:
30
30
  publish-to-pypi:
31
31
  name: >-
32
32
  Publish Python 🐍 distribution 📦 to PyPI
33
- #if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
33
+ if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
34
34
  needs:
35
35
  - build
36
36
  runs-on: ubuntu-latest
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: updates2mqtt
3
- Version: 1.3.4
3
+ Version: 1.3.5
4
4
  Summary: System update and docker image notification and execution over MQTT
5
5
  Project-URL: Repository, https://github.com/rhizomatics/updates2mqtt
6
6
  Project-URL: Documentation, https://updates2mqtt.rhizomatics.org.uk
@@ -65,10 +65,15 @@ button in the HomeAssistant update dialog. Icons and release notes can be specif
65
65
 
66
66
  updates2mqtt prefers to be run inside a Docker container.
67
67
 
68
- ### Manual
68
+ ### Manual - Run without installing using uv
69
69
  ```
70
- uv sync
71
- uv run updates2mqtt
70
+ uv run --with updates2mqtt updates2mqtt
71
+ ```
72
+
73
+ ### Manual - Install and run with pip
74
+ ```
75
+ pip install updates2mqtt
76
+ python3 -m updates2mqtt
72
77
  ```
73
78
  ### Docker
74
79
 
@@ -30,10 +30,15 @@ button in the HomeAssistant update dialog. Icons and release notes can be specif
30
30
 
31
31
  updates2mqtt prefers to be run inside a Docker container.
32
32
 
33
- ### Manual
33
+ ### Manual - Run without installing using uv
34
34
  ```
35
- uv sync
36
- uv run updates2mqtt
35
+ uv run --with updates2mqtt updates2mqtt
36
+ ```
37
+
38
+ ### Manual - Install and run with pip
39
+ ```
40
+ pip install updates2mqtt
41
+ python3 -m updates2mqtt
37
42
  ```
38
43
  ### Docker
39
44
 
@@ -7,7 +7,7 @@ authors = [
7
7
  ]
8
8
 
9
9
  requires-python = ">=3.13"
10
- version = "1.3.4"
10
+ version = "1.3.5"
11
11
  license="Apache-2.0"
12
12
  keywords=["mqtt", "docker", "updates", "automation","home-assistant","homeassistant","selfhosting"]
13
13
 
@@ -39,7 +39,8 @@ class App:
39
39
  self.last_scan_timestamp: str | None = None
40
40
  app_config: Config | None = load_app_config(CONF_FILE)
41
41
  if app_config is None:
42
- log.error(f"Invalid configuration at {CONF_FILE}, exiting")
42
+ log.error(f"Invalid configuration at {CONF_FILE}, edit config to fix missing or invalid values and restart")
43
+ log.error("Exiting app")
43
44
  sys.exit(1)
44
45
  self.cfg: Config = app_config
45
46
 
@@ -96,6 +96,10 @@ class UpdateInfoConfig:
96
96
  common_packages: dict[str, PackageUpdateInfo] = field(default_factory=lambda: {})
97
97
 
98
98
 
99
+ class IncompleteConfigException(BaseException):
100
+ pass
101
+
102
+
99
103
  def load_package_info(pkginfo_file_path: Path) -> UpdateInfoConfig:
100
104
  if pkginfo_file_path.exists():
101
105
  log.debug("Loading common package update info", path=pkginfo_file_path)
@@ -107,29 +111,33 @@ def load_package_info(pkginfo_file_path: Path) -> UpdateInfoConfig:
107
111
  return typing.cast("UpdateInfoConfig", cfg)
108
112
 
109
113
 
110
- def load_app_config(conf_file_path: Path) -> Config | None:
111
- initializing: bool = False
114
+ def load_app_config(conf_file_path: Path, return_new: bool = False) -> Config | None:
112
115
  base_cfg = OmegaConf.structured(Config)
113
116
  if conf_file_path.exists():
114
117
  cfg = OmegaConf.merge(base_cfg, OmegaConf.load(conf_file_path))
115
118
  else:
116
- initializing = True
117
- try:
118
- log.debug("Creating config directory if not already present", path=conf_file_path)
119
- conf_file_path.parent.mkdir(parents=True, exist_ok=True)
120
- except Exception:
121
- log.exception("Unable to create config directory", path=conf_file_path.parent)
119
+ if not conf_file_path.parent.exists():
120
+ try:
121
+ log.debug(f"Creating config directory {conf_file_path.parent} if not already present")
122
+ conf_file_path.parent.mkdir(parents=True, exist_ok=True)
123
+ except Exception:
124
+ log.exception("Unable to create config directory", path=conf_file_path.parent)
122
125
  try:
123
126
  conf_file_path.write_text(OmegaConf.to_yaml(base_cfg))
127
+ log.info(f"Auto-generated a new config file at {conf_file_path}")
128
+ log.info("The config has place holders for MQTT user and password")
129
+ if return_new:
130
+ return base_cfg
131
+ return None
124
132
  except Exception:
125
133
  log.exception("Unable to write config file", path=conf_file_path)
126
134
  cfg = base_cfg
127
135
 
128
136
  try:
129
137
  # Validate that all required fields are present, throw exception now rather than when config first used
130
- OmegaConf.to_container(cfg, throw_on_missing=not initializing)
138
+ OmegaConf.to_container(cfg, throw_on_missing=True)
131
139
  OmegaConf.set_readonly(cfg, True)
132
140
  return typing.cast("Config", cfg)
133
141
  except (MissingMandatoryValue, ValidationError) as e:
134
- log.error("Configuration error: %s", e, path=conf_file_path)
142
+ log.error("Configuration error %s", e, path=conf_file_path.as_posix())
135
143
  return None
@@ -22,7 +22,7 @@ def test_config(config_name: str) -> None:
22
22
  def test_round_trip_config() -> None:
23
23
  with tempfile.TemporaryDirectory() as tmpdir:
24
24
  conf_path: Path = Path(tmpdir) / "config-test.yaml"
25
- generated_config = load_app_config(conf_path)
25
+ generated_config = load_app_config(conf_path, return_new=True)
26
26
  assert conf_path.exists()
27
27
  assert generated_config is not None
28
28
  # set mandatory values
@@ -988,7 +988,7 @@ wheels = [
988
988
 
989
989
  [[package]]
990
990
  name = "updates2mqtt"
991
- version = "1.3.4"
991
+ version = "1.3.5"
992
992
  source = { editable = "." }
993
993
  dependencies = [
994
994
  { name = "docker" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes