Transitioned to docker env-based configuration
This commit is contained in:
		
							parent
							
								
									a11de2770f
								
							
						
					
					
						commit
						e6413c3596
					
				
							
								
								
									
										58
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								bot.py
									
									
									
									
									
								
							@ -7,20 +7,48 @@ from configparser import ConfigParser
 | 
				
			|||||||
from data_manager import DataManager
 | 
					from data_manager import DataManager
 | 
				
			||||||
import pathlib
 | 
					import pathlib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Load env
 | 
					# ---------- Env & config loading ----------
 | 
				
			||||||
load_dotenv()
 | 
					 | 
				
			||||||
TOKEN = os.getenv('DISCORD_TOKEN')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Where to read settings from
 | 
					load_dotenv()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TOKEN = os.getenv('DISCORD_TOKEN', '').strip()
 | 
				
			||||||
CONFIG_PATH = os.getenv('SHAI_CONFIG', '/config/settings.conf')
 | 
					CONFIG_PATH = os.getenv('SHAI_CONFIG', '/config/settings.conf')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Load settings
 | 
					 | 
				
			||||||
config = ConfigParser()
 | 
					config = ConfigParser()
 | 
				
			||||||
read_ok = config.read(CONFIG_PATH)
 | 
					read_files = config.read(CONFIG_PATH)
 | 
				
			||||||
if not read_ok:
 | 
					if not read_files:
 | 
				
			||||||
    print(f"[Config] WARNING: could not read config at {CONFIG_PATH}; using in-image defaults where possible.")
 | 
					    print(f"[Config] INFO: no config at {CONFIG_PATH} (or unreadable). Will rely on env + defaults.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Ensure DEFAULT section exists
 | 
				
			||||||
 | 
					if 'DEFAULT' not in config:
 | 
				
			||||||
 | 
					    config['DEFAULT'] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _overlay_env_into_config(cfg: ConfigParser):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Overlay all SHAI_* environment variables into cfg['DEFAULT'] so env wins.
 | 
				
			||||||
 | 
					    Also accept SHAI_DATA_FILE or SHAI_DATA for data_file.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    d = cfg['DEFAULT']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Map SHAI_* -> lower-case keys (e.g. SHAI_MOD_CHANNEL_ID -> 'mod_channel_id')
 | 
				
			||||||
 | 
					    for k, v in os.environ.items():
 | 
				
			||||||
 | 
					        if not k.startswith('SHAI_'):
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
 | 
					        key = k[5:].lower()  # drop 'SHAI_' prefix
 | 
				
			||||||
 | 
					        # normalize common aliases
 | 
				
			||||||
 | 
					        if key == 'data':
 | 
				
			||||||
 | 
					            key = 'data_file'
 | 
				
			||||||
 | 
					        d[key] = str(v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # If neither env nor file provided data_file, set a safe default
 | 
				
			||||||
 | 
					    if not d.get('data_file', '').strip():
 | 
				
			||||||
 | 
					        d['data_file'] = '/data/data.json'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Apply overlay so env takes precedence everywhere
 | 
				
			||||||
 | 
					_overlay_env_into_config(config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ---------- Discord intents ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Intents (enable Members + Message Content in Dev Portal)
 | 
					 | 
				
			||||||
intents = discord.Intents.default()
 | 
					intents = discord.Intents.default()
 | 
				
			||||||
intents.guilds = True
 | 
					intents.guilds = True
 | 
				
			||||||
intents.members = True
 | 
					intents.members = True
 | 
				
			||||||
@ -29,13 +57,18 @@ intents.reactions = True
 | 
				
			|||||||
intents.emojis_and_stickers = True
 | 
					intents.emojis_and_stickers = True
 | 
				
			||||||
intents.voice_states = True
 | 
					intents.voice_states = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Data file path (prefer INI, else env, else sensible default)
 | 
					# ---------- Bot + DataManager ----------
 | 
				
			||||||
data_file = config['DEFAULT'].get('data_file', os.getenv('SHAI_DATA', '/data/data.json'))
 | 
					
 | 
				
			||||||
 | 
					data_file = config['DEFAULT']['data_file']  # guaranteed present by overlay
 | 
				
			||||||
 | 
					if not TOKEN:
 | 
				
			||||||
 | 
					    print("[Config] WARNING: DISCORD_TOKEN not set (env). Bot will fail to log in.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bot = commands.Bot(command_prefix='!', intents=intents)
 | 
					bot = commands.Bot(command_prefix='!', intents=intents)
 | 
				
			||||||
bot.config = config
 | 
					bot.config = config
 | 
				
			||||||
bot.data_manager = DataManager(data_file)
 | 
					bot.data_manager = DataManager(data_file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ---------- Self-check helpers ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def _guild_selfcheck(g: discord.Guild, cfg):
 | 
					async def _guild_selfcheck(g: discord.Guild, cfg):
 | 
				
			||||||
    problems = []
 | 
					    problems = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -97,7 +130,8 @@ async def on_ready():
 | 
				
			|||||||
    except Exception as e:
 | 
					    except Exception as e:
 | 
				
			||||||
        print("[Slash] Sync failed:", repr(e))
 | 
					        print("[Slash] Sync failed:", repr(e))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Auto-discover extensions
 | 
					# ---------- Auto-discover extensions ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
modules_path = pathlib.Path(__file__).parent / 'modules'
 | 
					modules_path = pathlib.Path(__file__).parent / 'modules'
 | 
				
			||||||
extensions = []
 | 
					extensions = []
 | 
				
			||||||
for folder in modules_path.iterdir():
 | 
					for folder in modules_path.iterdir():
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user