Merge pull request 'any-env-and-bind-address' (#58) from any-env-and-bind-address into dev
Reviewed-on: #58 Reviewed-by: VD15 <valkyriedev15@gmail.com>
This commit is contained in:
commit
7c4fd5fc41
5 changed files with 78 additions and 13 deletions
|
@ -3,7 +3,7 @@ import misskey as misskey
|
||||||
from client import client_connection
|
from client import client_connection
|
||||||
import db_utils as db
|
import db_utils as db
|
||||||
|
|
||||||
from config import NOTIFICATION_POLL_INTERVAL
|
from config import NOTIFICATION_POLL_INTERVAL, USE_WHITELIST
|
||||||
from notification import process_notifications
|
from notification import process_notifications
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -15,6 +15,10 @@ if __name__ == '__main__':
|
||||||
# Setup default administrators
|
# Setup default administrators
|
||||||
db.setup_administrators()
|
db.setup_administrators()
|
||||||
|
|
||||||
|
# Show whitelist status
|
||||||
|
whitelist_status = "enabled" if USE_WHITELIST else "disabled"
|
||||||
|
print(f'Instance whitelisting: {whitelist_status}')
|
||||||
|
|
||||||
print('Listening for notifications...')
|
print('Listening for notifications...')
|
||||||
while True:
|
while True:
|
||||||
if not process_notifications(client):
|
if not process_notifications(client):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
'''Essentials for the bot to function'''
|
'''Essentials for the bot to function'''
|
||||||
import configparser
|
import configparser
|
||||||
import json
|
import json
|
||||||
|
import re
|
||||||
from os import environ, path
|
from os import environ, path
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,8 +14,10 @@ def get_config_file() -> str:
|
||||||
env: str | None = environ.get('KEMOVERSE_ENV')
|
env: str | None = environ.get('KEMOVERSE_ENV')
|
||||||
if not env:
|
if not env:
|
||||||
raise ConfigError('Error: KEMOVERSE_ENV is unset')
|
raise ConfigError('Error: KEMOVERSE_ENV is unset')
|
||||||
if not (env in ['prod', 'dev']):
|
|
||||||
raise ConfigError(f'Error: Invalid environment: {env}')
|
# Validate environment name contains only alphanumeric, dash, and underscore
|
||||||
|
if not re.match(r'^[a-zA-Z0-9_-]+$', env):
|
||||||
|
raise ValueError(f'KEMOVERSE_ENV "{env}" contains invalid characters. Only alphanumeric, dash (-), and underscore (_) are allowed.')
|
||||||
|
|
||||||
config_path: str = f'config_{env}.ini'
|
config_path: str = f'config_{env}.ini'
|
||||||
|
|
||||||
|
@ -23,6 +26,50 @@ def get_config_file() -> str:
|
||||||
return config_path
|
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(
|
def get_rarity_to_weight(
|
||||||
config_section: configparser.SectionProxy) -> dict[int, float]:
|
config_section: configparser.SectionProxy) -> dict[int, float]:
|
||||||
"""Parses Rarity_X keys from config and returns a {rarity: weight} dict."""
|
"""Parses Rarity_X keys from config and returns a {rarity: weight} dict."""
|
||||||
|
@ -38,19 +85,26 @@ config = configparser.ConfigParser()
|
||||||
config.read(get_config_file())
|
config.read(get_config_file())
|
||||||
|
|
||||||
# Username for the bot
|
# 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
|
# API key for the bot
|
||||||
KEY = config['credentials']['Token']
|
KEY = config['credentials']['Token']
|
||||||
# Bot's Misskey instance URL
|
# Bot's Misskey instance URL
|
||||||
INSTANCE = config['credentials']['Instance'].lower()
|
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
|
# Fedi handles in the traditional 'user@domain.tld' style, allows these users
|
||||||
# to use extra admin exclusive commands with the bot
|
# to use extra admin exclusive commands with the bot
|
||||||
ADMINS = json.loads(config['application']['DefaultAdmins'])
|
ADMINS = json.loads(config['application']['DefaultAdmins'])
|
||||||
# SQLite Database location
|
# SQLite Database location
|
||||||
DB_PATH = config['application']['DatabaseLocation']
|
DB_PATH = config['application'].get('DatabaseLocation', './gacha_game.db')
|
||||||
# Whether to enable the instance whitelist
|
# Whether to enable the instance whitelist
|
||||||
USE_WHITELIST = config['application']['UseWhitelist']
|
USE_WHITELIST = config['application'].getboolean('UseWhitelist', True)
|
||||||
|
|
||||||
NOTIFICATION_POLL_INTERVAL = int(config['notification']['PollInterval'])
|
NOTIFICATION_POLL_INTERVAL = int(config['notification']['PollInterval'])
|
||||||
NOTIFICATION_BATCH_SIZE = int(config['notification']['BatchSize'])
|
NOTIFICATION_BATCH_SIZE = int(config['notification']['BatchSize'])
|
||||||
|
|
|
@ -5,6 +5,11 @@
|
||||||
DefaultAdmins = ["@localadmin", "@remoteadmin@example.tld"]
|
DefaultAdmins = ["@localadmin", "@remoteadmin@example.tld"]
|
||||||
; SQLite Database location
|
; SQLite Database location
|
||||||
DatabaseLocation = ./gacha_game.db
|
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
|
; Whether to lmit access to the bot via an instance whitelist
|
||||||
; The whitelist can be adjusted via the application
|
; The whitelist can be adjusted via the application
|
||||||
UseWhitelist = False
|
UseWhitelist = False
|
||||||
|
|
|
@ -57,16 +57,14 @@ def perform_migration(cursor: sqlite3.Cursor, migration: tuple[int, str]) -> Non
|
||||||
def get_db_path() -> str | DBNotFoundError:
|
def get_db_path() -> str | DBNotFoundError:
|
||||||
'''Gets the DB path from config.ini'''
|
'''Gets the DB path from config.ini'''
|
||||||
env = os.environ.get('KEMOVERSE_ENV')
|
env = os.environ.get('KEMOVERSE_ENV')
|
||||||
if not (env and env in ['prod', 'dev']):
|
|
||||||
raise KemoverseEnvUnset
|
|
||||||
|
|
||||||
print(f'Running in "{env}" mode')
|
|
||||||
|
|
||||||
config_path = f'config_{env}.ini'
|
config_path = f'config_{env}.ini'
|
||||||
|
|
||||||
if not os.path.isfile(config_path):
|
if not os.path.isfile(config_path):
|
||||||
raise ConfigError(f'Could not find {config_path}')
|
raise ConfigError(f'Could not find {config_path}')
|
||||||
|
|
||||||
|
print(f'Running in "{env}" mode')
|
||||||
|
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
config.read(config_path)
|
config.read(config_path)
|
||||||
db_path = config['application']['DatabaseLocation']
|
db_path = config['application']['DatabaseLocation']
|
||||||
|
@ -96,7 +94,6 @@ def main():
|
||||||
return
|
return
|
||||||
except KemoverseEnvUnset:
|
except KemoverseEnvUnset:
|
||||||
print('Error: KEMOVERSE_ENV is either not set or has an invalid value.')
|
print('Error: KEMOVERSE_ENV is either not set or has an invalid value.')
|
||||||
print('Please set KEMOVERSE_ENV to either "dev" or "prod" before running.')
|
|
||||||
print(traceback.format_exc())
|
print(traceback.format_exc())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import sqlite3
|
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 flask import Flask, render_template, abort
|
||||||
from werkzeug.exceptions import HTTPException
|
from werkzeug.exceptions import HTTPException
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
DB_PATH = "./gacha_game.db" # Adjust path if needed
|
|
||||||
|
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
conn = sqlite3.connect(DB_PATH)
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
@ -68,4 +73,4 @@ def submit_character():
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
app.run(host=BIND_ADDRESS, port=WEB_PORT, debug=True)
|
||||||
|
|
Loading…
Add table
Reference in a new issue