From 918ed75e9bb8b9dfb017b0fa5ee123aa8763301c Mon Sep 17 00:00:00 2001 From: Moon Date: Thu, 12 Jun 2025 14:11:45 +0900 Subject: [PATCH] better config file handling for testing multiple configs and validating contents --- bot/config.py | 81 +++++++++++++++++++++++++++++++++++++++++---------- db.py | 42 +++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 19 deletions(-) diff --git a/bot/config.py b/bot/config.py index b22f6c5..1f2b3a7 100644 --- a/bot/config.py +++ b/bot/config.py @@ -1,28 +1,79 @@ '''Essentials for the bot to function''' import configparser -config = configparser.ConfigParser() -config.read('config.ini') +import os +import sys +import argparse + +def get_config_file_path(): + """Get config file path from command line arguments or default""" + parser = argparse.ArgumentParser(add_help=False) # Don't interfere with other argument parsing + parser.add_argument('--config', default='config.ini', help='Path to config file (default: config.ini)') + + # Parse only known args to avoid conflicts with other argument parsing + args, _ = parser.parse_known_args() + return args.config + +def load_config(): + """Load and validate config file with proper error handling""" + config_file = get_config_file_path() + config = configparser.ConfigParser() + + # Check if config file exists + if not os.path.exists(config_file): + print(f"Error: {config_file} not found!") + if config_file == 'config.ini': + print("Please copy example_config.ini to config.ini and configure it.") + print(f"Or use --config /path/to/your/config.ini to specify a different location.") + sys.exit(1) + + try: + config.read(config_file) + except configparser.Error as e: + print(f"Error reading {config_file}: {e}") + sys.exit(1) + + # Check if [application] section exists + if 'application' not in config: + print(f"Error: [application] section missing in {config_file}") + sys.exit(1) + + # Validate required fields + required_fields = ['BotUser', 'ApiKey', 'InstanceUrl', 'InstanceType', 'DatabaseLocation'] + missing_fields = [] + + for field in required_fields: + if field not in config['application'] or not config['application'][field].strip(): + missing_fields.append(field) + + if missing_fields: + print(f"Error: Required fields missing in {config_file}: {', '.join(missing_fields)}") + sys.exit(1) + + # Validate InstanceType + instance_type = config['application']['InstanceType'].lower() + if instance_type not in ('misskey', 'pleroma'): + print("Error: InstanceType must be either 'misskey' or 'pleroma'") + sys.exit(1) + + return config + +# Load and validate configuration +config = load_config() # Username for the bot -USER = config['application']['BotUser'] +USER = config['application']['BotUser'] # API key for the bot -KEY = config['application']['ApiKey'] -# Bot's Misskey instance URL +KEY = config['application']['ApiKey'] + +# Bot's instance URL INSTANCE = config['application']['InstanceUrl'] # SQLite Database location DB_PATH = config['application']['DatabaseLocation'] -# Instance type validation -if 'InstanceType' not in config['application']: - raise ValueError("InstanceType must be specified in config.ini") - -instance_type = config['application']['InstanceType'].lower() -if instance_type not in ('misskey', 'pleroma'): - raise ValueError("InstanceType must be either 'misskey' or 'pleroma'") - -INSTANCE_TYPE = instance_type +# Instance type +INSTANCE_TYPE = config['application']['InstanceType'].lower() # Web server port WEB_PORT = config['application'].getint('WebPort', 5000) @@ -36,4 +87,4 @@ TRUSTED_INSTANCES = [instance.strip() for instance in trusted_instances_str.spli # TODO: move this to db # Fedi handles in the traditional 'user@domain.tld' style, allows these users # to use extra admin exclusive commands with the bot''' -ADMINS = config['application']['DefaultAdmins'] +ADMINS = config['application'].get('DefaultAdmins', '[]') diff --git a/db.py b/db.py index 9ef9857..db0aee1 100644 --- a/db.py +++ b/db.py @@ -1,12 +1,46 @@ import sqlite3 import configparser +import os +import sys +import argparse -# Read config to get database location -config = configparser.ConfigParser() -config.read('config.ini') +def get_config_file_path(): + """Get config file path from command line arguments or default""" + parser = argparse.ArgumentParser(add_help=False) + parser.add_argument('--config', default='config.ini', help='Path to config file (default: config.ini)') + args, _ = parser.parse_known_args() + return args.config + +def get_db_path(): + """Get database path from config with error handling""" + config_file = get_config_file_path() + + if not os.path.exists(config_file): + print(f"Error: {config_file} not found!") + if config_file == 'config.ini': + print("Please copy example_config.ini to config.ini and configure it.") + print(f"Or use --config /path/to/your/config.ini to specify a different location.") + sys.exit(1) + + config = configparser.ConfigParser() + try: + config.read(config_file) + except configparser.Error as e: + print(f"Error reading {config_file}: {e}") + sys.exit(1) + + if 'application' not in config: + print(f"Error: [application] section missing in {config_file}") + sys.exit(1) + + if 'DatabaseLocation' not in config['application']: + print(f"Error: DatabaseLocation missing in {config_file}") + sys.exit(1) + + return config['application']['DatabaseLocation'] # Connect to SQLite database (or create it if it doesn't exist) -db_path = config['application']['DatabaseLocation'] +db_path = get_db_path() conn = sqlite3.connect(db_path) cursor = conn.cursor()