Web_Viewer: refactor database path handling

- Introduced a new method to retrieve the database path, allowing for a fallback to the [Bot] section if the [Web_Viewer] db_path is unset.
- Updated various parts of the codebase to utilize this new method, ensuring consistent database path resolution across the application.
- Enhanced the configuration example to clarify the optional nature of the db_path setting for the web viewer.
This commit is contained in:
Adam Gessaman
2026-02-11 09:47:29 -08:00
parent 6e466fe766
commit 8d4e960052
3 changed files with 49 additions and 46 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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()