Compare commits

..

No commits in common. "897c77fee651bf2f9365c184c9727de5044895af" and "240d606f2b92b11d10366e63021fb422d58755e3" have entirely different histories.

9 changed files with 95 additions and 131 deletions

View File

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -44,7 +44,7 @@ emojis: Dict[str, str] = {
class Geeksbot(commands.Bot):
def __init__(self, **kwargs):
kwargs["command_prefix"] = self.get_custom_prefix
self.description = 'I am Geeksbot! Fear me!'
self.description = 'I am Geeksbot Dev! Fear me!\n I might just break and take you with me :P'
kwargs['description'] = self.description
super().__init__(**kwargs)
self.aio_session = aiohttp.ClientSession(loop=self.loop)
@ -56,14 +56,13 @@ class Geeksbot(commands.Bot):
self.infected = {}
self.TOKEN = self.bot_secrets['token']
self.embed_color = discord.Colour.from_rgb(49, 107, 111)
self.error_color = discord.Colour.from_rgb(142, 29, 31)
del self.bot_secrets['token']
self.db_con = database.DatabaseConnection(**self.bot_secrets['db_con'])
self.default_prefix = 'g$'
self.default_prefix = 'g~'
self.voice_chans = {}
self.spam_list = {}
self.owner_id = 351794468870946827
self.__version__ = 'v1.0.0'
self.__version__ = '1.0.0b'
self.gcs_service = build('customsearch', 'v1', developerKey=self.bot_secrets['google_search_key'])
self.tpe = futures.ThreadPoolExecutor()
self.geo_api = '2d4e419c2be04c8abe91cb5dd1548c72'

View File

@ -94,22 +94,22 @@ class Admin:
@commands.group(case_insensitive=True)
async def set(self, ctx):
"""Group for setting configuration options"""
"""Run help set for more info"""
pass
@commands.group(case_insensitive=True)
async def add(self, ctx):
"""Group for adding items to guild config"""
"""Run help set for more info"""
pass
@commands.group(case_insensitive=True)
async def remove(self, ctx):
"""Group for removing items from guild config"""
"""Run help set for more info"""
pass
@set.command(name='admin_chan', aliases=['ac', 'admin_chat', 'admin chat'])
async def _admin_channel(self, ctx, channel: discord.TextChannel=None):
"""Sets the admin notification channel"""
"""Sets the channel for admin specific notifications"""
if ctx.guild:
if await checks.is_admin(self.bot, ctx):
if channel is not None:
@ -119,8 +119,7 @@ class Admin:
@set.command(name='channel_lockdown', aliases=['lockdown', 'restrict_access', 'cl'])
async def _channel_lockdown(self, ctx, config='true'):
"""Toggles the channel lockdown restriction
When this is active Geeksbot can only respond in channels defined in allowed_channels
"""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 await checks.is_admin(self.bot, ctx):
@ -147,67 +146,62 @@ class Admin:
@add.command(name='allowed_channels', aliases=['channel', 'ac'])
async def _allowed_channels(self, ctx, *, channels):
"""Defines channels Geeksbot can respond in
This only takes effect if channel_lockdown is enabled.
If one of the channels passed is not found then it is ignored."""
"""Allows Admin to restrict what channels Geeksbot is allowed to access
This only takes effect if channel_lockdown is enabled."""
if ctx.guild:
if await checks.is_admin(self.bot, ctx):
channels = channels.lower().replace(' ', '').split(',')
existing_channels = list()
channels_add = list()
admin_log.info(channels)
allowed_channels = await self.bot.db_con.fetchval('select allowed_channels from guild_config '
'where guild_id = $1', ctx.guild.id)
if allowed_channels == 'null':
allowed_channels = None
channels = [discord.utils.get(ctx.guild.channels, name=channel)
for channel in channels if channel is not None]
if allowed_channels and channels:
allowed_channels = [int(channel) for channel in json.loads(allowed_channels)]
existing_channels = [channel for channel in channels if channel.id in allowed_channels]
channels_add = [channel for channel in channels if channel.id not in allowed_channels]
allowed_channels += [channel.id for channel in channels if channel.id not in allowed_channels]
await self.bot.db_con.execute('update guild_config set allowed_channels = $2 where guild_id = $1',
ctx.guild.id, json.dumps(allowed_channels))
elif channels:
admin_log.info('Config is empty')
allowed_channels = [channel.id for channel in channels]
await self.bot.db_con.execute('update guild_config set allowed_channels = $2 '
'where guild_id = $1', ctx.guild.id,
json.dumps(allowed_channels))
added = ''
for channel in channels:
chnl = discord.utils.get(ctx.guild.channels, name=channel)
if chnl is None:
await ctx.send(f'{channel} is not a valid text channel in this guild.')
else:
await ctx.send('None of those are valid text channels for this guild.')
return
if existing_channels:
channel_str = '\n'.join([str(channel.name) for channel in existing_channels])
await ctx.send(f'The following channels were skipped because they are already in the config:\n'
f'{channel_str}\n')
if channels_add:
channel_str = '\n'.join([str(channel.name) for channel in channels_add])
await ctx.send('The following channels have been added to the allowed channel list:\n'
f'{channel_str}\n')
admin_log.info('Chan found')
if await self.bot.db_con.fetchval('select allowed_channels from guild_config '
'where guild_id = $1', ctx.guild.id):
if chnl.id in json.loads(await self.bot.db_con.fetchval('select allowed_channels '
'from guild_config '
'where guild_id = $1',
ctx.guild.id)):
admin_log.info('Chan found in config')
await ctx.send(f'{channel} is already in the list of allowed channels. Skipping...')
else:
admin_log.info('Chan not found in config')
allowed_channels = json.loads(await self.bot.db_con.fetchval('select allowed_channels '
'from guild_config '
'where guild_id = $1',
ctx.guild.id))\
.append(chnl.id)
await self.bot.db_con.execute('update guild_config set allowed_channels = $2 '
'where guild_id = $1', ctx.guild.id, allowed_channels)
added = f'{added}\n{channel}'
else:
admin_log.info('Chan not found in config')
allowed_channels = [chnl.id]
await self.bot.db_con.execute('update guild_config set allowed_channels = $2 '
'where guild_id = $1', ctx.guild.id, allowed_channels)
added = f'{added}\n{channel}'
if added != '':
await ctx.send(f'The following channels have been added to the allowed channel list: {added}')
await ctx.message.add_reaction('')
else:
await ctx.send(f'You are not authorized to run this command.')
else:
await ctx.send('This command must be run from inside a guild.')
# TODO Fix view_code
@commands.command(hidden=True)
@commands.command()
@commands.is_owner()
async def view_code(self, ctx, code_name):
pag = utils.Paginator(self.bot, prefix='```py', suffix='```')
pag.add(inspect.getsource(self.bot.all_commands[code_name].callback))
pag.add(inspect.getsource(self.bot.get_command(code_name).callback))
for page in pag.pages():
await ctx.send(page)
@add.command(aliases=['prefix', 'p'])
@commands.cooldown(1, 5, type=commands.BucketType.guild)
async def add_prefix(self, ctx, *, prefix=None):
"""Adds a custom prefix for the current guild
"""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."""
@ -240,7 +234,7 @@ class Admin:
@remove.command(aliases=['prefix', 'p'])
@commands.cooldown(1, 5, type=commands.BucketType.guild)
async def remove_prefix(self, ctx, *, prefix=None):
"""Removes custom prefix from the current guild
"""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:
@ -279,7 +273,7 @@ class Admin:
@commands.cooldown(1, 5, type=commands.BucketType.guild)
@commands.check(checks.is_guild_owner)
async def _add_admin_role(self, ctx, role=None):
"""Adds role to the admin list for current guild
"""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)
@ -300,7 +294,7 @@ class Admin:
@commands.cooldown(1, 5, type=commands.BucketType.guild)
@commands.check(checks.is_guild_owner)
async def _remove_admin_role(self, ctx, role=None):
"""Removes role from admin list in current guild"""
"""The Guild owner can remove a role from the admin list"""
role = discord.utils.get(ctx.guild.roles, name=role)
if role is not None:
roles = json.loads(await self.bot.db_con.fetchval('select admin_roles from guild_config '

View File

@ -150,13 +150,13 @@ class BotEvents:
# noinspection PyMethodMayBeStatic
async def on_command_error(self, ctx, error):
pag = utils.Paginator(ctx.bot, embed=True, max_line_length=48)
pag.set_embed_meta(title=f'Command Error',
color=self.bot.error_color,
thumbnail=f'{ctx.guild.me.avatar_url}')
pag.add(error)
book = utils.Book(pag, (None, ctx.channel, self.bot, ctx.message))
await book.create_book()
pag = utils.Paginator(ctx.bot)
import traceback
if ctx.channel.id == 418452585683484680 and type(error) == commands.errors.CommandNotFound:
return
pag.add(''.join(traceback.format_exception(type(error), error, error.__traceback__)))
for page in pag.pages():
await ctx.send(page)
async def on_guild_join(self, guild):
with open(f"{config_dir}{default_guild_config_file}", 'r') as file:

View File

@ -33,9 +33,6 @@ class Fun:
@commands.command()
@commands.cooldown(1, 30, type=commands.BucketType.user)
async def infect(self, ctx, member: discord.Member, emoji):
"""Infects a user with the given emoji
Every time the user sends a message that I am also in I will react to that message with said emoji."""
if member.id == self.bot.user.id and ctx.author.id != owner_id:
await ctx.send(f'You rolled a Critical Fail...\nInfection bounces off and rebounds on the attacker.')
member = ctx.author
@ -51,7 +48,6 @@ class Fun:
@commands.command()
@commands.cooldown(1, 5, type=commands.BucketType.user)
async def heal(self, ctx, member: discord.Member):
"""Removes infection from user."""
if ctx.author == member and ctx.author.id != owner_id:
await ctx.send('You can\'t heal yourself silly...')
else:
@ -61,7 +57,7 @@ class Fun:
else:
await ctx.send(f'{member.display_name} is not infected...')
@commands.command(hidden=True)
@commands.command()
@commands.is_owner()
async def print_infections(self, ctx):
await ctx.author.send(f'```{self.bot.infected}```')
@ -69,7 +65,6 @@ class Fun:
@commands.command()
@commands.cooldown(1, 5, type=commands.BucketType.user)
async def slap(self, ctx, member: discord.Member):
"""IRC Style Trout Slap"""
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:
await ctx.send(f'You rolled a Critical Fail...\nThe trout bounces off and rebounds on the attacker.')
@ -89,7 +84,6 @@ class Fun:
@commands.command()
@commands.cooldown(1, 5, type=commands.BucketType.user)
async def fact(self, ctx, number: int):
"""Returns the given factorial up to 20,000!"""
if 0 < number < 20001:
n = 1990
with ctx.channel.typing():
@ -156,7 +150,6 @@ class Fun:
@commands.command(name='explode', aliases=['splode'])
async def explode_user(self, ctx, member: discord.Member=None):
"""Trolls user by punching them to oblivion."""
if member is None or member.id == 396588996706304010:
member = ctx.author

View File

@ -16,7 +16,7 @@ class Git:
@commands.group(case_insensitive=True, invoke_without_command=True)
async def git(self, ctx):
"""Shows my Git link"""
"""Run help git for more info"""
em = discord.Embed(style='rich',
title=f'Here is where you can find my code',
url='https://github.com/dustinpianalto/Geeksbot/tree/development',
@ -29,7 +29,6 @@ class Git:
@git.command()
@commands.is_owner()
async def pull(self, ctx):
"""Pulls updates from GitHub rebasing branch."""
pag = Paginator(self.bot, max_line_length=44, embed=True)
pag.set_embed_meta(title='Git Pull',
color=self.bot.embed_color,
@ -42,22 +41,23 @@ class Git:
pag.add('\uFFF7\n\uFFF8')
pag.add(await asyncio.wait_for(self.bot.loop.create_task(run_command('git show --stat | '
'sed "s/.*@.*[.].*/ /g"')), 10))
book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
msg = await ctx.send('Starting Book')
book = Book(pag, (msg, ctx.channel, self.bot, ctx.message))
await book.create_book()
@git.command()
@commands.is_owner()
async def status(self, ctx):
"""Gets status of current branch."""
pag = Paginator(self.bot, max_line_length=44, max_lines=30, embed=True)
pag.set_embed_meta(title='Git Status',
color=self.bot.embed_color,
thumbnail=f'{ctx.guild.me.avatar_url}')
pag = Paginator(max_line_length=60, max_lines=30, max_chars=1014)
em = discord.Embed(style='rich',
title=f'Git Pull',
color=embed_color)
em.set_thumbnail(url=f'{ctx.guild.me.avatar_url}')
result = await asyncio.wait_for(self.bot.loop.create_task(run_command('git status')), 10)
pag.add(result)
book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
await book.create_book()
for page in pag.pages():
em.add_field(name='', value=f'{page}')
await ctx.send(embed=em)
def setup(bot):

View File

@ -18,10 +18,10 @@ class Patreon:
async def get_patreon_links(self, ctx, target: discord.Member=None):
"""Prints Patreon information for creators on the server."""
if await self.bot.db_con.fetchval('select patreon_enabled from guild_config where guild_id = $1', ctx.guild.id):
patreon_info = await self.bot.db_con.fetchrow('select patreon_message,patreon_links from guild_config '
patreon_info = await self.bot.db_con.fetchval('select patreon_message,patreon_links from guild_config '
'where guild_id = $1', ctx.guild.id)
message = patreon_info['patreon_message'].replace('\\n', '\n')
patreon_links = json.loads(patreon_info['patreon_links'])
message = patreon_info[0].replace('\\n', '\n')
patreon_links = json.loads(patreon_info[1])
for key in patreon_links:
message = message + '\n{0}: {1}'.format(key, patreon_links[key])
if target is None:

View File

@ -54,15 +54,15 @@ class Utils:
msg = await self.bot.wait_for('message', timeout=5, check=check)
self.bot.ping_times[i]['rec'] = msg
@commands.command(hidden=True)
@commands.command()
async def channel_ping(self, ctx, wait_time: float=10, message: str='=bump', channel: int=265828729970753537):
await ctx.send('Starting Background Process.')
self.bot.loop.create_task(self._4_hour_ping(channel, message, wait_time))
@commands.command(hidden=True)
@commands.command()
@commands.is_owner()
async def sysinfo(self, ctx):
"""Gets system status for my server."""
"""WIP Gets current system status for the server that Geeksbot is running on."""
await ctx.send(f'```ml\n'
f'CPU Percentages: {psutil.cpu_percent(percpu=True)}\n'
f'Memory Usage: {psutil.virtual_memory().percent}%\n'
@ -178,10 +178,7 @@ class Utils:
@commands.command()
@commands.cooldown(1, 5, type=commands.BucketType.user)
async def ping(self, ctx, mode='normal', count: int=2):
"""Check the Bot\'s connection to Discord
For more detailed information set the <mode> as comp and it will test the ping
<count> number of times."""
"""Check the Bot\'s connection to Discord"""
em = discord.Embed(style='rich',
title=f'Pong 🏓',
color=discord.Colour.green()
@ -189,8 +186,8 @@ class Utils:
msg = await ctx.send(embed=em)
time1 = ctx.message.created_at
time = (msg.created_at - time1).total_seconds() * 1000
em.description = f'Response Time: **{math.ceil(time)}ms**\n' \
f'Discord Latency: **{math.ceil(self.bot.latency*1000)}ms**'
em.description = f'''Response Time: **{math.ceil(time)}ms**
Discord Latency: **{math.ceil(self.bot.latency*1000)}ms**'''
await msg.edit(embed=em)
if mode == 'comp':
@ -219,8 +216,8 @@ class Utils:
time = time.total_seconds()
times.append(time)
value = f"Message Sent:" \
f"{datetime.strftime(self.bot.ping_times[i]['snd'].created_at, '%H:%M:%S.%f')}\n" \
f"Response Received: {datetime.strftime(now, '%H:%M:%S.%f')}\n" \
f"{datetime.strftime(self.bot.ping_times[i]['snd'].created_at, '%H:%M:%S.%f')}" \
f"Response Received: {datetime.strftime(now, '%H:%M:%S.%f')}" \
f"Total Time: {math.ceil(time * 1000)}ms"
await self.bot.ping_times[i]['rec'].delete()
em.add_field(name=f'Ping Test {i}', value=value, inline=True)
@ -237,7 +234,7 @@ class Utils:
@commands.group(case_insensitive=True)
async def admin(self, ctx):
"""Group for Admin help requests"""
"""Run help admin for more info"""
pass
@admin.command(name='new', aliases=['nr'])
@ -257,12 +254,17 @@ class Utils:
if channel:
chan = discord.utils.get(ctx.guild.channels, id=channel)
msg = ''
admin_roles = []
roles = await self.bot.db_con.fetchval(f'select admin_roles,rcon_admin_roles from guild_config '
f'where guild_id = $1', ctx.guild.id)
f'where $1', ctx.guild.id)
request_id = await self.bot.db_con.fetchval(f'select id from admin_requests where '
f'issuing_member_id = $1 and request_time = $2',
ctx.author.id, ctx.message.created_at)
admin_roles = json.loads(roles).values()
for item in roles:
i = json.loads(item)
for j in i:
if i[j] not in admin_roles:
admin_roles.append(i[j])
for role in admin_roles:
msg = '{0} {1}'.format(msg, discord.utils.get(ctx.guild.roles, id=role).mention)
msg += f"New Request ID: {request_id} " \
@ -281,7 +283,7 @@ class Utils:
@admin.command(name='list', aliases=['lr'])
@commands.cooldown(1, 5, type=commands.BucketType.user)
async def list_admin_requests(self, ctx, assigned_to: discord.Member=None):
"""List of all active Admin help requests
"""Returns a list of all active Admin help requests for this guild
If a user runs this command it will return all the requests that they have submitted and are still open.
- The [assigned_to] argument is ignored but will still give an error if an incorrect value is entered.
@ -370,7 +372,7 @@ class Utils:
except ValueError:
await ctx.send(f'{request_id} is not a valid request id.')
else:
request = await self.bot.db_con.fetchrow(f'select * from admin_requests where id = $1',
request = await self.bot.db_con.fetchval(f'select * from admin_requests where id = $1',
request_id)
if request:
if request[3] == ctx.guild.id:
@ -394,8 +396,7 @@ class Utils:
@commands.command(name='weather', aliases=['wu'])
@commands.cooldown(5, 15, type=commands.BucketType.default)
async def get_weather(self, ctx, *, location='palmer ak'):
"""Gets the weather data for the location given
"""Gets the weather data for the location provided,
If no location is included then it will get the weather for the Bot's home location.
"""
try:
@ -432,8 +433,7 @@ class Utils:
@commands.command(name='localtime', aliases=['time', 'lt'])
@commands.cooldown(1, 3, type=commands.BucketType.user)
async def get_localtime(self, ctx, timezone: str='Anchorage'):
"""Shows the current time in the timezone given
"""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()
@ -462,13 +462,6 @@ class Utils:
@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):
"""Convert the time provided to given timezone
Attempts to process the given time and timezone and convert into the given timezone.
Example: g$gti CET Friday June 15 2018 US/Alaska
This will be processed into a datetime with US/Alaska set as the timezone and will
convert it into CET timezone and return both times."""
em = discord.Embed()
if time is None:
@ -528,7 +521,7 @@ class Utils:
@commands.command(name='purge', aliases=['clean', 'erase'])
@commands.cooldown(1, 3, type=commands.BucketType.user)
async def purge_messages(self, ctx, number: int=20, member: discord.Member=None):
"""Purge messages from the current channel
"""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
@ -572,9 +565,7 @@ class Utils:
@commands.command(name='purge_all', aliases=['cls', 'clear'])
@commands.cooldown(1, 3, type=commands.BucketType.user)
async def purge_all(self, ctx, number: int=20, contents: str='all'):
"""Purge all messages from the current channel
Will delete all of the last <number> of messages from the channel
"""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):
@ -605,8 +596,6 @@ class Utils:
@commands.command(hidden=True, name='sheets')
async def google_sheets(self, ctx, member: discord.Member):
"""Access Google Sheets and looks for the member"""
if await checks.is_admin(self.bot, ctx):
scope = ['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/drive']
@ -632,10 +621,7 @@ class Utils:
@commands.command(name='iss')
async def iss_loc(self, ctx):
"""Locate the International Space Station
Gets the location of the ISS and display on a
Blue Marble map."""
"""WIP Locates the International Space Station and display on a map"""
def gen_image(iss_loc):
lat = iss_loc['latitude']
lon = iss_loc['longitude']
@ -660,8 +646,6 @@ class Utils:
@commands.command(name='location', aliases=['loc', 'map'])
async def map_location(self, ctx, *, location):
"""WIP Displays the given location on a map
Searches for the location provided and plots the Lat Long on a map.
Note: This is SLOW!!! Be prepared to wait up to a minute for the result"""
def draw_map(m, scale=1):
@ -720,7 +704,6 @@ class Utils:
@commands.command(name='help', aliases=['h'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def custom_help(self, ctx, *, command: str=None):
"""This help message"""
pag = utils.Paginator(self.bot, embed=True, max_line_length=48)
prefixes = await self.bot.get_custom_prefix(self.bot, ctx.message)
if isinstance(prefixes, list):