mirror of
https://github.com/PR0M3TH3AN/SeedPass.git
synced 2025-09-08 15:28:44 +00:00
Add verbose timing logs
This commit is contained in:
@@ -101,6 +101,7 @@ class NostrClient:
|
|||||||
self.fingerprint = fingerprint
|
self.fingerprint = fingerprint
|
||||||
self.fingerprint_dir = self.encryption_manager.fingerprint_dir
|
self.fingerprint_dir = self.encryption_manager.fingerprint_dir
|
||||||
self.config_manager = config_manager
|
self.config_manager = config_manager
|
||||||
|
self.verbose_timing = False
|
||||||
|
|
||||||
if parent_seed is None:
|
if parent_seed is None:
|
||||||
parent_seed = self.encryption_manager.decrypt_parent_seed()
|
parent_seed = self.encryption_manager.decrypt_parent_seed()
|
||||||
@@ -123,6 +124,12 @@ class NostrClient:
|
|||||||
else:
|
else:
|
||||||
self.relays = relays
|
self.relays = relays
|
||||||
|
|
||||||
|
if self.config_manager is not None:
|
||||||
|
try:
|
||||||
|
self.verbose_timing = self.config_manager.get_verbose_timing()
|
||||||
|
except Exception:
|
||||||
|
self.verbose_timing = False
|
||||||
|
|
||||||
# store the last error encountered during network operations
|
# store the last error encountered during network operations
|
||||||
self.last_error: Optional[str] = None
|
self.last_error: Optional[str] = None
|
||||||
|
|
||||||
@@ -351,6 +358,7 @@ class NostrClient:
|
|||||||
Maximum chunk size in bytes. Defaults to 50 kB.
|
Maximum chunk size in bytes. Defaults to 50 kB.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
start = time.perf_counter()
|
||||||
if self.offline_mode or not self.relays:
|
if self.offline_mode or not self.relays:
|
||||||
return Manifest(ver=1, algo="gzip", chunks=[]), ""
|
return Manifest(ver=1, algo="gzip", chunks=[]), ""
|
||||||
await self._connect_async()
|
await self._connect_async()
|
||||||
@@ -381,6 +389,9 @@ class NostrClient:
|
|||||||
manifest_id = result.id.to_hex() if hasattr(result, "id") else str(result)
|
manifest_id = result.id.to_hex() if hasattr(result, "id") else str(result)
|
||||||
self.current_manifest = manifest
|
self.current_manifest = manifest
|
||||||
self._delta_events = []
|
self._delta_events = []
|
||||||
|
if getattr(self, "verbose_timing", False):
|
||||||
|
duration = time.perf_counter() - start
|
||||||
|
logger.info("publish_snapshot completed in %.2f seconds", duration)
|
||||||
return manifest, manifest_id
|
return manifest, manifest_id
|
||||||
|
|
||||||
async def fetch_latest_snapshot(self) -> Tuple[Manifest, list[bytes]] | None:
|
async def fetch_latest_snapshot(self) -> Tuple[Manifest, list[bytes]] | None:
|
||||||
|
@@ -58,6 +58,7 @@ class ConfigManager:
|
|||||||
"min_lowercase": 2,
|
"min_lowercase": 2,
|
||||||
"min_digits": 2,
|
"min_digits": 2,
|
||||||
"min_special": 2,
|
"min_special": 2,
|
||||||
|
"verbose_timing": False,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
data = self.vault.load_config()
|
data = self.vault.load_config()
|
||||||
@@ -82,6 +83,7 @@ class ConfigManager:
|
|||||||
data.setdefault("min_lowercase", 2)
|
data.setdefault("min_lowercase", 2)
|
||||||
data.setdefault("min_digits", 2)
|
data.setdefault("min_digits", 2)
|
||||||
data.setdefault("min_special", 2)
|
data.setdefault("min_special", 2)
|
||||||
|
data.setdefault("verbose_timing", False)
|
||||||
|
|
||||||
# Migrate legacy hashed_password.enc if present and password_hash is missing
|
# Migrate legacy hashed_password.enc if present and password_hash is missing
|
||||||
legacy_file = self.fingerprint_dir / "hashed_password.enc"
|
legacy_file = self.fingerprint_dir / "hashed_password.enc"
|
||||||
@@ -315,3 +317,12 @@ class ConfigManager:
|
|||||||
"""Retrieve the delay in seconds between Nostr retries."""
|
"""Retrieve the delay in seconds between Nostr retries."""
|
||||||
cfg = self.load_config(require_pin=False)
|
cfg = self.load_config(require_pin=False)
|
||||||
return float(cfg.get("nostr_retry_delay", 1.0))
|
return float(cfg.get("nostr_retry_delay", 1.0))
|
||||||
|
|
||||||
|
def set_verbose_timing(self, enabled: bool) -> None:
|
||||||
|
cfg = self.load_config(require_pin=False)
|
||||||
|
cfg["verbose_timing"] = bool(enabled)
|
||||||
|
self.save_config(cfg)
|
||||||
|
|
||||||
|
def get_verbose_timing(self) -> bool:
|
||||||
|
cfg = self.load_config(require_pin=False)
|
||||||
|
return bool(cfg.get("verbose_timing", False))
|
||||||
|
@@ -138,6 +138,7 @@ class PasswordManager:
|
|||||||
self.offline_mode: bool = False
|
self.offline_mode: bool = False
|
||||||
self.profile_stack: list[tuple[str, Path, str]] = []
|
self.profile_stack: list[tuple[str, Path, str]] = []
|
||||||
self.last_unlock_duration: float | None = None
|
self.last_unlock_duration: float | None = None
|
||||||
|
self.verbose_timing: bool = False
|
||||||
|
|
||||||
# Initialize the fingerprint manager first
|
# Initialize the fingerprint manager first
|
||||||
self.initialize_fingerprint_manager()
|
self.initialize_fingerprint_manager()
|
||||||
@@ -247,6 +248,8 @@ class PasswordManager:
|
|||||||
"yellow",
|
"yellow",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
if getattr(self, "verbose_timing", False):
|
||||||
|
logger.info("Vault unlocked in %.2f seconds", self.last_unlock_duration)
|
||||||
|
|
||||||
def initialize_fingerprint_manager(self):
|
def initialize_fingerprint_manager(self):
|
||||||
"""
|
"""
|
||||||
@@ -1014,6 +1017,7 @@ class PasswordManager:
|
|||||||
)
|
)
|
||||||
self.secret_mode_enabled = bool(config.get("secret_mode_enabled", False))
|
self.secret_mode_enabled = bool(config.get("secret_mode_enabled", False))
|
||||||
self.clipboard_clear_delay = int(config.get("clipboard_clear_delay", 45))
|
self.clipboard_clear_delay = int(config.get("clipboard_clear_delay", 45))
|
||||||
|
self.verbose_timing = bool(config.get("verbose_timing", False))
|
||||||
if not self.offline_mode:
|
if not self.offline_mode:
|
||||||
print("Connecting to relays...")
|
print("Connecting to relays...")
|
||||||
self.nostr_client = NostrClient(
|
self.nostr_client = NostrClient(
|
||||||
@@ -1034,6 +1038,7 @@ class PasswordManager:
|
|||||||
|
|
||||||
def sync_index_from_nostr(self) -> None:
|
def sync_index_from_nostr(self) -> None:
|
||||||
"""Always fetch the latest vault data from Nostr and update the local index."""
|
"""Always fetch the latest vault data from Nostr and update the local index."""
|
||||||
|
start = time.perf_counter()
|
||||||
try:
|
try:
|
||||||
result = asyncio.run(self.nostr_client.fetch_latest_snapshot())
|
result = asyncio.run(self.nostr_client.fetch_latest_snapshot())
|
||||||
if not result:
|
if not result:
|
||||||
@@ -1054,6 +1059,10 @@ class PasswordManager:
|
|||||||
logger.info("Local database synchronized from Nostr.")
|
logger.info("Local database synchronized from Nostr.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"Unable to sync index from Nostr: {e}")
|
logger.warning(f"Unable to sync index from Nostr: {e}")
|
||||||
|
finally:
|
||||||
|
if getattr(self, "verbose_timing", False):
|
||||||
|
duration = time.perf_counter() - start
|
||||||
|
logger.info("sync_index_from_nostr completed in %.2f seconds", duration)
|
||||||
|
|
||||||
def start_background_sync(self) -> None:
|
def start_background_sync(self) -> None:
|
||||||
"""Launch a thread to synchronize the vault without blocking the UI."""
|
"""Launch a thread to synchronize the vault without blocking the UI."""
|
||||||
|
@@ -473,6 +473,9 @@ def config_set(ctx: typer.Context, key: str, value: str) -> None:
|
|||||||
"quick_unlock": lambda v: cfg.set_quick_unlock(
|
"quick_unlock": lambda v: cfg.set_quick_unlock(
|
||||||
v.lower() in ("1", "true", "yes", "y", "on")
|
v.lower() in ("1", "true", "yes", "y", "on")
|
||||||
),
|
),
|
||||||
|
"verbose_timing": lambda v: cfg.set_verbose_timing(
|
||||||
|
v.lower() in ("1", "true", "yes", "y", "on")
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
action = mapping.get(key)
|
action = mapping.get(key)
|
||||||
|
32
src/tests/test_verbose_timing.py
Normal file
32
src/tests/test_verbose_timing.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from password_manager.manager import PasswordManager
|
||||||
|
from helpers import dummy_nostr_client
|
||||||
|
|
||||||
|
|
||||||
|
def test_unlock_vault_logs_time(monkeypatch, caplog, tmp_path):
|
||||||
|
pm = PasswordManager.__new__(PasswordManager)
|
||||||
|
pm.fingerprint_dir = tmp_path
|
||||||
|
pm.setup_encryption_manager = lambda path: None
|
||||||
|
pm.initialize_bip85 = lambda: None
|
||||||
|
pm.initialize_managers = lambda: None
|
||||||
|
pm.update_activity = lambda: None
|
||||||
|
pm.verbose_timing = True
|
||||||
|
caplog.set_level(logging.INFO, logger="password_manager.manager")
|
||||||
|
times = iter([0.0, 1.0])
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"password_manager.manager.time.perf_counter", lambda: next(times)
|
||||||
|
)
|
||||||
|
pm.unlock_vault()
|
||||||
|
assert "Vault unlocked in 1.00 seconds" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
def test_publish_snapshot_logs_time(dummy_nostr_client, monkeypatch, caplog):
|
||||||
|
client, _relay = dummy_nostr_client
|
||||||
|
client.verbose_timing = True
|
||||||
|
caplog.set_level(logging.INFO, logger="nostr.client")
|
||||||
|
times = iter([0.0, 1.0])
|
||||||
|
monkeypatch.setattr("nostr.client.time.perf_counter", lambda: next(times))
|
||||||
|
asyncio.run(client.publish_snapshot(b"data"))
|
||||||
|
assert "publish_snapshot completed in 1.00 seconds" in caplog.text
|
Reference in New Issue
Block a user