From 2ef70801c70c30219ba0db12de277873c8a5f32a Mon Sep 17 00:00:00 2001 From: Moon Date: Sat, 14 Jun 2025 05:08:59 +0900 Subject: [PATCH] fix config module ref --- bot/config.py | 56 ++++++++++++++++++++++++++++++++++++++++++++-- example_config.ini | 5 +++++ web/app.py | 9 ++++++-- 3 files changed, 66 insertions(+), 4 deletions(-) diff --git a/bot/config.py b/bot/config.py index 54689f3..e30d505 100644 --- a/bot/config.py +++ b/bot/config.py @@ -1,6 +1,7 @@ '''Essentials for the bot to function''' import configparser import json +import re from os import environ, path @@ -21,6 +22,50 @@ def get_config_file() -> str: return config_path +def normalize_user(user_string: str) -> str: + """ + Normalizes a user string to the format @user@domain.tld where domain is lowercase and user is case-sensitive + + Args: + user_string: User string in various formats + + Returns: + Normalized user string + + Raises: + ValueError: If the user string is invalid or domain is malformed + """ + if not user_string or not user_string.strip(): + raise ValueError("User string cannot be empty") + + user_string = user_string.strip() + + # Add leading @ if missing + if not user_string.startswith('@'): + user_string = '@' + user_string + + # Split into user and domain parts + parts = user_string[1:].split('@', 1) # Remove leading @ and split + if len(parts) != 2: + raise ValueError(f"Invalid user format: {user_string}. Expected @user@domain.tld") + + username, domain = parts + + if not username: + raise ValueError("Username cannot be empty") + + if not domain: + raise ValueError("Domain cannot be empty") + + # Validate domain format (basic check for valid domain structure) + domain_pattern = r'^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$' + if not re.match(domain_pattern, domain): + raise ValueError(f"Invalid domain format: {domain}") + + # Return normalized format: @user@domain.tld (domain lowercase, user case-sensitive) + return f"@{username}@{domain.lower()}" + + def get_rarity_to_weight( config_section: configparser.SectionProxy) -> dict[int, float]: """Parses Rarity_X keys from config and returns a {rarity: weight} dict.""" @@ -36,17 +81,24 @@ config = configparser.ConfigParser() config.read(get_config_file()) # Username for the bot -USER = config['credentials']['User'].lower() +if 'User' not in config['credentials'] or not config['credentials']['User'].strip(): + raise ConfigError("User must be specified in config.ini under [credentials]") + +USER = normalize_user(config['credentials']['User']) # API key for the bot KEY = config['credentials']['Token'] # Bot's Misskey instance URL INSTANCE = config['credentials']['Instance'].lower() +# Web server port +WEB_PORT = config['application'].getint('WebPort', 5000) +BIND_ADDRESS = config['application'].get('BindAddress', '127.0.0.1') + # Fedi handles in the traditional 'user@domain.tld' style, allows these users # to use extra admin exclusive commands with the bot ADMINS = json.loads(config['application']['DefaultAdmins']) # SQLite Database location -DB_PATH = config['application']['DatabaseLocation'] +DB_PATH = config['application'].get('DatabaseLocation', './gacha_game.db') # Whether to enable the instance whitelist USE_WHITELIST = config['application']['UseWhitelist'] diff --git a/example_config.ini b/example_config.ini index 0ea2422..8c18c28 100644 --- a/example_config.ini +++ b/example_config.ini @@ -5,6 +5,11 @@ DefaultAdmins = ["@localadmin", "@remoteadmin@example.tld"] ; SQLite Database location DatabaseLocation = ./gacha_game.db +; Web server port (default: 5000) +WebPort = 5000 +; Web server bind address (default: 127.0.0.1, set to 0.0.0.0 to listen on all interfaces) +BindAddress = 127.0.0.1 + ; Whether to lmit access to the bot via an instance whitelist ; The whitelist can be adjusted via the application UseWhitelist = False diff --git a/web/app.py b/web/app.py index 61ed38f..fcd67a1 100644 --- a/web/app.py +++ b/web/app.py @@ -1,10 +1,15 @@ import sqlite3 +import sys +from pathlib import Path +# Add parent directory to Python path so we can import from bot/ +sys.path.append(str(Path(__file__).parent.parent)) + +from bot.config import WEB_PORT, BIND_ADDRESS, DB_PATH from flask import Flask, render_template, abort from werkzeug.exceptions import HTTPException app = Flask(__name__) -DB_PATH = "./gacha_game.db" # Adjust path if needed def get_db_connection(): conn = sqlite3.connect(DB_PATH) @@ -68,4 +73,4 @@ def submit_character(): if __name__ == '__main__': - app.run(host='0.0.0.0', port=5000, debug=True) + app.run(host=BIND_ADDRESS, port=WEB_PORT, debug=True)