Clean up error handling, naming, and README accuracy
- config.py: warn and fall back to defaults on invalid keybinding fields instead of raising an unhandled ValueError - clipboard.py: replace check=True with manual returncode check for a friendly error message instead of a raw traceback - __main__.py: rename __handle_* to _handle_* (double-underscore name mangling is meaningless at module level) - rofi.py: check that rofi is installed before launching - history.py: warn on corrupted history file instead of silently returning empty - README: fix install path (cd bw-menu/python), add name to available keybinding fields
This commit is contained in:
parent
4d6e64668a
commit
baa3146840
@ -12,7 +12,7 @@ cargo install rbw # requires rbw >= 1.14.0
|
|||||||
|
|
||||||
# install bw-menu
|
# install bw-menu
|
||||||
git clone https://git.navidsassan.ch/navid.sassan/bw-menu.git
|
git clone https://git.navidsassan.ch/navid.sassan/bw-menu.git
|
||||||
cd bw-menu
|
cd bw-menu/python
|
||||||
uv sync
|
uv sync
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ keybindings:
|
|||||||
totp: Shift+Return
|
totp: Shift+Return
|
||||||
```
|
```
|
||||||
|
|
||||||
Each entry maps a vault field to a [rofi key name](https://davatorium.github.io/rofi/current/rofi-keys.5/). Available fields: `password`, `username`, `totp`.
|
Each entry maps a vault field to a [rofi key name](https://davatorium.github.io/rofi/current/rofi-keys.5/). Available fields: `password`, `username`, `totp`, `name`.
|
||||||
|
|
||||||
The **first** entry is bound to rofi's accept key (`kb-accept-entry`). Additional entries become custom keybindings (`kb-custom-1`, `kb-custom-2`, …).
|
The **first** entry is bound to rofi's accept key (`kb-accept-entry`). Additional entries become custom keybindings (`kb-custom-1`, `kb-custom-2`, …).
|
||||||
|
|
||||||
|
|||||||
@ -9,12 +9,12 @@ def main():
|
|||||||
args = parse_args()
|
args = parse_args()
|
||||||
|
|
||||||
if args.command == "select":
|
if args.command == "select":
|
||||||
__handle_select(args)
|
_handle_select(args)
|
||||||
elif args.command == "history":
|
elif args.command == "history":
|
||||||
__handle_history(args)
|
_handle_history(args)
|
||||||
|
|
||||||
|
|
||||||
def __handle_select(args):
|
def _handle_select(args):
|
||||||
selector = create_selector(args.selector)
|
selector = create_selector(args.selector)
|
||||||
selection = selector.run(args)
|
selection = selector.run(args)
|
||||||
if selection is None:
|
if selection is None:
|
||||||
@ -29,7 +29,7 @@ def __handle_select(args):
|
|||||||
clipboard.copy(value)
|
clipboard.copy(value)
|
||||||
|
|
||||||
|
|
||||||
def __handle_history(args):
|
def _handle_history(args):
|
||||||
if args.history_command == "list":
|
if args.history_command == "list":
|
||||||
for i, entry in enumerate(history.load()):
|
for i, entry in enumerate(history.load()):
|
||||||
print(f"{i}: {format_entry(entry)}")
|
print(f"{i}: {format_entry(entry)}")
|
||||||
|
|||||||
@ -8,7 +8,10 @@ def copy(text: str):
|
|||||||
if tool is None:
|
if tool is None:
|
||||||
print("No clipboard tool found (install wl-copy or xclip)", file=sys.stderr)
|
print("No clipboard tool found (install wl-copy or xclip)", file=sys.stderr)
|
||||||
sys.exit(5)
|
sys.exit(5)
|
||||||
subprocess.run(tool, input=text, encoding="utf-8", check=True)
|
result = subprocess.run(tool, input=text, encoding="utf-8")
|
||||||
|
if result.returncode != 0:
|
||||||
|
print(f"Error copying to clipboard: {result.stderr}", file=sys.stderr)
|
||||||
|
sys.exit(5)
|
||||||
|
|
||||||
|
|
||||||
def __detect_tool() -> list[str] | None:
|
def __detect_tool() -> list[str] | None:
|
||||||
|
|||||||
@ -54,9 +54,12 @@ def load() -> Config:
|
|||||||
keybindings = {str(k): str(v) for k, v in kb.items()}
|
keybindings = {str(k): str(v) for k, v in kb.items()}
|
||||||
invalid = {k for k in keybindings if k not in VALID_FIELDS}
|
invalid = {k for k in keybindings if k not in VALID_FIELDS}
|
||||||
if invalid:
|
if invalid:
|
||||||
raise ValueError(
|
print(
|
||||||
f"Invalid keybinding field(s): {', '.join(sorted(invalid))}. Valid fields: {', '.join(sorted(VALID_FIELDS))}"
|
f"Warning: invalid keybinding field(s): {', '.join(sorted(invalid))}. "
|
||||||
|
f"Valid fields: {', '.join(sorted(VALID_FIELDS))}. Using defaults",
|
||||||
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
|
return Config()
|
||||||
return Config(keybindings=keybindings)
|
return Config(keybindings=keybindings)
|
||||||
except yaml.YAMLError:
|
except yaml.YAMLError:
|
||||||
print(
|
print(
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from bw_menu.rbw import Entry
|
from bw_menu.rbw import Entry
|
||||||
@ -21,6 +22,10 @@ def load() -> list[Entry]:
|
|||||||
data = json.loads(path.read_text())
|
data = json.loads(path.read_text())
|
||||||
return [Entry(e["name"], e["folder"], e["username"]) for e in data["entries"]]
|
return [Entry(e["name"], e["folder"], e["username"]) for e in data["entries"]]
|
||||||
except (json.JSONDecodeError, KeyError):
|
except (json.JSONDecodeError, KeyError):
|
||||||
|
print(
|
||||||
|
f"Warning: history file {path} could not be read, ignoring",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -84,6 +85,9 @@ class RofiSelector:
|
|||||||
path.unlink(missing_ok=True)
|
path.unlink(missing_ok=True)
|
||||||
|
|
||||||
def __launch(self, keybindings: dict[str, str]):
|
def __launch(self, keybindings: dict[str, str]):
|
||||||
|
if not shutil.which("rofi"):
|
||||||
|
print("rofi is not installed", file=sys.stderr)
|
||||||
|
sys.exit(5)
|
||||||
script = str(Path(sys.argv[0]).resolve())
|
script = str(Path(sys.argv[0]).resolve())
|
||||||
keys = list(keybindings.values())
|
keys = list(keybindings.values())
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user