basic-password-manager 0.2.3__tar.gz → 0.2.4__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 (17) hide show
  1. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/PKG-INFO +1 -1
  2. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/PKG-INFO +1 -1
  3. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/cli.py +3 -4
  4. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/logo.py +44 -2
  5. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/tui.py +12 -2
  6. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pyproject.toml +1 -1
  7. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/LICENSE +0 -0
  8. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/README.md +0 -0
  9. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/SOURCES.txt +0 -0
  10. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/dependency_links.txt +0 -0
  11. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/entry_points.txt +0 -0
  12. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/requires.txt +0 -0
  13. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/basic_password_manager.egg-info/top_level.txt +0 -0
  14. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/__init__.py +0 -0
  15. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/crypto.py +0 -0
  16. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/pw_manager/vault.py +0 -0
  17. {basic_password_manager-0.2.3 → basic_password_manager-0.2.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-password-manager
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: The Paladin — a local encrypted password manager that lives in your terminal
5
5
  License-Expression: MIT
6
6
  Project-URL: Repository, https://github.com/Daisentaur/password-manager
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-password-manager
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: The Paladin — a local encrypted password manager that lives in your terminal
5
5
  License-Expression: MIT
6
6
  Project-URL: Repository, https://github.com/Daisentaur/password-manager
@@ -62,11 +62,10 @@ def cmd_about(args):
62
62
  v = version("basic-password-manager")
63
63
  except PackageNotFoundError:
64
64
  v = "dev" # running from source without an install
65
- if sys.stdout.isatty():
66
- from . import logo
65
+ from . import logo
67
66
 
68
- print(logo.ansi())
69
- print(f"The Paladin v{v}")
67
+ print(logo.ascii_art())
68
+ print(f"The Paladin v{v}")
70
69
  print("your passwords, guarded locally — no browser, no cloud, no mercy")
71
70
  print("https://github.com/Daisentaur/password-manager")
72
71
 
@@ -62,11 +62,34 @@ def ansi(indent: str = "") -> str:
62
62
  return "\n".join(out)
63
63
 
64
64
 
65
- def rich_text() -> Text:
66
- """The knight as a Rich Text, for Textual widgets."""
65
+ _ORANGE = (PALETTE["b"], PALETTE["r"])
66
+
67
+
68
+ def _tinted(pixel, tint, accent):
69
+ """Recolor a pixel: keep its brightness, take its hue from the theme —
70
+ the accent color for the sword guard, the tint for everything else."""
71
+ if tint is None or pixel is None:
72
+ return pixel
73
+ base = accent if pixel in _ORANGE else tint
74
+ lum = sum(pixel) / 765
75
+ return tuple(int(c * lum) for c in base)
76
+
77
+
78
+ def _hex_rgb(color: str) -> tuple:
79
+ color = color.lstrip("#")
80
+ return tuple(int(color[i : i + 2], 16) for i in (0, 2, 4))
81
+
82
+
83
+ def rich_text(tint: str | None = None, accent: str | None = None) -> Text:
84
+ """The knight as a Rich Text, for Textual widgets. Pass theme colors as
85
+ hex strings to render him in the theme's livery instead of silver."""
86
+ tint_rgb = _hex_rgb(tint) if tint else None
87
+ accent_rgb = _hex_rgb(accent) if accent else tint_rgb
67
88
  text = Text()
68
89
  for row in _pixel_pairs():
69
90
  for top, bottom in row:
91
+ top = _tinted(top, tint_rgb, accent_rgb)
92
+ bottom = _tinted(bottom, tint_rgb, accent_rgb)
70
93
  if top is None and bottom is None:
71
94
  text.append(" ")
72
95
  elif bottom is None:
@@ -79,6 +102,25 @@ def rich_text() -> Text:
79
102
  return text
80
103
 
81
104
 
105
+ def ascii_art() -> str:
106
+ """The knight as plain monochrome ASCII — two chars per pixel to keep
107
+ his proportions in terminal cells, denser glyphs for brighter armor."""
108
+ lines = []
109
+ for row in ROWS:
110
+ line = ""
111
+ for ch in row:
112
+ pixel = PALETTE.get(ch)
113
+ if pixel is None:
114
+ line += " "
115
+ elif pixel in _ORANGE:
116
+ line += "%%"
117
+ else:
118
+ lum = sum(pixel) / 765
119
+ line += "::" if lum < 0.15 else "++" if lum < 0.45 else "==" if lum < 0.8 else "##"
120
+ lines.append(line.rstrip())
121
+ return "\n".join(lines)
122
+
123
+
82
124
  def says(message: str) -> str:
83
125
  """Cowsay, but it's a knight."""
84
126
  border = "_" * (len(message) + 2)
@@ -23,7 +23,7 @@ from .cli import VAULT_PATH, generate, import_csv, to_clipboard
23
23
  THEME_FILE = os.path.expanduser("~/.local/share/pw-manager/theme")
24
24
 
25
25
  APP_NAME = "The Paladin"
26
- APP_ICON = ""
26
+ APP_ICON = ""
27
27
 
28
28
  TUXEDO_THEMES = [
29
29
  Theme(
@@ -76,11 +76,21 @@ class UnlockScreen(Screen):
76
76
 
77
77
  def compose(self) -> ComposeResult:
78
78
  with Vertical(id="unlock-box"):
79
- yield Static(logo.rich_text(), id="unlock-logo")
79
+ yield Static(id="unlock-logo")
80
80
  yield Label(f"{APP_ICON} {APP_NAME}", id="unlock-title")
81
81
  yield Input(password=True, placeholder="master password", id="master")
82
82
  yield Static("", id="unlock-error")
83
83
 
84
+ def on_mount(self) -> None:
85
+ self._paint_logo()
86
+ self.app.theme_changed_signal.subscribe(self, self._paint_logo)
87
+
88
+ def _paint_logo(self, _theme: Theme | None = None) -> None:
89
+ theme = self.app.current_theme
90
+ self.query_one("#unlock-logo", Static).update(
91
+ logo.rich_text(tint=theme.primary, accent=theme.warning or theme.primary)
92
+ )
93
+
84
94
  def on_input_submitted(self, event: Input.Submitted) -> None:
85
95
  self.query_one("#unlock-error", Static).update("unlocking…")
86
96
  try:
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "basic-password-manager"
7
- version = "0.2.3"
7
+ version = "0.2.4"
8
8
  description = "The Paladin — a local encrypted password manager that lives in your terminal"
9
9
  readme = "README.md"
10
10
  license = "MIT"