|
|
import discord
|
|
|
from discord.ext import commands
|
|
|
import json
|
|
|
import logging
|
|
|
import math
|
|
|
import psutil
|
|
|
from datetime import datetime, timedelta
|
|
|
import asyncio
|
|
|
import async_timeout
|
|
|
from .imports import checks
|
|
|
import pytz
|
|
|
import gspread
|
|
|
from oauth2client.service_account import ServiceAccountCredentials
|
|
|
|
|
|
config_dir = 'config/'
|
|
|
admin_id_file = 'admin_ids'
|
|
|
extension_dir = 'extensions'
|
|
|
owner_id = 351794468870946827
|
|
|
embed_color = discord.Colour.from_rgb(49, 107, 111)
|
|
|
bot_config_file = 'bot_config.json'
|
|
|
invite_match = '(https?://)?(www.)?discord(app.com/(invite|oauth2)|.gg|.io)/[\w\d_\-?=&/]+'
|
|
|
|
|
|
utils_log = logging.getLogger('utils')
|
|
|
clock_emojis = ['🕛', '🕐', '🕑', '🕒', '🕓', '🕔', '🕕', '🕖', '🕗', '🕘', '🕙', '🕚']
|
|
|
|
|
|
|
|
|
class Utils:
|
|
|
def __init__(self, bot):
|
|
|
self.bot = bot
|
|
|
|
|
|
async def _4_hour_ping(self, channel, message, wait_time):
|
|
|
channel = self.bot.get_channel(channel)
|
|
|
time_now = datetime.utcnow()
|
|
|
await channel.send(message)
|
|
|
while True:
|
|
|
if time_now < datetime.utcnow() - timedelta(seconds=wait_time+10):
|
|
|
await channel.send(message)
|
|
|
time_now = datetime.utcnow()
|
|
|
await asyncio.sleep(wait_time/100)
|
|
|
|
|
|
async def background_ping(self, ctx, i):
|
|
|
def check(message):
|
|
|
return message.author == ctx.guild.me and 'ping_test' in message.content
|
|
|
msg = await self.bot.wait_for('message', timeout=5, check=check)
|
|
|
self.bot.ping_times[i]['rec'] = msg
|
|
|
|
|
|
@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()
|
|
|
@commands.is_owner()
|
|
|
async def sysinfo(self, ctx):
|
|
|
await ctx.send(f'''
|
|
|
```ml
|
|
|
CPU Percentages: {psutil.cpu_percent(percpu=True)}
|
|
|
Memory Usage: {psutil.virtual_memory().percent}%
|
|
|
Disc Usage: {psutil.disk_usage("/").percent}%
|
|
|
```''')
|
|
|
|
|
|
@commands.command(hidden=True)
|
|
|
async def role(self, ctx, role):
|
|
|
if ctx.guild.id == 396156980974059531 and role != 'Admin' and role != 'Admin Geeks':
|
|
|
try:
|
|
|
role = discord.utils.get(ctx.guild.roles, name=role)
|
|
|
except Exception:
|
|
|
await ctx.send('Unknown Role')
|
|
|
else:
|
|
|
if role is not None:
|
|
|
await ctx.message.author.add_roles(role)
|
|
|
await ctx.send("Roles Updated")
|
|
|
else:
|
|
|
await ctx.send('Unknown Role')
|
|
|
else:
|
|
|
await ctx.send("You are not authorized to send this command.")
|
|
|
|
|
|
@commands.command(aliases=['oauth', 'link'])
|
|
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
|
|
async def invite(self, ctx, guy: discord.User=None):
|
|
|
"""Shows you the bot's invite link.
|
|
|
If you pass in an ID of another bot, it gives you the invite link to that bot.
|
|
|
"""
|
|
|
guy = guy or self.bot.user
|
|
|
url = discord.utils.oauth_url(guy.id)
|
|
|
await ctx.send(f'**{url}**')
|
|
|
|
|
|
@staticmethod
|
|
|
def create_date_string(time, time_now):
|
|
|
diff = (time_now - time)
|
|
|
date_str = time.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
return f"{diff.days} {'day' if diff.days == 1 else 'days'} " \
|
|
|
f"{diff.seconds // 3600} {'hour' if diff.seconds // 3600 == 1 else 'hours'} " \
|
|
|
f"{diff.seconds % 3600 // 60} {'minute' if diff.seconds % 3600 // 60 == 1 else 'minutes'} " \
|
|
|
f"{diff.seconds % 3600 % 60} {'second' if diff.seconds % 3600 % 60 == 1 else 'seconds'} ago.\n{date_str}"
|
|
|
|
|
|
@commands.command()
|
|
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
|
|
async def me(self, ctx):
|
|
|
"""Prints out your user information."""
|
|
|
em = discord.Embed(style='rich',
|
|
|
title=f'{ctx.author.name}#{ctx.author.discriminator} ({ctx.author.display_name})',
|
|
|
description=f'({ctx.author.id})',
|
|
|
color=embed_color)
|
|
|
em.set_thumbnail(url=f'{ctx.author.avatar_url}')
|
|
|
em.add_field(name=f'Highest Role:',
|
|
|
value=f'{ctx.author.top_role}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f'Bot:',
|
|
|
value=f'{ctx.author.bot}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f'Joined Guild:',
|
|
|
value=f'{self.create_date_string(ctx.author.joined_at, ctx.message.created_at)}',
|
|
|
inline=False)
|
|
|
em.add_field(name=f'Joined Discord:',
|
|
|
value=f'{self.create_date_string(ctx.author.created_at, ctx.message.created_at)}',
|
|
|
inline=False)
|
|
|
em.add_field(name=f'Current Status:',
|
|
|
value=f'{ctx.author.status}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f"Currently{' '+ctx.author.activity.type.name.title() if ctx.author.activity else ''}:",
|
|
|
value=f"{ctx.author.activity.name if ctx.author.activity else 'Not doing anything important.'}",
|
|
|
inline=True)
|
|
|
count = 0
|
|
|
async for message in ctx.channel.history(after=(ctx.message.created_at - timedelta(hours=1))):
|
|
|
if message.author == ctx.author:
|
|
|
count += 1
|
|
|
em.add_field(name=f'Activity:',
|
|
|
value=f'You have sent {count} '
|
|
|
f'{"message" if count == 1 else "messages"} in the last hour to this channel.',
|
|
|
inline=False)
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
@commands.command()
|
|
|
@commands.cooldown(1, 5, type=commands.BucketType.user)
|
|
|
async def user(self, ctx, member: discord.Member):
|
|
|
"""Prints User information.
|
|
|
<member> should be in the form @Dusty.P#0001"""
|
|
|
em = discord.Embed(style='rich',
|
|
|
title=f'{member.name}#{member.discriminator} ({member.display_name})',
|
|
|
description=f'({member.id})',
|
|
|
color=embed_color)
|
|
|
em.set_thumbnail(url=f'{member.avatar_url}')
|
|
|
em.add_field(name=f'Highest Role:',
|
|
|
value=f'{member.top_role}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f'Bot:',
|
|
|
value=f'{member.bot}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f'Joined Guild:',
|
|
|
value=f'{self.create_date_string(member.joined_at,ctx.message.created_at)}',
|
|
|
inline=False)
|
|
|
em.add_field(name=f'Joined Discord:',
|
|
|
value=f'{self.create_date_string(member.created_at,ctx.message.created_at)}',
|
|
|
inline=False)
|
|
|
em.add_field(name=f'Current Status:',
|
|
|
value=f'{member.status}',
|
|
|
inline=True)
|
|
|
em.add_field(name=f"Currently{' '+member.activity.type.name.title() if member.activity else ''}:",
|
|
|
value=f"{member.activity.name if member.activity else 'Not doing anything important.'}",
|
|
|
inline=True)
|
|
|
count = 0
|
|
|
async for message in ctx.channel.history(after=(ctx.message.created_at - timedelta(hours=1))):
|
|
|
if message.author == member:
|
|
|
count += 1
|
|
|
em.add_field(name=f'Activity:',
|
|
|
value=f'{member.display_name} has sent {count} '
|
|
|
f'{"message" if count == 1 else "messages"} in the last hour to this channel.',
|
|
|
inline=False)
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
@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"""
|
|
|
em = discord.Embed(style='rich',
|
|
|
title=f'Pong 🏓',
|
|
|
color=discord.Colour.green()
|
|
|
)
|
|
|
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**
|
|
|
Discord Latency: **{math.ceil(self.bot.latency*1000)}ms**'''
|
|
|
await msg.edit(embed=em)
|
|
|
|
|
|
if mode == 'comp':
|
|
|
try:
|
|
|
count = int(count)
|
|
|
except Exception:
|
|
|
await ctx.send('Not a valid count. Must be a whole number.')
|
|
|
else:
|
|
|
if count > 24:
|
|
|
await ctx.send('24 Pings is the max allowed. Setting count to 24.', delete_after=5)
|
|
|
count = 24
|
|
|
self.bot.ping_times = []
|
|
|
times = []
|
|
|
for i in range(count):
|
|
|
self.bot.ping_times.append({})
|
|
|
self.bot.loop.create_task(self.background_ping(ctx, i))
|
|
|
await asyncio.sleep(0.1)
|
|
|
self.bot.ping_times[i]['snd'] = await ctx.send('ping_test')
|
|
|
now = datetime.utcnow()
|
|
|
while 'rec' not in self.bot.ping_times[i]:
|
|
|
now = datetime.utcnow()
|
|
|
if now.timestamp() > self.bot.ping_times[i]['snd'].created_at.timestamp()+5:
|
|
|
break
|
|
|
if 'rec' in self.bot.ping_times[i]:
|
|
|
time = now - self.bot.ping_times[i]['snd'].created_at
|
|
|
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')}" \
|
|
|
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)
|
|
|
else:
|
|
|
em.add_field(name=f'Ping Test {i}', value='Timeout...', inline=True)
|
|
|
total_time = 0
|
|
|
print(times)
|
|
|
for time in times:
|
|
|
total_time += time * 1000
|
|
|
em.add_field(value=f'Total Time for Comprehensive test: {math.ceil(total_time)}ms',
|
|
|
name=f'Average: **{round(total_time/count,1)}ms**',
|
|
|
inline=False)
|
|
|
await msg.edit(embed=em)
|
|
|
|
|
|
@commands.group(case_insensitive=True)
|
|
|
async def admin(self, ctx):
|
|
|
"""Run help admin for more info"""
|
|
|
pass
|
|
|
|
|
|
@admin.command(name='new', aliases=['nr'])
|
|
|
@commands.cooldown(1, 30, type=commands.BucketType.user)
|
|
|
async def new_admin_request(self, ctx, *, request_msg=None):
|
|
|
"""Submit a new request for admin assistance.
|
|
|
The admin will be notified when your request is made and it will be added to the request list for this guild.
|
|
|
"""
|
|
|
if ctx.guild:
|
|
|
if request_msg is not None:
|
|
|
if len(request_msg) < 1000:
|
|
|
self.bot.con.run('insert into admin_requests (issuing_member_id, guild_orig, request_text,'
|
|
|
'request_time) values (%(member_id)s, %(guild_id)s, %(text)s, %(time)s)',
|
|
|
{'member_id': ctx.author.id, 'guild_id': ctx.guild.id, 'text': request_msg,
|
|
|
'time': ctx.message.created_at})
|
|
|
channel = self.bot.con.one(f'select admin_chat from guild_config where guild_id = {ctx.guild.id}')
|
|
|
if channel:
|
|
|
chan = discord.utils.get(ctx.guild.channels, id=channel)
|
|
|
msg = ''
|
|
|
admin_roles = []
|
|
|
roles = self.bot.con.one(f'select admin_roles,rcon_admin_roles from guild_config where '
|
|
|
f'guild_id = %(id)s', {'id': ctx.guild.id})
|
|
|
request_id = self.bot.con.one(f'select id from admin_requests where '
|
|
|
f'issuing_member_id = %(member_id)s and request_time = %(time)s',
|
|
|
{'member_id': ctx.author.id, 'time': ctx.message.created_at})
|
|
|
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}
|
|
|
{ctx.author.mention} has requested assistance:
|
|
|
```{request_msg}```
|
|
|
Requested on: {datetime.strftime(ctx.message.created_at, '%Y-%m-%d at %H:%M:%S')} GMT"""
|
|
|
await chan.send(msg)
|
|
|
await ctx.send('The Admin have received your request.')
|
|
|
else:
|
|
|
await ctx.send('Request is too long, please keep your message to less than 1000 characters.')
|
|
|
else:
|
|
|
await ctx.send('Please include a message containing information about your request.')
|
|
|
else:
|
|
|
await ctx.send('This command must be run from inside a guild.')
|
|
|
|
|
|
@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):
|
|
|
"""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.
|
|
|
|
|
|
If an admin runs this command it will return all the open requests for this guild.
|
|
|
- If the [assigned_to] argument is included it will instead return all open requests that
|
|
|
are assigned to the specified admin.
|
|
|
"""
|
|
|
em = discord.Embed(style='rich',
|
|
|
title=f'Admin Help Requests',
|
|
|
color=discord.Colour.green()
|
|
|
)
|
|
|
if checks.is_admin(self.bot, ctx) or checks.is_rcon_admin(self.bot, ctx):
|
|
|
if assigned_to is None:
|
|
|
requests = self.bot.con.all(f'select * from admin_requests where guild_orig = %(guild_id)s '
|
|
|
f'and completed_time is null', {'guild_id': ctx.guild.id})
|
|
|
em.title = f'Admin help requests for {ctx.guild.name}'
|
|
|
if requests:
|
|
|
for request in requests:
|
|
|
member = discord.utils.get(ctx.guild.members, id=request[1])
|
|
|
admin = discord.utils.get(ctx.guild.members, id=request[2])
|
|
|
title = f"""{'Request ID':^12}{'Requested By':^20}{'Assigned to':^20}
|
|
|
{request[0]:^12}{member.display_name if member else 'None':^20}
|
|
|
{admin.display_name if admin else 'None':^20}"""
|
|
|
em.add_field(name='',
|
|
|
value=f"""```{title}
|
|
|
|
|
|
{request[4]}
|
|
|
|
|
|
Requested on: {datetime.strftime(request[5], '%Y-%m-%d at %H:%M:%S')} GMT```""",
|
|
|
inline=False)
|
|
|
else:
|
|
|
em.add_field(name='There are no pending requests for this guild.', value='', inline=False)
|
|
|
else:
|
|
|
if checks.check_admin_role(self.bot, ctx, assigned_to)\
|
|
|
or checks.check_rcon_role(self.bot, ctx, assigned_to):
|
|
|
requests = self.bot.con.all('select * from admin_requests where assigned_to = %(admin_id)s '
|
|
|
'and guild_orig = %(guild_id)s and completed_time is null',
|
|
|
{'admin_id': assigned_to.id, 'guild_id': ctx.guild.id})
|
|
|
em.title = f'Admin help requests assigned to {assigned_to.display_name} in {ctx.guild.name}'
|
|
|
if requests:
|
|
|
for request in requests:
|
|
|
member = discord.utils.get(ctx.guild.members, id=request[1])
|
|
|
em.add_field(name=f"Request ID: {request[0]} Requested By:"
|
|
|
f"{member.display_name if member else 'None'}",
|
|
|
value=f"""{request[4]}
|
|
|
Requested on: {datetime.strftime(request[5], '%Y-%m-%d at %H:%M:%S')} GMT
|
|
|
""",
|
|
|
inline=False)
|
|
|
else:
|
|
|
em.add_field(name=f'There are no pending requests for {assigned_to.display_name} this guild.',
|
|
|
value='',
|
|
|
inline=False)
|
|
|
else:
|
|
|
em.title = f'{assigned_to.display_name} is not an admin in this guild.'
|
|
|
else:
|
|
|
requests = self.bot.con.all('select * from admin_requests where issuing_member_id = %(member_id)s '
|
|
|
'and guild_orig = %(guild_id)s and completed_time is null',
|
|
|
{'member_id': ctx.author.id, 'guild_id': ctx.guild.id})
|
|
|
em.title = f'Admin help requests for {ctx.author.display_name}'
|
|
|
if requests:
|
|
|
for request in requests:
|
|
|
admin = discord.utils.get(ctx.guild.members, id=request[2])
|
|
|
em.add_field(name=f"Request ID: {request[0]}"
|
|
|
f"{' Assigned to: ' + admin.display_name if admin else ''}",
|
|
|
value=f"""{request[4]}
|
|
|
Requested on: {datetime.strftime(request[5], '%Y-%m-%d at %H:%M:%S')} GMT
|
|
|
""",
|
|
|
inline=False)
|
|
|
else:
|
|
|
em.add_field(name='You have no pending Admin Help requests.',
|
|
|
value='To submit a request please use `admin new <message>`',
|
|
|
inline=False)
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
@admin.command(name='close')
|
|
|
async def close_request(self, ctx, *, request_ids=None):
|
|
|
"""Allows Admin to close admin help tickets.
|
|
|
[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 request_ids:
|
|
|
request_ids = request_ids.replace(' ', '').split(',')
|
|
|
for request_id in request_ids:
|
|
|
try:
|
|
|
request_id = int(request_id)
|
|
|
except Exception:
|
|
|
await ctx.send(f'{request_id} is not a valid request id.')
|
|
|
else:
|
|
|
request = self.bot.con.one(f'select * from admin_requests where id = %(request_id)s',
|
|
|
{'request_id': request_id})
|
|
|
if request:
|
|
|
if request[3] == ctx.guild.id:
|
|
|
if request[6] is None:
|
|
|
self.bot.con.run('update admin_requests set completed_time = %(time_now)s where '
|
|
|
'id = %(request_id)s',
|
|
|
{'time_now': ctx.message.created_at, 'request_id': request_id})
|
|
|
await ctx.send(f'Request {request_id} by '
|
|
|
f'{ctx.guild.get_member(request[1]).display_name}'
|
|
|
f' has been marked complete.')
|
|
|
else:
|
|
|
await ctx.send(f'Request {request_id} is already marked complete.')
|
|
|
else:
|
|
|
await ctx.send(f'Request {request_id} is not registered to this guild.')
|
|
|
else:
|
|
|
await ctx.send(f'{request_id} is not a valid request id.')
|
|
|
else:
|
|
|
await ctx.send('You must include at least one request id to close.')
|
|
|
else:
|
|
|
await ctx.send(f'You are not authorized to run this command.')
|
|
|
|
|
|
@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 provided,
|
|
|
If no location is included then it will get the weather for the Bot's home location.
|
|
|
"""
|
|
|
try:
|
|
|
url = f'http://autocomplete.wunderground.com/aq?query={location}&format=JSON'
|
|
|
with async_timeout.timeout(10):
|
|
|
async with self.bot.aio_session.get(url) as response:
|
|
|
data = await response.json()
|
|
|
link = data['RESULTS'][0]['l']
|
|
|
url = f'http://api.wunderground.com/api/88e14343b2dd6d8e/geolookup/conditions/{link}.json'
|
|
|
with async_timeout.timeout(10):
|
|
|
async with self.bot.aio_session.get(url) as response:
|
|
|
data = json.loads(await response.text())
|
|
|
utils_log.info(data)
|
|
|
em = discord.Embed()
|
|
|
em.title = f"Weather for {data['current_observation']['display_location']['full']}"
|
|
|
em.url = data['current_observation']['forecast_url']
|
|
|
em.description = data['current_observation']['observation_time']
|
|
|
em.set_thumbnail(url=data['current_observation']['icon_url'])
|
|
|
em.set_footer(text='Data provided by wunderground.com',
|
|
|
icon_url=data['current_observation']['image']['url'])
|
|
|
value_str = f'''```
|
|
|
{'Temp:':<20}{data['current_observation']['temperature_string']:<22}
|
|
|
{'Feels Like:':<20}{data['current_observation']['feelslike_string']:<22}
|
|
|
{'Relative Humidity:':<20}{data['current_observation']['relative_humidity']:<22}
|
|
|
{'Wind:':<5}{data['current_observation']['wind_string']:^44}
|
|
|
```'''
|
|
|
em.add_field(name=f"Current Conditions: {data['current_observation']['weather']}",
|
|
|
value=value_str,
|
|
|
inline=False)
|
|
|
await ctx.send(embed=em)
|
|
|
except IndexError:
|
|
|
await ctx.send('Can\'t find that location, please try again.')
|
|
|
|
|
|
@commands.command(name='localtime', aliases=['time', 'lt'])
|
|
|
@commands.cooldown(1, 3, type=commands.BucketType.user)
|
|
|
async def get_localtime(self, ctx, timezone: str='Anchorage'):
|
|
|
em = discord.Embed()
|
|
|
try:
|
|
|
tz = pytz.timezone(timezone)
|
|
|
localtime = datetime.now(tz=tz)
|
|
|
em.title = f'{clock_emojis[(localtime.hour % 12)]} {tz}'
|
|
|
em.description = localtime.strftime('%c')
|
|
|
em.colour = embed_color
|
|
|
await ctx.send(embed=em)
|
|
|
except pytz.exceptions.UnknownTimeZoneError:
|
|
|
for tz in pytz.all_timezones:
|
|
|
if timezone.lower() in tz.lower():
|
|
|
localtime = datetime.now(tz=pytz.timezone(tz))
|
|
|
em.title = f'{clock_emojis[(localtime.hour % 12)]} {tz}'
|
|
|
em.description = localtime.strftime('%c')
|
|
|
em.colour = embed_color
|
|
|
await ctx.send(embed=em)
|
|
|
return
|
|
|
em.title = 'Unknown Timezone.'
|
|
|
em.colour = discord.Colour.red()
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
@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):
|
|
|
def is_me(message):
|
|
|
if message.author == self.bot.user:
|
|
|
return True
|
|
|
prefixes = self.bot.con.one('select prefix from guild_config where guild_id = %(id)s', {'id': ctx.guild.id})
|
|
|
if prefixes:
|
|
|
for prefix in prefixes:
|
|
|
if message.content.startswith(prefix):
|
|
|
return True
|
|
|
return False
|
|
|
return message.content.startswith(self.bot.default_prefix)
|
|
|
|
|
|
def is_member(message):
|
|
|
return message.author == member
|
|
|
|
|
|
def is_author(message):
|
|
|
return message.author == ctx.author
|
|
|
|
|
|
if checks.is_admin(self.bot, ctx):
|
|
|
if member:
|
|
|
deleted = await ctx.channel.purge(limit=number, check=is_member)
|
|
|
if member != ctx.author:
|
|
|
await ctx.message.delete()
|
|
|
else:
|
|
|
deleted = await ctx.channel.purge(limit=number, check=is_me)
|
|
|
else:
|
|
|
deleted = await ctx.channel.purge(limit=number, check=is_author)
|
|
|
em = discord.Embed(title='❌ Purge', colour=discord.Colour.red())
|
|
|
em.description = f'Deleted {len(deleted)} messages.'
|
|
|
await ctx.send(embed=em, delete_after=5)
|
|
|
|
|
|
@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'):
|
|
|
if checks.is_admin(self.bot, ctx):
|
|
|
if contents != 'all':
|
|
|
deleted = await ctx.channel.purge(limit=number, check=lambda message: message.content == contents)
|
|
|
else:
|
|
|
deleted = await ctx.channel.purge(limit=number)
|
|
|
em = discord.Embed(title='❌ Purge', colour=discord.Colour.red())
|
|
|
em.description = f'Deleted {len(deleted)} messages.'
|
|
|
if contents != ctx.message.content and contents != 'all':
|
|
|
await ctx.message.delete()
|
|
|
await ctx.send(embed=em, delete_after=5)
|
|
|
|
|
|
@commands.command(name='google', aliases=['g', 'search'])
|
|
|
async def google_search(self, ctx, *, search):
|
|
|
res = self.bot.gcs_service.cse().list(q=search, cx='012214819999548252842:tarnolfyw44').execute()
|
|
|
results = res['items'][:4]
|
|
|
em = discord.Embed()
|
|
|
em.title = f'Google Search'
|
|
|
em.description = f'Top 4 results for "{search}"'
|
|
|
em.colour = embed_color
|
|
|
for result in results:
|
|
|
em.add_field(name=f'{result["title"]}', value=f'{result["snippet"]}\n{result["link"]}')
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
@commands.command(hidden=True, name='sheets')
|
|
|
async def google_sheets(self, ctx, member: discord.Member):
|
|
|
if checks.is_admin(self.bot, ctx):
|
|
|
scope = ['https://spreadsheets.google.com/feeds',
|
|
|
'https://www.googleapis.com/auth/drive']
|
|
|
credentials = ServiceAccountCredentials.from_json_keyfile_name('config/google_client_secret.json', scope)
|
|
|
gc = gspread.authorize(credentials)
|
|
|
sh = gc.open_by_key('128GnQPOx0u7oPGvu5nAJks_Qv2R0Ru9ILAniICoxhJ8')
|
|
|
ws = sh.worksheet('Current Whitelist')
|
|
|
names = ws.col_values('3')
|
|
|
steam = ws.col_values('6')
|
|
|
tier = ws.col_values('5')
|
|
|
patron = ws.col_values('4')
|
|
|
em = discord.Embed()
|
|
|
em.title = f'User Data from Whitelist Sheet'
|
|
|
em.colour = embed_color
|
|
|
for i, name in enumerate(names):
|
|
|
if member.name.lower() in name.lower()\
|
|
|
or member.display_name.lower() in name.lower()\
|
|
|
or name.lower() in member.name.lower()\
|
|
|
or name.lower() in member.display_name.lower():
|
|
|
em.add_field(name=name,
|
|
|
value=f'Steam ID: {steam[i]}\nPatreon Level: {tier[i]}\nPatron of: {patron[i]}')
|
|
|
await ctx.send(embed=em)
|
|
|
|
|
|
|
|
|
def setup(bot):
|
|
|
bot.add_cog(Utils(bot))
|