Initial Commit
This commit is contained in:
parent
d70c97da0c
commit
4eddf2aabd
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
bot_secrets.json
|
||||
16
.idea/dictionaries/Dustin_Pianalto.xml
generated
Normal file
16
.idea/dictionaries/Dustin_Pianalto.xml
generated
Normal file
@ -0,0 +1,16 @@
|
||||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="Dustin.Pianalto">
|
||||
<words>
|
||||
<w>aiohttp</w>
|
||||
<w>asctime</w>
|
||||
<w>chans</w>
|
||||
<w>coro</w>
|
||||
<w>customsearch</w>
|
||||
<w>emojis</w>
|
||||
<w>exts</w>
|
||||
<w>levelname</w>
|
||||
<w>lockdown</w>
|
||||
<w>msecs</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
||||
148
bot.py
Normal file
148
bot.py
Normal file
@ -0,0 +1,148 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import logging
|
||||
import json
|
||||
import aiohttp
|
||||
import asyncpg
|
||||
from concurrent import futures
|
||||
from typing import Dict
|
||||
|
||||
log_format = '{asctime}.{msecs:03.0f}|{levelname:<8}|{name}::{message}'
|
||||
date_format = '%Y.%m.%d %H.%M.%S'
|
||||
|
||||
log_dir = 'logs'
|
||||
|
||||
log_file = '{0}/submitter_{1}.log'.format(log_dir, datetime.now().strftime('%Y%m%d_%H%M%S%f'))
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG, style='{', filename=log_file, datefmt=date_format, format=log_format)
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter(log_format, style='{', datefmt=date_format)
|
||||
console_handler.setFormatter(formatter)
|
||||
logging.getLogger('').addHandler(console_handler)
|
||||
|
||||
extension_dir = 'exts'
|
||||
owner_id = 351794468870946827
|
||||
bot_config_file = 'bot_config.json'
|
||||
secrets_file = 'bot_secrets.json'
|
||||
|
||||
description = 'Submission Bot for Ark Smart Breeder'
|
||||
|
||||
|
||||
class Submitter(commands.Bot):
|
||||
def __init__(self, **kwargs):
|
||||
kwargs["command_prefix"] = self.get_custom_prefix
|
||||
super().__init__(**kwargs)
|
||||
self.aio_session = aiohttp.ClientSession(loop=self.loop)
|
||||
with open(f'{config_dir}{bot_config_file}') as file:
|
||||
self.bot_config = json.load(file)
|
||||
with open(f'{config_dir}{secrets_file}') as file:
|
||||
self.bot_secrets = json.load(file)
|
||||
self.guild_config = {}
|
||||
self.infected = {}
|
||||
self.TOKEN = self.bot_secrets['token']
|
||||
del self.bot_secrets['token']
|
||||
self.db_con = None
|
||||
self.default_prefix = '!'
|
||||
self.tpe = futures.ThreadPoolExecutor()
|
||||
self.unicode_emojis: Dict[str, str] = {
|
||||
'x': '❌',
|
||||
'y': '✅',
|
||||
'poop': '💩',
|
||||
'boom': '💥',
|
||||
'left_fist': '🤛',
|
||||
}
|
||||
|
||||
async def connect_db(self):
|
||||
self.db_con = await asyncpg.create_pool(host=self.bot_secrets['db_con']['host'],
|
||||
database=self.bot_secrets['db_con']['db_name'],
|
||||
user=self.bot_secrets['db_con']['user'],
|
||||
password=self.bot_secrets['db_con']['password'],
|
||||
loop=self.loop)
|
||||
|
||||
@staticmethod
|
||||
async def get_custom_prefix(bot_inst, message):
|
||||
return await bot_inst.db_con.fetchval('select prefix from guild_config where guild_id = $1',
|
||||
message.guild.id) or bot_inst.default_prefix
|
||||
|
||||
async def load_ext(self, ctx, mod=None):
|
||||
self.load_extension('{0}.{1}'.format(extension_dir, mod))
|
||||
if ctx is not None:
|
||||
await ctx.send('{0} loaded.'.format(mod))
|
||||
|
||||
async def unload_ext(self, ctx, mod=None):
|
||||
self.unload_extension('{0}.{1}'.format(extension_dir, mod))
|
||||
if ctx is not None:
|
||||
await ctx.send('{0} unloaded.'.format(mod))
|
||||
|
||||
async def close(self):
|
||||
await super().close()
|
||||
self.aio_session.close() # aiohttp is drunk and can't decide if it's a coro or not
|
||||
|
||||
|
||||
bot = Submitter(description=description, case_insensitive=True)
|
||||
|
||||
|
||||
@bot.command(hidden=True)
|
||||
@commands.is_owner()
|
||||
async def load(ctx, mod=None):
|
||||
"""Allows the owner to load extensions dynamically"""
|
||||
await bot.load_ext(ctx, mod)
|
||||
|
||||
|
||||
@bot.command(hidden=True)
|
||||
@commands.is_owner()
|
||||
async def reload(ctx, mod=None):
|
||||
"""Allows the owner to reload extensions dynamically"""
|
||||
if mod == 'all':
|
||||
load_list = bot.bot_config['load_list']
|
||||
for load_item in load_list:
|
||||
await bot.unload_ext(ctx, f'{load_item}')
|
||||
await bot.load_ext(ctx, f'{load_item}')
|
||||
else:
|
||||
await bot.unload_ext(ctx, mod)
|
||||
await bot.load_ext(ctx, mod)
|
||||
|
||||
|
||||
@bot.command(hidden=True)
|
||||
@commands.is_owner()
|
||||
async def unload(ctx, mod):
|
||||
"""Allows the owner to unload extensions dynamically"""
|
||||
await bot.unload_ext(ctx, mod)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_message(ctx):
|
||||
if not ctx.author.bot:
|
||||
if ctx.guild:
|
||||
if int(await bot.db_con.fetchval("select channel_lockdown from guild_config where guild_id = $1",
|
||||
ctx.guild.id)):
|
||||
if ctx.channel.id in json.loads(await bot.db_con.fetchval("select allowed_channels from guild_config "
|
||||
"where guild_id = $1",
|
||||
ctx.guild.id)):
|
||||
await bot.process_commands(ctx)
|
||||
else:
|
||||
await bot.process_commands(ctx)
|
||||
else:
|
||||
await bot.process_commands(ctx)
|
||||
|
||||
|
||||
@bot.event
|
||||
async def on_ready():
|
||||
if bot.db_con is None:
|
||||
await bot.connect_db()
|
||||
bot.recent_msgs = {}
|
||||
logging.info('Logged in as {0.name}|{0.id}'.format(bot.user))
|
||||
load_list = bot.bot_config['load_list']
|
||||
for load_item in load_list:
|
||||
await bot.load_ext(None, f'{load_item}')
|
||||
logging.info('Extension Loaded: {0}'.format(load_item))
|
||||
with open(f'{config_dir}reboot', 'r') as f:
|
||||
reboot = f.readlines()
|
||||
if int(reboot[0]) == 1:
|
||||
await bot.get_channel(int(reboot[1])).send('Restart Finished.')
|
||||
with open(f'{config_dir}reboot', 'w') as f:
|
||||
f.write(f'0')
|
||||
logging.info('Done loading, Submitter is active.')
|
||||
|
||||
bot.run(bot.TOKEN)
|
||||
6
config/bot_config.json
Normal file
6
config/bot_config.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"load_list": [
|
||||
"admin",
|
||||
"uploader"
|
||||
]
|
||||
}
|
||||
0
exts/__init__.py
Normal file
0
exts/__init__.py
Normal file
3
exts/admin.py
Normal file
3
exts/admin.py
Normal file
@ -0,0 +1,3 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import os
|
||||
0
exts/imports/__init__.py
Normal file
0
exts/imports/__init__.py
Normal file
83
exts/imports/utils.py
Normal file
83
exts/imports/utils.py
Normal file
@ -0,0 +1,83 @@
|
||||
from io import StringIO
|
||||
import sys
|
||||
import asyncio
|
||||
import discord
|
||||
from discord.ext.commands.formatter import Paginator
|
||||
|
||||
|
||||
class Capturing(list):
|
||||
def __enter__(self):
|
||||
self._stdout = sys.stdout
|
||||
sys.stdout = self._stringio = StringIO()
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.extend(self._stringio.getvalue().splitlines())
|
||||
del self._stringio # free up some memory
|
||||
sys.stdout = self._stdout
|
||||
|
||||
|
||||
def to_list_of_str(items, out: list=list(), level=1, recurse=0):
|
||||
def rec_loop(item, key, out, level):
|
||||
quote = '"'
|
||||
if type(item) == list:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}[')
|
||||
new_level = level + 1
|
||||
out = to_list_of_str(item, out, new_level, 1)
|
||||
out.append(f'{" "*level}]')
|
||||
elif type(item) == dict:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{{')
|
||||
new_level = level + 1
|
||||
out = to_list_of_str(item, out, new_level, 1)
|
||||
out.append(f'{" "*level}}}')
|
||||
else:
|
||||
out.append(f'{" "*level}{quote+key+quote+": " if key else ""}{repr(item)},')
|
||||
|
||||
if type(items) == list:
|
||||
if not recurse:
|
||||
out = list()
|
||||
out.append('[')
|
||||
for item in items:
|
||||
rec_loop(item, None, out, level)
|
||||
if not recurse:
|
||||
out.append(']')
|
||||
elif type(items) == dict:
|
||||
if not recurse:
|
||||
out = list()
|
||||
out.append('{')
|
||||
for key in items:
|
||||
rec_loop(items[key], key, out, level)
|
||||
if not recurse:
|
||||
out.append('}')
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def paginate(text, maxlen=1990):
|
||||
paginator = Paginator(prefix='```py', max_size=maxlen+10)
|
||||
if type(text) == list:
|
||||
data = to_list_of_str(text)
|
||||
elif type(text) == dict:
|
||||
data = to_list_of_str(text)
|
||||
else:
|
||||
data = str(text).split('\n')
|
||||
for line in data:
|
||||
if len(line) > maxlen:
|
||||
n = maxlen
|
||||
for l in [line[i:i+n] for i in range(0, len(line), n)]:
|
||||
paginator.add_line(l)
|
||||
else:
|
||||
paginator.add_line(line)
|
||||
return paginator.pages
|
||||
|
||||
|
||||
async def run_command(args):
|
||||
# Create subprocess
|
||||
process = await asyncio.create_subprocess_shell(
|
||||
args,
|
||||
# stdout must a pipe to be accessible as process.stdout
|
||||
stdout=asyncio.subprocess.PIPE)
|
||||
# Wait for the subprocess to finish
|
||||
stdout, stderr = await process.communicate()
|
||||
# Return stdout
|
||||
return stdout.decode().strip()
|
||||
24
exts/uploader.py
Normal file
24
exts/uploader.py
Normal file
@ -0,0 +1,24 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import zipfile
|
||||
import os
|
||||
|
||||
|
||||
class Uploader:
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@commands.command(name='submit', aliases=['upload'])
|
||||
async def upload_dino(self, ctx, official: str='unofficial'):
|
||||
if official == 'unofficial':
|
||||
|
||||
with zipfile.ZipFile('archive.zip') as z:
|
||||
for filename in z.namelist():
|
||||
if not os.path.isdir(filename):
|
||||
with z.open(filename) as f:
|
||||
for line in f:
|
||||
print(line)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(Uploader(bot))
|
||||
3
exts/utils.py
Normal file
3
exts/utils.py
Normal file
@ -0,0 +1,3 @@
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import os
|
||||
Loading…
x
Reference in New Issue
Block a user