artemis_framework 0.2.2__tar.gz → 0.3.0__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 (25) hide show
  1. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/PKG-INFO +2 -1
  2. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/gpg_context.py +7 -0
  3. artemis_framework-0.3.0/artemis_framework/asphodel/tui/modals/__init__.py +0 -0
  4. artemis_framework-0.3.0/artemis_framework/asphodel/tui/screens/__init__.py +0 -0
  5. artemis_framework-0.3.0/artemis_framework/asphodel/tui/settings.py +129 -0
  6. artemis_framework-0.3.0/artemis_framework/asphodel/tui/widgets/__init__.py +0 -0
  7. artemis_framework-0.3.0/artemis_framework/elysium/__ini +0 -0
  8. artemis_framework-0.3.0/artemis_framework/elysium/__init__.py +0 -0
  9. artemis_framework-0.3.0/artemis_framework/tartarus/__init__.py +0 -0
  10. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/pyproject.toml +2 -1
  11. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/LICENSE +0 -0
  12. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/README.md +0 -0
  13. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/__init__.py +0 -0
  14. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/__main__.py +0 -0
  15. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/__init__.py +0 -0
  16. /artemis_framework-0.2.2/artemis_framework/elysium/__ini → /artemis_framework-0.3.0/artemis_framework/asphodel/__main__.py +0 -0
  17. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/__init__.py +0 -0
  18. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/_gpg_binary.py +0 -0
  19. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/armor_binary.py +0 -0
  20. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/encrypt_decrypt.py +0 -0
  21. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/key_management.py +0 -0
  22. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/macos_shim.py +0 -0
  23. {artemis_framework-0.2.2 → artemis_framework-0.3.0}/artemis_framework/asphodel/core/sign_verify.py +0 -0
  24. {artemis_framework-0.2.2/artemis_framework/elysium → artemis_framework-0.3.0/artemis_framework/asphodel/tui}/__init__.py +0 -0
  25. /artemis_framework-0.2.2/artemis_framework/tartarus/__init__.py → /artemis_framework-0.3.0/artemis_framework/asphodel/tui/app.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: artemis_framework
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: A package for doing great things!
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -10,6 +10,7 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.13
12
12
  Classifier: Programming Language :: Python :: 3.14
13
+ Requires-Dist: python-gnupg (>=0.5.6,<0.6.0)
13
14
  Description-Content-Type: text/markdown
14
15
 
15
16
  # artemis_framework
@@ -28,6 +28,13 @@ def build_gpg(
28
28
  raise RuntimeError(f"Cannot create GNUPGHOME at {home}: {exc}") from exc
29
29
 
30
30
  try:
31
+ # gpg = gnupg.GPG(
32
+ # gnupghome=str(home),
33
+ # gpgbinary=binary,
34
+ # verbose=verbose,
35
+ # use_agent=use_agent,
36
+ # options=options or []
37
+ # )
31
38
  gpg = gnupg.GPG(
32
39
  gnupghome=str(home),
33
40
  gpgbinary=binary,
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ import tempfile
6
+ from dataclasses import asdict, dataclass, field
7
+ from pathlib import Path
8
+
9
+
10
+ def _config_dir() -> Path:
11
+ if os.name == "nt":
12
+ base = Path(os.environ.get("APPDATA", Path.home()))
13
+ else:
14
+ base = Path(os.environ.get("XDG_CONFIG_HOME", Path.hom() / ".config"))
15
+ return base / "artemis-framework" / "asphodel"
16
+
17
+
18
+ CONFIG_FILE = _config_dir() / "settings.json"
19
+
20
+
21
+ _DEFAULT_GNUPGHOME: str = ""
22
+ _DEFAULT_GPG_BINARY: str = "gpg"
23
+ _DEFAULT_ALGORITHM: str = "rsa"
24
+ _DEFAULT_EXPIRE: str = "2y"
25
+ _DEFAULT_KEYSERVER_URL: str = "https://keys.openpgp.org"
26
+ _DEFAULT_PASSPHRASE_CACHE: bool = False
27
+
28
+
29
+ @dataclass
30
+ class AppSettings:
31
+ gnupghome: str = field(default=_DEFAULT_GNUPGHOME)
32
+ gpg_binary: str = field(default=_DEFAULT_GPG_BINARY)
33
+ algorithm: str = field(default=_DEFAULT_ALGORITHM)
34
+ expire: str = field(default=_DEFAULT_EXPIRE)
35
+ keyserver_url: str = field(default=_DEFAULT_KEYSERVER_URL)
36
+ passphrase_cache_enabled: bool = field(default=_DEFAULT_PASSPHRASE_CACHE)
37
+
38
+ def gnupghome_path(self) -> Path | None:
39
+ if not self.gnupghome.strip():
40
+ return None
41
+ return Path(self.gnupghome).expanduser().resolve()
42
+
43
+ def gpg_binary_resolved(self) -> str:
44
+ return self.gpg_binary.strip() or _DEFAULT_GPG_BINARY
45
+
46
+ def keyserver_url_resolved(self) -> str:
47
+ url = self.keyserver_url.strip()
48
+ return url if url else _DEFAULT_KEYSERVER_URL
49
+
50
+ def build_gpg(self):
51
+ from artemis_framework.asphodel.core import build_gpg as _build_gpg
52
+ return _build_gpg(
53
+ gnupghome=self.gnupghome_path(),
54
+ binary=self.gpg_binary_resolved()
55
+ )
56
+
57
+ def validate_gnupghome(self) -> tuple[bool, str]:
58
+ if not self.gnupghome.strip():
59
+ return True, "Use asphodel-pgp default (test keyring)"
60
+ p = Path(self.gnupghome).expanduser()
61
+ if p.exists():
62
+ if p.is_dir():
63
+ return True, str(p.resolve())
64
+ return False, f"Path exists but is not a directory: {p}"
65
+ return True, f"Will be created: {p.resolve()}"
66
+
67
+ def validate_gpg_binary(self) -> tuple[bool, str]:
68
+ import shutil
69
+ binary = self.gpg_binary_resolved()
70
+ found = shutil.which(binary)
71
+ if found:
72
+ return True, found
73
+ p = Path(binary)
74
+ if p.exists() and os.access(p, os.X_OK):
75
+ return True, str(p.resolve())
76
+
77
+ return False, f"'{binary}' not found on PATH"
78
+
79
+ def validate_keyserver_url(self) -> tuple[bool, str]:
80
+ url = self.keyserver_url_resolved()
81
+ if url.startswith("https://") or url.startswith("http://"):
82
+ return True, url
83
+ return False, f"URL must start with https:// -or- http:// (got: '{url}')"
84
+
85
+
86
+ def load_settings() -> AppSettings:
87
+ if not CONFIG_FILE.exists():
88
+ return AppSettings()
89
+
90
+ try:
91
+ raw = json.loads(CONFIG_FILE.read_text(encoding="utf-8"))
92
+ except (json.JSONDecodeError, OSError):
93
+ return AppSettings()
94
+
95
+ return AppSettings(
96
+ gnupghome=raw.get("gnupghome", _DEFAULT_GNUPGHOME),
97
+ gpg_binary=raw.get("gpg_binary", _DEFAULT_GPG_BINARY),
98
+ algorithm=raw.get("algorithm", _DEFAULT_ALGORITHM),
99
+ expire=raw.get("expire", _DEFAULT_EXPIRE),
100
+ keyserver_url=raw.get("keyserver_url", _DEFAULT_KEYSERVER_URL),
101
+ passphrase_cache_enabled=bool(
102
+ raw.get("passphrase_cache_enabled", _DEFAULT_PASSPHRASE_CACHE)
103
+ )
104
+ )
105
+
106
+
107
+ def save_settings(cfg: AppSettings) -> bool:
108
+ try:
109
+ CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
110
+ payload = json.dumps(asdict(cfg), indent=2, ensure_ascii=False)
111
+
112
+ fd, tmp_path = tempfile.mkstemp(
113
+ dir=CONFIG_FILE.parent,
114
+ prefix=".settings_tmp_",
115
+ suffix=".json"
116
+ )
117
+ try:
118
+ with os.fdopen(fd, "w", encoding="utf-8") as file:
119
+ file.write(payload)
120
+ Path(tmp_path).replace(CONFIG_FILE)
121
+ except Exception:
122
+ try:
123
+ os.unlink(tmp_path)
124
+ except OSError:
125
+ pass
126
+ raise
127
+ return True
128
+ except OSError:
129
+ return False
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "artemis_framework"
3
- version = "0.2.2"
3
+ version = "0.3.0"
4
4
  description = "A package for doing great things!"
5
5
  authors = ["Dylan Garrett"]
6
6
  license = "MIT"
@@ -8,6 +8,7 @@ readme = "README.md"
8
8
 
9
9
  [tool.poetry.dependencies]
10
10
  python = "^3.13"
11
+ python-gnupg = "^0.5.6"
11
12
 
12
13
 
13
14
  [build-system]