Merge remote-tracking branch 'origin/development' into development
This commit is contained in:
commit
2fdac0b854
91
.gitignore
vendored
91
.gitignore
vendored
@ -1,6 +1,93 @@
|
|||||||
bot_secrets.json
|
bot_secrets.json
|
||||||
google_client_secret.json
|
google_client_secret.json
|
||||||
__pycache__/
|
|
||||||
logs/*
|
logs/*
|
||||||
*.sh.swp
|
*.sh.swp
|
||||||
.idea/
|
|
||||||
|
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-debug/
|
||||||
|
cmake-build-release/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
@ -84,7 +84,7 @@ class Admin:
|
|||||||
@commands.command(hidden=True)
|
@commands.command(hidden=True)
|
||||||
@commands.check(checks.is_guild_owner)
|
@commands.check(checks.is_guild_owner)
|
||||||
async def get_guild_config(self, ctx):
|
async def get_guild_config(self, ctx):
|
||||||
config = await self.bot.db_con.fetchval('select * from guild_config where guild_id = $1', ctx.guild.id)
|
config = await self.bot.db_con.fetchrow('select * from guild_config where guild_id = $1', ctx.guild.id)
|
||||||
configs = [str(config)[i:i+1990] for i in range(0, len(config), 1990)]
|
configs = [str(config)[i:i+1990] for i in range(0, len(config), 1990)]
|
||||||
await ctx.message.author.send(f'The current config for the {ctx.guild.name} guild is:\n')
|
await ctx.message.author.send(f'The current config for the {ctx.guild.name} guild is:\n')
|
||||||
admin_log.info(configs)
|
admin_log.info(configs)
|
||||||
@ -109,8 +109,9 @@ class Admin:
|
|||||||
|
|
||||||
@set.command(name='admin_chan', aliases=['ac', 'admin_chat', 'admin chat'])
|
@set.command(name='admin_chan', aliases=['ac', 'admin_chat', 'admin chat'])
|
||||||
async def _admin_channel(self, ctx, channel: discord.TextChannel=None):
|
async def _admin_channel(self, ctx, channel: discord.TextChannel=None):
|
||||||
|
"""Sets the channel for admin specific notifications"""
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
if channel is not None:
|
if channel is not None:
|
||||||
await self.bot.db_con.execute('update guild_config set admin_chat = $2 where guild_id = $1',
|
await self.bot.db_con.execute('update guild_config set admin_chat = $2 where guild_id = $1',
|
||||||
ctx.guild.id, channel.id)
|
ctx.guild.id, channel.id)
|
||||||
@ -118,8 +119,10 @@ class Admin:
|
|||||||
|
|
||||||
@set.command(name='channel_lockdown', aliases=['lockdown', 'restrict_access', 'cl'])
|
@set.command(name='channel_lockdown', aliases=['lockdown', 'restrict_access', 'cl'])
|
||||||
async def _channel_lockdown(self, ctx, config='true'):
|
async def _channel_lockdown(self, ctx, config='true'):
|
||||||
|
"""Toggles the channel lockdown restricting Geeksbot to only access channels defined in allowed_channels
|
||||||
|
If you run this before configuring allowed_channels it will tell you to run that command first."""
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
if str(config).lower() == 'true':
|
if str(config).lower() == 'true':
|
||||||
if await self.bot.db_con.fetchval('select allowed_channels from guild_config '
|
if await self.bot.db_con.fetchval('select allowed_channels from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id) is []:
|
'where guild_id = $1', ctx.guild.id) is []:
|
||||||
@ -143,8 +146,10 @@ class Admin:
|
|||||||
|
|
||||||
@add.command(name='allowed_channels', aliases=['channel', 'ac'])
|
@add.command(name='allowed_channels', aliases=['channel', 'ac'])
|
||||||
async def _allowed_channels(self, ctx, *, channels):
|
async def _allowed_channels(self, ctx, *, channels):
|
||||||
|
"""Allows Admin to restrict what channels Geeksbot is allowed to access
|
||||||
|
This only takes effect if channel_lockdown is enabled."""
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
channels = channels.lower().replace(' ', '').split(',')
|
channels = channels.lower().replace(' ', '').split(',')
|
||||||
added = ''
|
added = ''
|
||||||
for channel in channels:
|
for channel in channels:
|
||||||
@ -195,8 +200,12 @@ class Admin:
|
|||||||
@add.command(aliases=['prefix', 'p'])
|
@add.command(aliases=['prefix', 'p'])
|
||||||
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
async def add_prefix(self, ctx, *, prefix=None):
|
async def add_prefix(self, ctx, *, prefix=None):
|
||||||
|
"""Adds a guild specific prefix to the guild config
|
||||||
|
Note: This overwrites the default of g$. If you would
|
||||||
|
like to keep using g$ you will need to add it to the
|
||||||
|
Guild config as well."""
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
prefixes = await self.bot.db_con.fetchval('select prefix from guild_config where guild_id = $1',
|
prefixes = await self.bot.db_con.fetchval('select prefix from guild_config where guild_id = $1',
|
||||||
ctx.guild.id)
|
ctx.guild.id)
|
||||||
if prefix is None:
|
if prefix is None:
|
||||||
@ -224,8 +233,11 @@ class Admin:
|
|||||||
@remove.command(aliases=['prefix', 'p'])
|
@remove.command(aliases=['prefix', 'p'])
|
||||||
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
async def remove_prefix(self, ctx, *, prefix=None):
|
async def remove_prefix(self, ctx, *, prefix=None):
|
||||||
|
"""Removes a guild specific prefix from the guild config
|
||||||
|
If the last prefix is removed then Geeksbot will default
|
||||||
|
Back to g$"""
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
prefixes = await self.bot.db_con.fetchval('select prefix from guild_config where guild_id = $1',
|
prefixes = await self.bot.db_con.fetchval('select prefix from guild_config where guild_id = $1',
|
||||||
ctx.guild.id)
|
ctx.guild.id)
|
||||||
found = 0
|
found = 0
|
||||||
@ -260,6 +272,9 @@ class Admin:
|
|||||||
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
@commands.check(checks.is_guild_owner)
|
@commands.check(checks.is_guild_owner)
|
||||||
async def _add_admin_role(self, ctx, role=None):
|
async def _add_admin_role(self, ctx, role=None):
|
||||||
|
"""The Guild owner can add a role to the admin list
|
||||||
|
Allowing members of that role to run admin commands
|
||||||
|
on the current guild."""
|
||||||
role = discord.utils.get(ctx.guild.roles, name=role)
|
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||||
if role is not None:
|
if role is not None:
|
||||||
roles = json.loads(await self.bot.db_con.fetchval('select admin_roles from guild_config '
|
roles = json.loads(await self.bot.db_con.fetchval('select admin_roles from guild_config '
|
||||||
@ -278,6 +293,7 @@ class Admin:
|
|||||||
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
@commands.cooldown(1, 5, type=commands.BucketType.guild)
|
||||||
@commands.check(checks.is_guild_owner)
|
@commands.check(checks.is_guild_owner)
|
||||||
async def _remove_admin_role(self, ctx, role=None):
|
async def _remove_admin_role(self, ctx, role=None):
|
||||||
|
"""The Guild owner can remove a role from the admin list"""
|
||||||
role = discord.utils.get(ctx.guild.roles, name=role)
|
role = discord.utils.get(ctx.guild.roles, name=role)
|
||||||
if role is not None:
|
if role is not None:
|
||||||
roles = json.loads(await self.bot.db_con.fetchval('select admin_roles from guild_config '
|
roles = json.loads(await self.bot.db_con.fetchval('select admin_roles from guild_config '
|
||||||
|
|||||||
@ -84,7 +84,7 @@ class BotEvents:
|
|||||||
ctx.webhook_id, [json.dumps({'id': a.id, 'size': a.size, 'height': a.height, 'width': a.width,
|
ctx.webhook_id, [json.dumps({'id': a.id, 'size': a.size, 'height': a.height, 'width': a.width,
|
||||||
'filename': a.filename, 'url': a.url}) for a in ctx.attachments],
|
'filename': a.filename, 'url': a.url}) for a in ctx.attachments],
|
||||||
ctx.pinned, [json.dumps({'emoji': r.emoji, 'count': r.count}) for r in ctx.reactions],
|
ctx.pinned, [json.dumps({'emoji': r.emoji, 'count': r.count}) for r in ctx.reactions],
|
||||||
ctx.guild.id, ctx.created_at, ctx.system_content, ctx.author.id]
|
ctx.guild.id if ctx.guild else ctx.author.id, ctx.created_at, ctx.system_content, ctx.author.id]
|
||||||
await self.bot.db_con.execute(sql, *msg_data)
|
await self.bot.db_con.execute(sql, *msg_data)
|
||||||
if ctx.guild:
|
if ctx.guild:
|
||||||
if ctx.author != ctx.guild.me:
|
if ctx.author != ctx.guild.me:
|
||||||
|
|||||||
@ -65,13 +65,14 @@ class Fun:
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
||||||
async def slap(self, ctx, member: discord.Member):
|
async def slap(self, ctx, member: discord.Member):
|
||||||
|
trout = await self.bot.db_con.fetchval("select code from geeksbot_emojis where id = 449083238766477312")
|
||||||
if member.id == self.bot.user.id and ctx.author.id != owner_id:
|
if member.id == self.bot.user.id and ctx.author.id != owner_id:
|
||||||
await ctx.send(f'You rolled a Critical Fail...\nThe trout bounces off and rebounds on the attacker.')
|
await ctx.send(f'You rolled a Critical Fail...\nThe trout bounces off and rebounds on the attacker.')
|
||||||
await ctx.send(f'{ctx.author.mention} '
|
await ctx.send(f'{ctx.author.mention} '
|
||||||
f'You slap yourself in the face with a large trout <:trout:408543365085397013>')
|
f'You slap yourself in the face with a large trout {trout}')
|
||||||
else:
|
else:
|
||||||
await ctx.send(f'{ctx.author.display_name} slaps '
|
await ctx.send(f'{ctx.author.display_name} slaps '
|
||||||
f'{member.mention} around a bit with a large trout <:trout:408543365085397013>')
|
f'{member.mention} around a bit with a large trout {trout}')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_factorial(number):
|
def get_factorial(number):
|
||||||
@ -155,7 +156,7 @@ class Fun:
|
|||||||
trans = await self.bot.db_con.fetchval('select code from geeksbot_emojis where id = 405943174809255956')
|
trans = await self.bot.db_con.fetchval('select code from geeksbot_emojis where id = 405943174809255956')
|
||||||
msg = await ctx.send(f'{member.mention}{trans*20}{self.bot.unicode_emojis["left_fist"]}')
|
msg = await ctx.send(f'{member.mention}{trans*20}{self.bot.unicode_emojis["left_fist"]}')
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.5)
|
||||||
await msg.edit(content=f'{member.mention}{trans*(20-(i*5))}{self.bot.unicode_emojis["left_fist"]}')
|
await msg.edit(content=f'{member.mention}{trans*(20-(i*5))}{self.bot.unicode_emojis["left_fist"]}')
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
await msg.edit(content=f'{self.bot.unicode_emojis["boom"]}')
|
await msg.edit(content=f'{self.bot.unicode_emojis["boom"]}')
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import asyncio
|
|||||||
import discord
|
import discord
|
||||||
from discord.ext.commands.formatter import Paginator
|
from discord.ext.commands.formatter import Paginator
|
||||||
from . import checks
|
from . import checks
|
||||||
|
import re
|
||||||
|
import typing
|
||||||
|
|
||||||
|
|
||||||
class Capturing(list):
|
class Capturing(list):
|
||||||
@ -21,7 +23,7 @@ class Capturing(list):
|
|||||||
async def mute(bot, ctx, admin=0, member_id=None):
|
async def mute(bot, ctx, admin=0, member_id=None):
|
||||||
mute_role = bot.db_con.fetchval(f'select muted_role from guild_config where guild_id = $1', ctx.guild.id)
|
mute_role = bot.db_con.fetchval(f'select muted_role from guild_config where guild_id = $1', ctx.guild.id)
|
||||||
if mute_role:
|
if mute_role:
|
||||||
if admin or checks.is_admin(bot, ctx):
|
if admin or await checks.is_admin(bot, ctx):
|
||||||
if ctx.guild.me.guild_permissions.manage_roles:
|
if ctx.guild.me.guild_permissions.manage_roles:
|
||||||
if member_id:
|
if member_id:
|
||||||
ctx.guild.get_member(member_id).edit(roles=[discord.utils.get(ctx.guild.roles, id=mute_role)])
|
ctx.guild.get_member(member_id).edit(roles=[discord.utils.get(ctx.guild.roles, id=mute_role)])
|
||||||
@ -64,6 +66,11 @@ def to_list_of_str(items, out: list=list(), level=1, recurse=0):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def replace_text_ignorecase(in_str: str, old: str, new: str='') -> str:
|
||||||
|
re_replace = re.compile(re.escape(old), re.IGNORECASE)
|
||||||
|
return re_replace.sub(f'{new}', in_str)
|
||||||
|
|
||||||
|
|
||||||
def paginate(text, maxlen=1990):
|
def paginate(text, maxlen=1990):
|
||||||
paginator = Paginator(prefix='```py', max_size=maxlen+10)
|
paginator = Paginator(prefix='```py', max_size=maxlen+10)
|
||||||
if type(text) == list:
|
if type(text) == list:
|
||||||
@ -93,4 +100,22 @@ async def run_command(args):
|
|||||||
# Return stdout
|
# Return stdout
|
||||||
return stdout.decode().strip()
|
return stdout.decode().strip()
|
||||||
|
|
||||||
|
|
||||||
# TODO Add Paginator
|
# TODO Add Paginator
|
||||||
|
class Paginator:
|
||||||
|
def __init__(self,
|
||||||
|
max_chars: int=1990,
|
||||||
|
max_lines: int=20,
|
||||||
|
prefix: str='```md',
|
||||||
|
suffix: str='```',
|
||||||
|
page_break: str=''):
|
||||||
|
assert 0 < max_lines <= max_chars
|
||||||
|
|
||||||
|
self._parts = list()
|
||||||
|
self._prefix = prefix
|
||||||
|
self._suffix = suffix
|
||||||
|
self._max_chars = max_chars if max_chars + len(prefix) + len(suffix) + 2 <= 2000 \
|
||||||
|
else 2000 - len(prefix) - len(suffix) - 2
|
||||||
|
self._max_lines = max_lines - (prefix + suffix).count('\n') + 1
|
||||||
|
self._page_break = page_break
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ class Patreon:
|
|||||||
|
|
||||||
@commands.command(aliases=['patreon_message'])
|
@commands.command(aliases=['patreon_message'])
|
||||||
async def set_patreon_message(self, ctx, message):
|
async def set_patreon_message(self, ctx, message):
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
patreon_message = await self.bot.db_con.fetchval('select patreon_message from guild_config '
|
patreon_message = await self.bot.db_con.fetchval('select patreon_message from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id)
|
'where guild_id = $1', ctx.guild.id)
|
||||||
if message == patreon_message:
|
if message == patreon_message:
|
||||||
@ -47,7 +47,7 @@ class Patreon:
|
|||||||
|
|
||||||
@commands.command(aliases=['add_patreon', 'set_patreon'])
|
@commands.command(aliases=['add_patreon', 'set_patreon'])
|
||||||
async def add_patreon_info(self, ctx, name, url):
|
async def add_patreon_info(self, ctx, name, url):
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
patreon_info = await self.bot.db_con.fetchval('select patreon_links from guild_config where guild_id = $1',
|
patreon_info = await self.bot.db_con.fetchval('select patreon_links from guild_config where guild_id = $1',
|
||||||
ctx.guild.id)
|
ctx.guild.id)
|
||||||
patreon_links = {}
|
patreon_links = {}
|
||||||
@ -66,7 +66,7 @@ class Patreon:
|
|||||||
|
|
||||||
@commands.command(aliases=['remove_patreon'])
|
@commands.command(aliases=['remove_patreon'])
|
||||||
async def remove_patreon_info(self, ctx, name):
|
async def remove_patreon_info(self, ctx, name):
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
patreon_info = await self.bot.db_con.fetchval('select patreon_links from guild_config where guild_id = $1',
|
patreon_info = await self.bot.db_con.fetchval('select patreon_links from guild_config where guild_id = $1',
|
||||||
ctx.guild.id)
|
ctx.guild.id)
|
||||||
if patreon_info:
|
if patreon_info:
|
||||||
@ -86,7 +86,7 @@ class Patreon:
|
|||||||
|
|
||||||
@commands.command()
|
@commands.command()
|
||||||
async def enable_patreon(self, ctx, state: bool=True):
|
async def enable_patreon(self, ctx, state: bool=True):
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
patreon_status = await self.bot.db_con.fetchval('select patreon_enabled from guild_config '
|
patreon_status = await self.bot.db_con.fetchval('select patreon_enabled from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id)
|
'where guild_id = $1', ctx.guild.id)
|
||||||
if patreon_status and state:
|
if patreon_status and state:
|
||||||
|
|||||||
20
exts/rcon.py
20
exts/rcon.py
@ -138,7 +138,7 @@ class Rcon:
|
|||||||
first_last
|
first_last
|
||||||
"first last"
|
"first last"
|
||||||
To view all the valid ARK servers for this guild see list_ark_servers."""
|
To view all the valid ARK servers for this guild see list_ark_servers."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
if server is not None:
|
if server is not None:
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
||||||
'from guild_config where guild_id = $1',
|
'from guild_config where guild_id = $1',
|
||||||
@ -200,7 +200,7 @@ class Rcon:
|
|||||||
async def end_monitor_chat(self, ctx, *, server=None):
|
async def end_monitor_chat(self, ctx, *, server=None):
|
||||||
"""Ends chat monitoring on the specified server.
|
"""Ends chat monitoring on the specified server.
|
||||||
Context is the same as monitor_chat"""
|
Context is the same as monitor_chat"""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
if server is not None:
|
if server is not None:
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
||||||
'from guild_config where guild_id = $1',
|
'from guild_config where guild_id = $1',
|
||||||
@ -229,7 +229,7 @@ class Rcon:
|
|||||||
first_last
|
first_last
|
||||||
"first last"
|
"first last"
|
||||||
To view all the valid ARK servers for this guild see list_ark_servers."""
|
To view all the valid ARK servers for this guild see list_ark_servers."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
if server is not None:
|
if server is not None:
|
||||||
@ -267,7 +267,7 @@ class Rcon:
|
|||||||
async def add_rcon_server(self, ctx, server, ip, port, password):
|
async def add_rcon_server(self, ctx, server, ip, port, password):
|
||||||
"""Adds the specified server to the current guild\'s rcon config.
|
"""Adds the specified server to the current guild\'s rcon config.
|
||||||
All strings (<server>, <ip>, <password>) must be contained inside double quotes."""
|
All strings (<server>, <ip>, <password>) must be contained inside double quotes."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
server = server.title()
|
server = server.title()
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
@ -296,7 +296,7 @@ class Rcon:
|
|||||||
async def remove_rcon_server(self, ctx, server):
|
async def remove_rcon_server(self, ctx, server):
|
||||||
"""removes the specified server from the current guild\'s rcon config.
|
"""removes the specified server from the current guild\'s rcon config.
|
||||||
All strings <server> must be contained inside double quotes."""
|
All strings <server> must be contained inside double quotes."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
server = server.title()
|
server = server.title()
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
@ -316,7 +316,7 @@ class Rcon:
|
|||||||
"""Adds the included Steam 64 IDs to the running whitelist on all the ARK servers in the current guild\'s rcon config.
|
"""Adds the included Steam 64 IDs to the running whitelist on all the ARK servers in the current guild\'s rcon config.
|
||||||
Steam 64 IDs should be a comma seperated list of IDs.
|
Steam 64 IDs should be a comma seperated list of IDs.
|
||||||
Example: 76561198024193239,76561198024193239,76561198024193239"""
|
Example: 76561198024193239,76561198024193239,76561198024193239"""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
if steam_ids is not None:
|
if steam_ids is not None:
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections '
|
||||||
'from guild_config where guild_id = $1',
|
'from guild_config where guild_id = $1',
|
||||||
@ -364,7 +364,7 @@ class Rcon:
|
|||||||
"""Runs SaveWorld on the specified ARK server.
|
"""Runs SaveWorld on the specified ARK server.
|
||||||
If a server is not specified it will default to running saveworld on all servers in the guild\'s config.
|
If a server is not specified it will default to running saveworld on all servers in the guild\'s config.
|
||||||
Will print out "World Saved" for each server when the command completes successfully."""
|
Will print out "World Saved" for each server when the command completes successfully."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
success_msg = 'Running saveworld'
|
success_msg = 'Running saveworld'
|
||||||
@ -406,7 +406,7 @@ class Rcon:
|
|||||||
"""Sends a broadcast message to all servers in the guild config.
|
"""Sends a broadcast message to all servers in the guild config.
|
||||||
The message will be prefixed with the Discord name of the person running the command.
|
The message will be prefixed with the Discord name of the person running the command.
|
||||||
Will print "Success" for each server once the broadcast is sent."""
|
Will print "Success" for each server once the broadcast is sent."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
if message is not None:
|
if message is not None:
|
||||||
@ -443,7 +443,7 @@ class Rcon:
|
|||||||
The message will be prefixed with the Discord name of the person running the command.
|
The message will be prefixed with the Discord name of the person running the command.
|
||||||
If <server> has more than one word in it's name it will either need to be surrounded
|
If <server> has more than one word in it's name it will either need to be surrounded
|
||||||
by double quotes or the words separated by _"""
|
by double quotes or the words separated by _"""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
if server is not None:
|
if server is not None:
|
||||||
@ -481,7 +481,7 @@ class Rcon:
|
|||||||
and these channel's permissions will be synced to the category.
|
and these channel's permissions will be synced to the category.
|
||||||
These channels will be added to the guild's rcon config and are where the
|
These channels will be added to the guild's rcon config and are where the
|
||||||
server chat messages will be sent when monitor_chat is run."""
|
server chat messages will be sent when monitor_chat is run."""
|
||||||
if checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_rcon_admin(self.bot, ctx):
|
||||||
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
rcon_connections = json.loads(await self.bot.db_con.fetchval('select rcon_connections from guild_config '
|
||||||
'where guild_id = $1', ctx.guild.id))
|
'where guild_id = $1', ctx.guild.id))
|
||||||
edited = 0
|
edited = 0
|
||||||
|
|||||||
12
exts/repl.py
12
exts/repl.py
@ -69,16 +69,8 @@ class Repl:
|
|||||||
await ctx.message.add_reaction('✅')
|
await ctx.message.add_reaction('✅')
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
if ret is None:
|
output = f'{value}\nReturned: {ret}'
|
||||||
if value:
|
for page in paginate(output):
|
||||||
for page in paginate(value):
|
|
||||||
await ctx.send(page)
|
|
||||||
else:
|
|
||||||
self._last_result = ret
|
|
||||||
if value:
|
|
||||||
for page in paginate(value):
|
|
||||||
await ctx.send(page)
|
|
||||||
for page in paginate(ret):
|
|
||||||
await ctx.send(page)
|
await ctx.send(page)
|
||||||
|
|
||||||
@commands.command(hidden=True)
|
@commands.command(hidden=True)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import psutil
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import asyncio
|
import asyncio
|
||||||
import async_timeout
|
import async_timeout
|
||||||
from .imports import checks
|
from .imports import checks, utils
|
||||||
import pytz
|
import pytz
|
||||||
import gspread
|
import gspread
|
||||||
from oauth2client.service_account import ServiceAccountCredentials
|
from oauth2client.service_account import ServiceAccountCredentials
|
||||||
@ -18,6 +18,8 @@ from mpl_toolkits.basemap import Basemap
|
|||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from dateutil.parser import parse
|
||||||
|
from copy import copy
|
||||||
|
|
||||||
config_dir = 'config/'
|
config_dir = 'config/'
|
||||||
admin_id_file = 'admin_ids'
|
admin_id_file = 'admin_ids'
|
||||||
@ -29,6 +31,7 @@ invite_match = '(https?://)?(www.)?discord(app.com/(invite|oauth2)|.gg|.io)/[\w\
|
|||||||
|
|
||||||
utils_log = logging.getLogger('utils')
|
utils_log = logging.getLogger('utils')
|
||||||
clock_emojis = ['🕛', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚']
|
clock_emojis = ['🕛', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚']
|
||||||
|
replace_tzs = {'MST': 'US/Mountain', 'HST': 'US/Hawaii', 'EST': 'US/Eastern'}
|
||||||
|
|
||||||
|
|
||||||
class Utils:
|
class Utils:
|
||||||
@ -59,6 +62,7 @@ class Utils:
|
|||||||
@commands.command()
|
@commands.command()
|
||||||
@commands.is_owner()
|
@commands.is_owner()
|
||||||
async def sysinfo(self, ctx):
|
async def sysinfo(self, ctx):
|
||||||
|
"""WIP Gets current system status for the server that Geeksbot is running on."""
|
||||||
await ctx.send(f'```ml\n'
|
await ctx.send(f'```ml\n'
|
||||||
f'CPU Percentages: {psutil.cpu_percent(percpu=True)}\n'
|
f'CPU Percentages: {psutil.cpu_percent(percpu=True)}\n'
|
||||||
f'Memory Usage: {psutil.virtual_memory().percent}%\n'
|
f'Memory Usage: {psutil.virtual_memory().percent}%\n'
|
||||||
@ -292,7 +296,7 @@ class Utils:
|
|||||||
title=f'Admin Help Requests',
|
title=f'Admin Help Requests',
|
||||||
color=discord.Colour.green()
|
color=discord.Colour.green()
|
||||||
)
|
)
|
||||||
if checks.is_admin(self.bot, ctx) or checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx) or await checks.is_rcon_admin(self.bot, ctx):
|
||||||
if assigned_to is None:
|
if assigned_to is None:
|
||||||
requests = await self.bot.db_con.fetch(f'select * from admin_requests where guild_orig = $1 '
|
requests = await self.bot.db_con.fetch(f'select * from admin_requests where guild_orig = $1 '
|
||||||
f'and completed_time is null', ctx.guild.id)
|
f'and completed_time is null', ctx.guild.id)
|
||||||
@ -312,8 +316,8 @@ class Utils:
|
|||||||
else:
|
else:
|
||||||
em.add_field(name='There are no pending requests for this guild.', value='', inline=False)
|
em.add_field(name='There are no pending requests for this guild.', value='', inline=False)
|
||||||
else:
|
else:
|
||||||
if checks.check_admin_role(self.bot, ctx, assigned_to)\
|
if await checks.check_admin_role(self.bot, ctx, assigned_to)\
|
||||||
or checks.check_rcon_role(self.bot, ctx, assigned_to):
|
or await checks.check_rcon_role(self.bot, ctx, assigned_to):
|
||||||
requests = await self.bot.db_con.fetch('select * from admin_requests where assigned_to = $1 '
|
requests = await self.bot.db_con.fetch('select * from admin_requests where assigned_to = $1 '
|
||||||
'and guild_orig = $2 and completed_time is null',
|
'and guild_orig = $2 and completed_time is null',
|
||||||
assigned_to.id, ctx.guild.id)
|
assigned_to.id, ctx.guild.id)
|
||||||
@ -359,7 +363,7 @@ class Utils:
|
|||||||
"""Allows Admin to close admin help tickets.
|
"""Allows Admin to close admin help tickets.
|
||||||
[request_id] must be a valid integer pointing to an open Request ID
|
[request_id] must be a valid integer pointing to an open Request ID
|
||||||
"""
|
"""
|
||||||
if checks.is_admin(self.bot, ctx) or checks.is_rcon_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx) or await checks.is_rcon_admin(self.bot, ctx):
|
||||||
if request_ids:
|
if request_ids:
|
||||||
request_ids = request_ids.replace(' ', '').split(',')
|
request_ids = request_ids.replace(' ', '').split(',')
|
||||||
for request_id in request_ids:
|
for request_id in request_ids:
|
||||||
@ -429,7 +433,11 @@ class Utils:
|
|||||||
@commands.command(name='localtime', aliases=['time', 'lt'])
|
@commands.command(name='localtime', aliases=['time', 'lt'])
|
||||||
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
||||||
async def get_localtime(self, ctx, timezone: str='Anchorage'):
|
async def get_localtime(self, ctx, timezone: str='Anchorage'):
|
||||||
|
"""Shows the current time localized to the timezone given
|
||||||
|
This defaults to the Bot's local timezone of Anchorage Alaska USA if none are given."""
|
||||||
|
|
||||||
em = discord.Embed()
|
em = discord.Embed()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tz = pytz.timezone(timezone)
|
tz = pytz.timezone(timezone)
|
||||||
localtime = datetime.now(tz=tz)
|
localtime = datetime.now(tz=tz)
|
||||||
@ -450,9 +458,76 @@ class Utils:
|
|||||||
em.colour = discord.Colour.red()
|
em.colour = discord.Colour.red()
|
||||||
await ctx.send(embed=em)
|
await ctx.send(embed=em)
|
||||||
|
|
||||||
|
# noinspection PyUnboundLocalVariable
|
||||||
|
@commands.command(name='gettimein', aliases=['timein', 'gti'])
|
||||||
|
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
||||||
|
async def get_time_in_timezone(self, ctx, timezone: str='US/Eastern', *, time: str=None):
|
||||||
|
em = discord.Embed()
|
||||||
|
|
||||||
|
if time is None:
|
||||||
|
em.set_footer(text='Time not given... using current UTC time.')
|
||||||
|
in_time = datetime.utcnow()
|
||||||
|
parsed_tz = pytz.timezone('UTC')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
orig_time = copy(time)
|
||||||
|
split_time = time.split()
|
||||||
|
try:
|
||||||
|
parsed_tz = pytz.timezone(replace_tzs.get(split_time[-1].upper()) or split_time[-1])
|
||||||
|
time = utils.replace_text_ignorecase(time, old=split_time[-1], new='')
|
||||||
|
except pytz.exceptions.UnknownTimeZoneError:
|
||||||
|
for tz in pytz.all_timezones:
|
||||||
|
if split_time[-1].lower() in tz.lower():
|
||||||
|
time = utils.replace_text_ignorecase(time, old=split_time[-1], new='')
|
||||||
|
if tz in replace_tzs:
|
||||||
|
tz = replace_tzs['tz']
|
||||||
|
parsed_tz = pytz.timezone(tz)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
em.set_footer(text='Valid timezone not found in time string. Using UTC...')
|
||||||
|
parsed_tz = pytz.timezone('UTC')
|
||||||
|
if not time.isspace() and not time == '':
|
||||||
|
in_time = parse(time.upper())
|
||||||
|
in_time = parsed_tz.localize(in_time)
|
||||||
|
else:
|
||||||
|
em.set_footer(text='Time not given. Using current time.')
|
||||||
|
in_time = parsed_tz.localize(datetime.utcnow())
|
||||||
|
except ValueError:
|
||||||
|
raise commands.CommandError(f'For some reason I can\'t parse this time string: \n'
|
||||||
|
f'{orig_time} {time} {parsed_tz}\n'
|
||||||
|
f'Examples of valid time strings are in my help documentation.\n'
|
||||||
|
f'Please try again.')
|
||||||
|
try:
|
||||||
|
out_tz = pytz.timezone(timezone)
|
||||||
|
except pytz.exceptions.UnknownTimeZoneError:
|
||||||
|
for tz in pytz.all_timezones:
|
||||||
|
if timezone.lower() in tz.lower():
|
||||||
|
out_tz = pytz.timezone(tz)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
out_tz = None
|
||||||
|
em.title = 'Unknown Timezone.'
|
||||||
|
em.colour = discord.Colour.red()
|
||||||
|
finally:
|
||||||
|
if out_tz:
|
||||||
|
out_time = in_time.astimezone(out_tz)
|
||||||
|
em.add_field(name=f'{parsed_tz}',
|
||||||
|
value=f'{clock_emojis[(in_time.hour % 12)]} {in_time.strftime("%c")}', inline=False)
|
||||||
|
em.add_field(name=f'{out_tz}',
|
||||||
|
value=f'{clock_emojis[(out_time.hour % 12)]} {out_time.strftime("%c")}', inline=False)
|
||||||
|
em.colour = self.bot.embed_color
|
||||||
|
await ctx.send(embed=em)
|
||||||
|
|
||||||
@commands.command(name='purge', aliases=['clean', 'erase'])
|
@commands.command(name='purge', aliases=['clean', 'erase'])
|
||||||
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
||||||
async def purge_messages(self, ctx, number: int=20, member: discord.Member=None):
|
async def purge_messages(self, ctx, number: int=20, member: discord.Member=None):
|
||||||
|
"""Gives Admin the ability to quickly clear messages from a channel
|
||||||
|
By default this will only purge messages sent by Geeksbot and any messages that appear to
|
||||||
|
have called Geeksbot (aka start with one of the Geeksbot's prefixes for this Guild)
|
||||||
|
If you want to purge messages from a different user you must provide a number and member
|
||||||
|
|
||||||
|
Note: Geeksbot will not find <number> of messages by the given member, it will instead
|
||||||
|
search the last <number> messages in the channel and delete any by the given member"""
|
||||||
def is_me(message):
|
def is_me(message):
|
||||||
if message.author == self.bot.user:
|
if message.author == self.bot.user:
|
||||||
return True
|
return True
|
||||||
@ -471,7 +546,7 @@ class Utils:
|
|||||||
def is_author(message):
|
def is_author(message):
|
||||||
return message.author == ctx.author
|
return message.author == ctx.author
|
||||||
|
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
if member:
|
if member:
|
||||||
deleted = await ctx.channel.purge(limit=number, check=is_member)
|
deleted = await ctx.channel.purge(limit=number, check=is_member)
|
||||||
if member != ctx.author:
|
if member != ctx.author:
|
||||||
@ -487,7 +562,10 @@ class Utils:
|
|||||||
@commands.command(name='purge_all', aliases=['cls', 'clear'])
|
@commands.command(name='purge_all', aliases=['cls', 'clear'])
|
||||||
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
||||||
async def purge_all(self, ctx, number: int=20, contents: str='all'):
|
async def purge_all(self, ctx, number: int=20, contents: str='all'):
|
||||||
if checks.is_admin(self.bot, ctx):
|
"""Will delete all of the last <number> of messages from the channel
|
||||||
|
If <contents> is not 'all' then only messages containing <contents>
|
||||||
|
will be deleted."""
|
||||||
|
if await checks.is_admin(self.bot, ctx):
|
||||||
if contents != 'all':
|
if contents != 'all':
|
||||||
deleted = await ctx.channel.purge(limit=number, check=lambda message: message.content == contents)
|
deleted = await ctx.channel.purge(limit=number, check=lambda message: message.content == contents)
|
||||||
else:
|
else:
|
||||||
@ -500,6 +578,7 @@ class Utils:
|
|||||||
|
|
||||||
@commands.command(name='google', aliases=['g', 'search'])
|
@commands.command(name='google', aliases=['g', 'search'])
|
||||||
async def google_search(self, ctx, *, search):
|
async def google_search(self, ctx, *, search):
|
||||||
|
"""WIP Search Google for the given string"""
|
||||||
res = self.bot.gcs_service.cse().list(q=search, cx=self.bot.bot_secrets['cx']).execute()
|
res = self.bot.gcs_service.cse().list(q=search, cx=self.bot.bot_secrets['cx']).execute()
|
||||||
results = res['items'][:4]
|
results = res['items'][:4]
|
||||||
em = discord.Embed()
|
em = discord.Embed()
|
||||||
@ -513,7 +592,7 @@ class Utils:
|
|||||||
|
|
||||||
@commands.command(hidden=True, name='sheets')
|
@commands.command(hidden=True, name='sheets')
|
||||||
async def google_sheets(self, ctx, member: discord.Member):
|
async def google_sheets(self, ctx, member: discord.Member):
|
||||||
if checks.is_admin(self.bot, ctx):
|
if await checks.is_admin(self.bot, ctx):
|
||||||
scope = ['https://spreadsheets.google.com/feeds',
|
scope = ['https://spreadsheets.google.com/feeds',
|
||||||
'https://www.googleapis.com/auth/drive']
|
'https://www.googleapis.com/auth/drive']
|
||||||
credentials = ServiceAccountCredentials.from_json_keyfile_name('config/google_client_secret.json', scope)
|
credentials = ServiceAccountCredentials.from_json_keyfile_name('config/google_client_secret.json', scope)
|
||||||
@ -538,6 +617,7 @@ class Utils:
|
|||||||
|
|
||||||
@commands.command(name='iss')
|
@commands.command(name='iss')
|
||||||
async def iss_loc(self, ctx):
|
async def iss_loc(self, ctx):
|
||||||
|
"""WIP Locates the International Space Station and display on a map"""
|
||||||
def gen_image(iss_loc):
|
def gen_image(iss_loc):
|
||||||
lat = iss_loc['latitude']
|
lat = iss_loc['latitude']
|
||||||
lon = iss_loc['longitude']
|
lon = iss_loc['longitude']
|
||||||
@ -561,6 +641,8 @@ class Utils:
|
|||||||
|
|
||||||
@commands.command(name='location', aliases=['loc', 'map'])
|
@commands.command(name='location', aliases=['loc', 'map'])
|
||||||
async def map_location(self, ctx, *, location):
|
async def map_location(self, ctx, *, location):
|
||||||
|
"""WIP Displays the given location on a map
|
||||||
|
Note: This is SLOW!!! Be prepared to wait up to a minute for the result"""
|
||||||
|
|
||||||
def draw_map(m, scale=1):
|
def draw_map(m, scale=1):
|
||||||
# draw a shaded-relief image
|
# draw a shaded-relief image
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
@ -56,6 +57,7 @@ class Geeksbot(commands.Bot):
|
|||||||
self.guild_config = {}
|
self.guild_config = {}
|
||||||
self.infected = {}
|
self.infected = {}
|
||||||
self.TOKEN = self.bot_secrets['token']
|
self.TOKEN = self.bot_secrets['token']
|
||||||
|
self.embed_color = discord.Colour.from_rgb(49, 107, 111)
|
||||||
|
|
||||||
# async def connect_db():
|
# async def connect_db():
|
||||||
# return await asyncpg.create_pool(host=self.bot_secrets['db_con']['host'],
|
# return await asyncpg.create_pool(host=self.bot_secrets['db_con']['host'],
|
||||||
|
|||||||
44
misc.py
44
misc.py
@ -1,44 +0,0 @@
|
|||||||
@checks.no_bots()
|
|
||||||
@commands.cooldown(1,5,commands.BucketType.user)
|
|
||||||
@commands.command()
|
|
||||||
async def captcha(self, ctx, type, *, text):
|
|
||||||
type = type.lower()
|
|
||||||
if type not in "checked unchecked loading".split():
|
|
||||||
raise commands.BadArgument(f"Invalid type {type!r}. Available "
|
|
||||||
"types: `unchecked`, `loading`, `checked`")
|
|
||||||
font = ImageFont.truetype("Roboto-Regular.ttf", 14)
|
|
||||||
async with ctx.typing():
|
|
||||||
img = Image.open(f"blank-captcha-{type}.png")
|
|
||||||
img.load()
|
|
||||||
d = ImageDraw.Draw(img)
|
|
||||||
fnc = functools.partial(d.text, (53,30), text, fill=(0,0,0,255),
|
|
||||||
font=font)
|
|
||||||
await self.bot.loop.run_in_executor(None, fnc)
|
|
||||||
img.save("captcha.png")
|
|
||||||
await ctx.send(file=discord.File("captcha.png"))
|
|
||||||
os.system("rm captcha.png")
|
|
||||||
img.close()
|
|
||||||
|
|
||||||
|
|
||||||
import functools, youtube_dl
|
|
||||||
#bot.voice_chan = await ctx.author.voice.channel.connect()
|
|
||||||
bot.voice_chan.stop()
|
|
||||||
opts = {"format": 'webm[abr>0]/bestaudio/best',"ignoreerrors": True,"default_search": "auto","source_address": "0.0.0.0",'quiet': True}
|
|
||||||
ydl = youtube_dl.YoutubeDL(opts)
|
|
||||||
url = 'https://www.youtube.com/watch?v=hjbPszSt5Pc'
|
|
||||||
func = functools.partial(ydl.extract_info, url, download=False)
|
|
||||||
info = func()
|
|
||||||
#bot.voice_chan.play(discord.FFmpegPCMAudio('dead_puppies.mp3'))
|
|
||||||
bot.voice_chan.play(discord.FFmpegPCMAudio(info['url']))
|
|
||||||
#async while bot.voice_chan.is_playing():
|
|
||||||
# pass
|
|
||||||
#await bot.voice_chan.disconnect()
|
|
||||||
|
|
||||||
# Run event in loop after number of seconds
|
|
||||||
from functools import partial
|
|
||||||
return bot.loop.call_later(120, partial(bot.loop.create_task, ctx.send(f"{ctx.author.mention} Timer's Up")))
|
|
||||||
|
|
||||||
# Get the number of tasks currently in the loop
|
|
||||||
import asyncio
|
|
||||||
return len(asyncio.Task.all_tasks())
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user