diff --git a/config.ini.example b/config.ini.example index f5f5f1d..5665438 100644 --- a/config.ini.example +++ b/config.ini.example @@ -802,9 +802,10 @@ debug = false # false: Start web viewer manually (recommended) auto_start = false -# Database path for web viewer data -# Default: bot_data.db -db_path = bot_data.db +# Optional: database path for web viewer. If unset, the viewer uses [Bot] db_path (recommended). +# Only set this if you use a separate database for the viewer; you will see a startup warning. +# See docs/WEB_VIEWER.md for migrating from a separate database. +# db_path = meshcore_bot.db # Additional hashtag channels to decode in the packet stream # The web viewer can decrypt GroupText messages from hashtag channels diff --git a/modules/web_viewer/app.py b/modules/web_viewer/app.py index e6bb785..3476788 100644 --- a/modules/web_viewer/app.py +++ b/modules/web_viewer/app.py @@ -164,6 +164,17 @@ class BotDataViewer: return dict(greeter_enabled=greeter_enabled, feed_manager_enabled=feed_manager_enabled) + def _get_db_path(self): + """Get the database path, falling back to [Bot] db_path if [Web_Viewer] db_path is unset""" + # Use [Bot] db_path when [Web_Viewer] db_path is unset + bot_db = self.config.get('Bot', 'db_path', fallback='meshcore_bot.db') + if (self.config.has_section('Web_Viewer') and self.config.has_option('Web_Viewer', 'db_path') + and self.config.get('Web_Viewer', 'db_path', fallback='').strip()): + use_db = self.config.get('Web_Viewer', 'db_path').strip() + else: + use_db = bot_db + return str(resolve_path(use_db, self.bot_root)) + def _init_databases(self): """Initialize database connections""" try: @@ -442,11 +453,8 @@ class BotDataViewer: # Get commands from last 60 minutes cutoff_time = time.time() - (60 * 60) # 60 minutes ago - # Get database path - db_path = self.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - db_path = resolve_path(db_path, self.bot_root) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_db_path() with sqlite3.connect(db_path, timeout=30) as conn: cursor = conn.cursor() @@ -1519,10 +1527,8 @@ class BotDataViewer: import json # Get database path (re-resolve on each iteration in case config changed) - db_path = self.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - db_path = resolve_path(db_path, self.bot_root) + # Falls back to [Bot] db_path if [Web_Viewer] db_path is unset + db_path = self._get_db_path() # Check if database file exists and is accessible db_file = Path(db_path) @@ -1704,11 +1710,8 @@ class BotDataViewer: cutoff_time = time.time() - (days_to_keep * 24 * 60 * 60) - # Get database path - db_path = self.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - db_path = resolve_path(db_path, self.bot_root) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_db_path() # Use shorter timeout and isolation_level for better concurrency conn = sqlite3.connect(db_path, timeout=10, isolation_level='DEFERRED') @@ -2216,9 +2219,8 @@ class BotDataViewer: # Get database file size import os - db_path = self.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - db_path = resolve_path(db_path, self.bot_root) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_db_path() try: db_size_bytes = os.path.getsize(db_path) if db_size_bytes < 1024: @@ -2274,9 +2276,8 @@ class BotDataViewer: # Get initial database size import os - db_path = self.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - db_path = resolve_path(db_path, self.bot_root) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_db_path() initial_size = os.path.getsize(db_path) # Perform VACUUM to reclaim unused space diff --git a/modules/web_viewer/integration.py b/modules/web_viewer/integration.py index 9e0198d..a492fd4 100644 --- a/modules/web_viewer/integration.py +++ b/modules/web_viewer/integration.py @@ -30,17 +30,26 @@ class BotIntegration: self.circuit_breaker_open = False self.circuit_breaker_failures = 0 + def _get_web_viewer_db_path(self): + """Get the web viewer database path, falling back to [Bot] db_path if [Web_Viewer] db_path is unset""" + # Use [Bot] db_path when [Web_Viewer] db_path is unset + bot_db = self.bot.config.get('Bot', 'db_path', fallback='meshcore_bot.db') + if (self.bot.config.has_section('Web_Viewer') and self.bot.config.has_option('Web_Viewer', 'db_path') + and self.bot.config.get('Web_Viewer', 'db_path', fallback='').strip()): + use_db = self.bot.config.get('Web_Viewer', 'db_path').strip() + else: + use_db = bot_db + # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) + base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' + return str(resolve_path(use_db, base_dir)) + def _init_packet_stream_table(self): - """Initialize the packet_stream table in bot_data.db""" + """Initialize the packet_stream table in the database""" try: import sqlite3 - # Get database path from config - db_path = self.bot.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' - db_path = resolve_path(db_path, base_dir) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_web_viewer_db_path() # Connect to database and create table if it doesn't exist conn = sqlite3.connect(str(db_path), timeout=30.0) @@ -109,10 +118,8 @@ class BotIntegration: serializable_data = self._make_json_serializable(packet_data) # Store in database for web viewer to read - db_path = self.bot.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' - db_path = resolve_path(db_path, base_dir) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_web_viewer_db_path() conn = sqlite3.connect(str(db_path), timeout=30.0) cursor = conn.cursor() @@ -158,10 +165,8 @@ class BotIntegration: serializable_data = self._make_json_serializable(command_data) # Store in database for web viewer to read - db_path = self.bot.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' - db_path = resolve_path(db_path, base_dir) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_web_viewer_db_path() conn = sqlite3.connect(str(db_path), timeout=30.0) cursor = conn.cursor() @@ -188,10 +193,8 @@ class BotIntegration: serializable_data = self._make_json_serializable(routing_data) # Store in database for web viewer to read - db_path = self.bot.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' - db_path = resolve_path(db_path, base_dir) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_web_viewer_db_path() conn = sqlite3.connect(str(db_path), timeout=30.0) cursor = conn.cursor() @@ -215,10 +218,8 @@ class BotIntegration: cutoff_time = time.time() - (days_to_keep * 24 * 60 * 60) - db_path = self.bot.config.get('Web_Viewer', 'db_path', fallback='bot_data.db') - # Resolve database path (relative paths resolved from bot root, absolute paths used as-is) - base_dir = self.bot.bot_root if hasattr(self.bot, 'bot_root') else '.' - db_path = resolve_path(db_path, base_dir) + # Get database path (falls back to [Bot] db_path if [Web_Viewer] db_path is unset) + db_path = self._get_web_viewer_db_path() conn = sqlite3.connect(str(db_path), timeout=30.0) cursor = conn.cursor()