From 2324fbb0bcb8374eea7eaeb3115057ef46d5c432 Mon Sep 17 00:00:00 2001 From: dece Date: Thu, 3 Jun 2021 16:45:35 +0200 Subject: [PATCH] history: add optional persistent history --- bebop/browser/browser.py | 11 ++++++++++- bebop/config.py | 1 + bebop/fs.py | 12 +++++++++--- bebop/help.py | 1 + bebop/history.py | 33 ++++++++++++++++++++++++++++++--- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/bebop/browser/browser.py b/bebop/browser/browser.py index 5e56341..e39e635 100644 --- a/bebop/browser/browser.py +++ b/bebop/browser/browser.py @@ -164,10 +164,15 @@ class Browser: else: self.capsule_prefs = capsule_prefs + # Load user data files that may not exist (no warning). + if self.config["persistent_history"]: + if not self.history.load(): + logging.warning("Could not load history file.") + if failed_to_load: error_msg = ( f"Failed to open some local data: {', '.join(failed_to_load)}. " - "Some data may be lost if you continue." + "These may be replaced if you continue." ) self.set_status_error(error_msg) elif start_url: @@ -175,12 +180,16 @@ class Browser: else: self.open_home() + # Start listening for inputs. while self.running: try: self.handle_inputs() except KeyboardInterrupt: self.set_status("Cancelled.") + if self.config["persistent_history"]: + self.history.save() + def handle_inputs(self): char = self.screen.getch() if char == ord("?"): diff --git a/bebop/config.py b/bebop/config.py index 86e83d7..9b58baf 100644 --- a/bebop/config.py +++ b/bebop/config.py @@ -29,6 +29,7 @@ DEFAULT_CONFIG = { "-subj", "/CN={common_name}", ], "scroll_step": 3, + "persistent_history": False, } RENDER_MODES = ("fancy", "dumb") diff --git a/bebop/fs.py b/bebop/fs.py index 98762b6..c758456 100644 --- a/bebop/fs.py +++ b/bebop/fs.py @@ -48,23 +48,29 @@ def get_downloads_path() -> Path: @lru_cache(None) -def get_identities_list_path(): +def get_identities_list_path() -> Path: """Return the identities JSON file path.""" return get_user_data_path() / "identities.json" @lru_cache(None) -def get_identities_path(): +def get_identities_path() -> Path: """Return the directory where identities are stored.""" return get_user_data_path() / "identities" @lru_cache(None) -def get_capsule_prefs_path(): +def get_capsule_prefs_path() -> Path: """Return the directory where identities are stored.""" return get_user_data_path() / "capsule_prefs.json" +@lru_cache(None) +def get_history_path() -> Path: + """Return the saved history path.""" + return get_user_data_path() / "history.txt" + + def ensure_bebop_files_exist() -> Optional[str]: """Ensure various Bebop's files or directories are present. diff --git a/bebop/help.py b/bebop/help.py index 3affc67..1dd3769 100644 --- a/bebop/help.py +++ b/bebop/help.py @@ -70,6 +70,7 @@ Here are the available options: * render_mode (string): default render mode to use ("fancy" or "dumb"). * generate_client_cert_command (see note 3): command to generate a client cert. * scroll_step (int): number of lines/columns to scroll in one step. +* persistent_history (bool): save and reload history. Notes: diff --git a/bebop/history.py b/bebop/history.py index 46e2b27..2fcf01b 100644 --- a/bebop/history.py +++ b/bebop/history.py @@ -1,10 +1,12 @@ """History management.""" +import logging + +from bebop.fs import get_history_path -class History: - """Basic browsing history manager. - """ +class History: + """Basic browsing history manager.""" def __init__(self, limit): self.urls = [] @@ -55,3 +57,28 @@ class History: urls.append(url) seen.add(url) return "# History\n\n" + "\n".join("=> " + url for url in urls) + + def save(self): + """Save current history to user data.""" + history_path = get_history_path() + try: + with open(history_path, "wt") as history_file: + for url in self.urls: + history_file.write(url + "\n") + except OSError as exc: + logging.error(f"Failed to save history {history_path}: {exc}") + return False + return True + + def load(self): + """Load saved history from user data.""" + history_path = get_history_path() + self.urls = [] + try: + with open(history_path, "rt") as history_file: + for url in history_file: + self.urls.append(url.rstrip()) + except OSError as exc: + logging.error(f"Failed to load history {history_path}: {exc}") + return False + return True