Implement a better config system
This commit is contained in:
90
bot.py
90
bot.py
@@ -1,5 +1,4 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
@@ -10,9 +9,10 @@ import discord
|
|||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
from lib.config import config, config_meta, config_load, config_save, config_get, config_set, config_get_descriptions
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
TOKEN = os.getenv('DISCORD_TOKEN')
|
TOKEN = os.getenv('DISCORD_TOKEN')
|
||||||
CONFIG = 'config.json'
|
|
||||||
|
|
||||||
PING_REGEX = re.compile(r'\b(?:ge)?ping', re.IGNORECASE)
|
PING_REGEX = re.compile(r'\b(?:ge)?ping', re.IGNORECASE)
|
||||||
TOPFIT_REGEX = re.compile(r'\b(topfit|fit|top|micro|microsoft|virtual reality|vr|ä+h*m*|hä*)\b', re.IGNORECASE)
|
TOPFIT_REGEX = re.compile(r'\b(topfit|fit|top|micro|microsoft|virtual reality|vr|ä+h*m*|hä*)\b', re.IGNORECASE)
|
||||||
@@ -37,31 +37,11 @@ TOPFIT_WORDS = (
|
|||||||
|
|
||||||
# LOEH_ID = 327126546970312739
|
# LOEH_ID = 327126546970312739
|
||||||
LOEH_ID = 254265844928872448
|
LOEH_ID = 254265844928872448
|
||||||
SIP_ID = 327126546970312739
|
OWNER_ID = 327126546970312739
|
||||||
|
|
||||||
config: dict = {
|
|
||||||
'loeh-timeout': 10,
|
|
||||||
'loeh-cooldown': 20,
|
|
||||||
'prefix': 'och!'
|
|
||||||
}
|
|
||||||
last_loeh = 0
|
last_loeh = 0
|
||||||
|
|
||||||
|
config_load()
|
||||||
def load_config() -> dict:
|
|
||||||
try:
|
|
||||||
config_file = open(CONFIG, 'r')
|
|
||||||
config.update(json.load(config_file))
|
|
||||||
except (json.JSONDecodeError, FileNotFoundError):
|
|
||||||
pass
|
|
||||||
return config
|
|
||||||
|
|
||||||
|
|
||||||
def save_config():
|
|
||||||
with open(CONFIG, 'w') as config_file:
|
|
||||||
json.dump(config, config_file)
|
|
||||||
|
|
||||||
|
|
||||||
load_config()
|
|
||||||
bot = commands.Bot(command_prefix=config.get('prefix'))
|
bot = commands.Bot(command_prefix=config.get('prefix'))
|
||||||
|
|
||||||
|
|
||||||
@@ -79,14 +59,14 @@ async def on_ready():
|
|||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_message(message: discord.Message):
|
async def on_message(message: discord.Message):
|
||||||
global last_loeh, config
|
global last_loeh
|
||||||
if not message.author.bot:
|
if message.guild is not None and not message.author.bot:
|
||||||
if LOEH_REGEX.match(message.content):
|
if config_get('loeh-enable') and LOEH_REGEX.match(message.content):
|
||||||
if message.author.id == LOEH_ID:
|
if message.author.id == LOEH_ID:
|
||||||
await message.channel.send("https://siphalor.de/img/spidy-is-that-you.jpg")
|
await message.channel.send("https://siphalor.de/img/spidy-is-that-you.jpg")
|
||||||
else:
|
else:
|
||||||
t = time.time()
|
t = time.time()
|
||||||
if t - config['loeh-cooldown'] <= last_loeh:
|
if t - config_get('loeh-cooldown', message.guild.id) <= last_loeh:
|
||||||
await message.channel.send('Don\'t try this to often, **' + message.author.nick +
|
await message.channel.send('Don\'t try this to often, **' + message.author.nick +
|
||||||
'**. That might backfire.')
|
'**. That might backfire.')
|
||||||
last_loeh = t
|
last_loeh = t
|
||||||
@@ -98,7 +78,7 @@ async def on_message(message: discord.Message):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
await loeh.edit(mute=True)
|
await loeh.edit(mute=True)
|
||||||
sleeper = asyncio.sleep(config.get('loeh-timeout'))
|
sleeper = asyncio.sleep(config_get('loeh-timeout', message.guild.id))
|
||||||
|
|
||||||
message: Optional[discord.Message] = await message.channel.send('Zu Befehl!')
|
message: Optional[discord.Message] = await message.channel.send('Zu Befehl!')
|
||||||
await sleeper
|
await sleeper
|
||||||
@@ -108,7 +88,8 @@ async def on_message(message: discord.Message):
|
|||||||
except (discord.Forbidden, discord.HTTPException):
|
except (discord.Forbidden, discord.HTTPException):
|
||||||
await message.channel.send('Failed to complete your command, Sir')
|
await message.channel.send('Failed to complete your command, Sir')
|
||||||
return
|
return
|
||||||
elif PING_REGEX.search(message.content):
|
elif config_get('inf19x-insiders-enable'):
|
||||||
|
if PING_REGEX.search(message.content):
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
title="*pinken, schwaches Verb*",
|
title="*pinken, schwaches Verb*",
|
||||||
description="ein Netzwerkgerät testweise ansprechen.\nOft falsch geschrieben als pin__g__en",
|
description="ein Netzwerkgerät testweise ansprechen.\nOft falsch geschrieben als pin__g__en",
|
||||||
@@ -135,34 +116,43 @@ async def on_message(message: discord.Message):
|
|||||||
|
|
||||||
@bot.command(name='config')
|
@bot.command(name='config')
|
||||||
async def config_prefix_command(ctx: commands.Context, cmd: str = '', key: str = '', *, val: str = ''):
|
async def config_prefix_command(ctx: commands.Context, cmd: str = '', key: str = '', *, val: str = ''):
|
||||||
if ctx.author.id != SIP_ID:
|
if ctx.guild is None:
|
||||||
await ctx.send('You\'re not allowed to touch my most valuable piece')
|
await ctx.send('You can\'t run config commands in private messages!')
|
||||||
return
|
return
|
||||||
if cmd == '':
|
if cmd == '':
|
||||||
await ctx.send('Use `config get` or `config set` to query for or update config values. Use `config list` to '
|
await ctx.send('Use `' + bot.command_prefix + 'config get` or `' + bot.command_prefix +
|
||||||
'see all config options')
|
'config set` to query for or update config values. Use `' + bot.command_prefix +
|
||||||
|
'config list` to see all config options')
|
||||||
elif cmd == 'list':
|
elif cmd == 'list':
|
||||||
await ctx.send('Available config options:\n'
|
msg = 'Available config options:'
|
||||||
' - `prefix`: Set the bot prefix\n'
|
for (key, value) in config_get_descriptions():
|
||||||
' - `loeh-timeout`: The timeout for Löh in seconds'
|
msg += '\n - `' + key + '`: ' + value[1]
|
||||||
' - `loeh-cooldown`: Number of seconds between timeouts')
|
await ctx.send(msg)
|
||||||
elif cmd == 'get':
|
elif cmd == 'get':
|
||||||
if key in config:
|
if key in config:
|
||||||
await ctx.send('`' + key + '` is set to ' + str(config.get(key)))
|
await ctx.send('`' + key + '` is set to `' + str(config_get(key, ctx.guild.id)) + '`')
|
||||||
else:
|
else:
|
||||||
await ctx.send('Unknown config option "' + key + '"')
|
await ctx.send('Unknown config option `' + key + '`')
|
||||||
elif cmd == 'set':
|
elif cmd == 'set':
|
||||||
try:
|
if ctx.author.guild_permissions.administrator:
|
||||||
|
await ctx.send(config_set(key, val, ctx.guild.id))
|
||||||
|
else:
|
||||||
|
await ctx.send('You\'re not allowed to change the configuration on this server!')
|
||||||
|
elif cmd == 'get-global':
|
||||||
|
if key in config:
|
||||||
|
await ctx.send('`' + key + '` is globally set to `' + str(config_get(key)) + '`')
|
||||||
|
else:
|
||||||
|
await ctx.send('Unknown config option `' + key + '`')
|
||||||
|
elif cmd == 'set-global':
|
||||||
|
if ctx.author.id == OWNER_ID:
|
||||||
|
msg = config_set(key, val)
|
||||||
if key == 'prefix':
|
if key == 'prefix':
|
||||||
config['prefix'] = val
|
bot.command_prefix = config_get('prefix')
|
||||||
elif key == 'loeh-timeout':
|
await ctx.send(msg)
|
||||||
config['loeh-timeout'] = int(val)
|
else:
|
||||||
elif key == 'loeh-cooldown':
|
await ctx.send('You\'re not allowed to change the global configuration!')
|
||||||
config['loeh-cooldown'] = int(val)
|
else:
|
||||||
save_config()
|
await ctx.send('Unknown command!')
|
||||||
await ctx.send('Config successfully updated')
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
await ctx.send('Invalid value "' + val + '" for config `' + key + '`')
|
|
||||||
|
|
||||||
|
|
||||||
bot.run(TOKEN)
|
bot.run(TOKEN)
|
||||||
|
|||||||
0
lib/__init__.py
Normal file
0
lib/__init__.py
Normal file
92
lib/config.py
Normal file
92
lib/config.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import json
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
CONFIG = 'config.json'
|
||||||
|
config: dict = {
|
||||||
|
'inf19x-insiders-enable': False,
|
||||||
|
'loeh-cooldown': 20,
|
||||||
|
'loeh-enable': False,
|
||||||
|
'loeh-timeout': 10,
|
||||||
|
'prefix': 'och!',
|
||||||
|
}
|
||||||
|
config_meta: dict = {
|
||||||
|
'inf19x-insiders-enable': (
|
||||||
|
True,
|
||||||
|
'Enables university insider jokes of INF19X'
|
||||||
|
),
|
||||||
|
'loeh-cooldown': (
|
||||||
|
True,
|
||||||
|
'Number of seconds between timeouts'
|
||||||
|
),
|
||||||
|
'loeh-enable': (
|
||||||
|
True,
|
||||||
|
'Enable time-outing Löh'
|
||||||
|
),
|
||||||
|
'loeh-timeout': (
|
||||||
|
True,
|
||||||
|
'The timeout for Löh in seconds'
|
||||||
|
),
|
||||||
|
'prefix': (
|
||||||
|
False,
|
||||||
|
'Sets the prefix for this bot'
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def config_load() -> dict:
|
||||||
|
try:
|
||||||
|
config_file = open(CONFIG, 'r')
|
||||||
|
config.update(json.load(config_file))
|
||||||
|
except (json.JSONDecodeError, FileNotFoundError):
|
||||||
|
pass
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def config_save():
|
||||||
|
with open(CONFIG, 'w') as config_file:
|
||||||
|
json.dump(config, config_file)
|
||||||
|
|
||||||
|
|
||||||
|
def config_get(key: str, guild: Optional[int] = None):
|
||||||
|
guild = str(guild)
|
||||||
|
if guild in config:
|
||||||
|
guild = config[guild]
|
||||||
|
if key in guild:
|
||||||
|
return guild[key]
|
||||||
|
return config[key]
|
||||||
|
|
||||||
|
|
||||||
|
def config_set(key: str, value, guild: Optional[int] = None) -> str:
|
||||||
|
if guild is None:
|
||||||
|
return _config_set_in_scope(config, key, value, type(config[key]))
|
||||||
|
else:
|
||||||
|
if config_meta[key][0]:
|
||||||
|
return _config_set_in_scope(config[str(guild)], key, value, type(config[key]))
|
||||||
|
else:
|
||||||
|
return 'This config can only be changed globally by the bot owner!'
|
||||||
|
|
||||||
|
|
||||||
|
def config_get_descriptions() -> iter:
|
||||||
|
return map(lambda entry: (entry[0], entry[1]), config_meta.items())
|
||||||
|
|
||||||
|
|
||||||
|
def _config_set_in_scope(scope: dict, key: str, value, cfg_type: type) -> str:
|
||||||
|
success = False
|
||||||
|
try:
|
||||||
|
if type(value) == cfg_type:
|
||||||
|
scope[key] = value
|
||||||
|
success = True
|
||||||
|
if type(value) == str:
|
||||||
|
if cfg_type == int:
|
||||||
|
scope[key] = int(value)
|
||||||
|
success = True
|
||||||
|
elif cfg_type == float:
|
||||||
|
scope[key] = float(value)
|
||||||
|
success = True
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
success = False
|
||||||
|
if success:
|
||||||
|
config_save()
|
||||||
|
return 'Successfully updated config for `' + key + '`'
|
||||||
|
else:
|
||||||
|
return 'Unable to determine type of given argument'
|
||||||
Reference in New Issue
Block a user