1
0
Fork 0
mirror of synced 2024-05-17 19:12:33 +12:00

Updated for rewrite: Batch 6

This commit is contained in:
phxntxm 2017-03-07 22:28:30 -06:00
parent 2b9d8a2dca
commit 67d8fedef8
18 changed files with 242 additions and 225 deletions

7
bot.py
View file

@ -48,8 +48,7 @@ async def process_command(ctx):
server = ctx.message.guild
command = ctx.command
r_filter = {'command': command.qualified_name}
command_usage = await utils.get_content('command_usage', r_filter)
command_usage = await utils.get_content('command_usage', key=command.qualified_name)
if command_usage is None:
command_usage = {'command': command.qualified_name}
else:
@ -72,8 +71,8 @@ async def process_command(ctx):
command_usage['server_usage'] = total_server_usage
# Save all the changes
if not await utils.update_content('command_usage', command_usage, r_filter):
await utils.add_content('command_usage', command_usage, r_filter)
if not await utils.update_content('command_usage', command_usage, command.qualified_name):
await utils.add_content('command_usage', command_usage)
@bot.event

View file

@ -108,8 +108,7 @@ class Core:
await ctx.send(fmt)
else:
try:
r_filter = pendulum.parse(date)
motd = await utils.get_content('motd', r_filter)
motd = await utils.get_content('motd', str(pendulum.parse(date).date()))
date = motd[0]['date']
motd = motd[0]['motd']
fmt = "Message of the day for {}:\n\n{}".format(date, motd)

View file

@ -101,9 +101,8 @@ class Deviantart:
await user.send(fmt)
# Now we can update the user's last updated for this DA
# We want to do this whether or not our last if statement was met
r_filter = {'member_id': user.id}
update = {'last_updated': {da_name: result['deviationid']}}
await utils.update_content('deviantart', update, r_filter)
await utils.update_content('deviantart', update, str(user.id))
except Exception as e:
tb = traceback.format_exc()
fmt = "{1}\n{0.__class__.__name__}: {0}".format(tb, e)
@ -124,13 +123,13 @@ class Deviantart:
EXAMPLE: !da sub MyFavoriteArtistEva<3
RESULT: Notifications of amazing pics c:"""
r_filter = {'member_id': ctx.message.author.id}
content = await utils.get_content('deviantart', r_filter)
key = str(ctx.message.author.id)
content = await utils.get_content('deviantart', key)
# TODO: Ensure the user provided is a real user
if content is None:
entry = {'member_id': ctx.message.author.id, 'subbed': [username], 'last_updated': {}}
await utils.add_content('deviantart', entry, r_filter)
await utils.add_content('deviantart', entry)
await ctx.send("You have just subscribed to {}!".format(username))
elif content[0]['subbed'] is None or username not in content[0]['subbed']:
if content[0]['subbed'] is None:
@ -138,7 +137,7 @@ class Deviantart:
else:
content[0]['subbed'].append(username)
sub_list = content[0]['subbed']
await utils.update_content('deviantart', {'subbed': sub_list}, r_filter)
await utils.update_content('deviantart', {'subbed': sub_list}, key)
await ctx.send("You have just subscribed to {}!".format(username))
else:
await ctx.send("You are already subscribed to that user!")
@ -150,14 +149,14 @@ class Deviantart:
EXAMPLE: !da unsub TheArtistWhoBetrayedMe
RESULT: No more pics from that terrible person!"""
r_filter = {'member_id': ctx.message.author.id}
content = await utils.get_content('deviantart', r_filter)
key = str(ctx.message.author.id)
content = await utils.get_content('deviantart', key)
if content is None or content[0]['subbed'] is None:
await ctx.send("You are not subscribed to anyone at the moment!")
elif username in content[0]['subbed']:
content[0]['subbed'].remove(username)
await utils.update_content('deviantart', {'subbed': content[0]['subbed']}, r_filter)
await utils.update_content('deviantart', {'subbed': content[0]['subbed']}, key)
await ctx.send("You have just unsubscribed from {}!".format(username))
else:
await ctx.send("You are not subscribed to that user!")

View file

@ -54,16 +54,15 @@ class StatsUpdate:
async def on_member_join(self, member):
guild = member.guild
r_filter = {'server_id': guild.id}
notifications = await config.get_content('user_notifications', r_filter)
server_settings = await config.get_content('server_settings', guild.id)
try:
channel_id = notifications[0]['channel_id']
except TypeError:
return
# By default, notifications should be off unless explicitly turned on
if not channel_id:
join_leave_on = server_settings[0]['join_leave']
if join_leave_on:
channel_id = server_settings[0]['notification_channel'] or member.guild.id
else:
return
except (IndexError, TypeError):
return
channel = guild.get_channel(channel_id)
@ -71,20 +70,19 @@ class StatsUpdate:
async def on_member_remove(self, member):
guild = member.guild
r_filter = {'server_id': guild.id}
notifications = await config.get_content('user_notifications', r_filter)
server_settings = await config.get_content('server_settings', guild.id)
try:
channel_id = notifications[0]['channel_id']
except TypeError:
join_leave_on = server_settings[0]['join_leave']
if join_leave_on:
channel_id = server_settings[0]['notification_channel'] or member.guild.id
else:
return
except (IndexError, TypeError):
return
# By default, notifications should be off unless explicitly turned on
if not channel_id:
return
channel = server.get_channel(channel_id)
await channelsend("{0} has left the server, I hope it wasn't because of something I said :c".format(member.display_name))
channel = guild.get_channel(channel_id)
await channel.send("{0} has left the server, I hope it wasn't because of something I said :c".format(member.display_name))
def setup(bot):

View file

@ -258,20 +258,20 @@ class Interaction:
await ctx.send("Why the heck are you booping me? Get away from me >:c")
return
r_filter = {'member_id': booper.id}
boops = await utils.get_content('boops', r_filter)
key = str(booper.id)
boops = await utils.get_content('boops', key)
if boops is not None:
boops = boops[0]['boops']
# If the booper has never booped the member provided, assure it's 0
amount = boops.get(boopee.id, 0) + 1
boops[boopee.id] = amount
await utils.update_content('boops', {'boops': boops}, r_filter)
await utils.update_content('boops', {'boops': boops}, key)
else:
entry = {'member_id': booper.id,
'boops': {boopee.id: 1}}
await utils.add_content('boops', entry, r_filter)
await utils.add_content('boops', entry)
amount = 1
fmt = "{0.mention} has just booped {1.mention}{3}! That's {2} times now!"

View file

@ -29,9 +29,8 @@ class Links:
url = "https://www.google.com/search"
# Turn safe filter on or off, based on whether or not this is a nsfw channel
r_filter = {'channel_id': ctx.message.channel.id}
nsfw_channels = await utils.get_content("nsfw_channels", r_filter)
safe = 'off' if nsfw_channels else 'on'
nsfw = await utils.channel_is_nsfw(ctx.message.channel)
safe = 'off' if nsfw else 'on'
params = {'q': query,
'safe': safe,
@ -191,12 +190,11 @@ class Links:
query = ' '.join(value for value in search if not re.search('&?filter_id=[0-9]+', value))
params = {'q': query}
r_filter = {'channel_id': ctx.message.channel.id}
nsfw_channels = await utils.get_content("nsfw_channels", r_filter)
nsfw = await utils.channel_is_nsfw(ctx.message.channel)
# If this is a nsfw channel, we just need to tack on 'explicit' to the terms
# Also use the custom filter that I have setup, that blocks some certain tags
# If the channel is not nsfw, we don't need to do anything, as the default filter blocks explicit
if nsfw_channels is not None:
if nsfw:
params['q'] += ", (explicit OR suggestive)"
params['filter_id'] = 95938
else:
@ -262,12 +260,11 @@ class Links:
params = {'limit': 320,
'tags': tags}
r_filter = {'channel_id': ctx.message.channel.id}
nsfw_channels = await utils.get_content("nsfw_channels", r_filter)
nsfw = await utils.channel_is_nsfw(ctx.message.channel)
# e621 by default does not filter explicit content, so tack on
# safe/explicit based on if this channel is nsfw or not
params['tags'] += " rating:explicit" if nsfw_channels else " rating:safe"
params['tags'] += " rating:explicit" if nsfw else " rating:safe"
data = await utils.request(url, payload=params)

View file

@ -99,19 +99,19 @@ class Mod:
except discord.HTTPException:
await ctx.send("Sorry, I failed to ban that user!")
@commands.command(no_pm=True)
@commands.command(no_pm=True, aliases=['alerts'])
@utils.custom_perms(kick_members=True)
async def alerts(self, ctx, channel: discord.TextChannel):
async def notifications(self, ctx, channel: discord.TextChannel):
"""This command is used to set a channel as the server's 'notifications' channel
Any notifications (like someone going live on Twitch, or Picarto) will go to that channel
EXAMPLE: !alerts #alerts
RESULT: No more alerts spammed in #general!"""
r_filter = {'server_id': ctx.message.guild.id}
key = ctx.message.guild.id
entry = {'server_id': ctx.message.guild.id,
'channel_id': channel.id}
if not await utils.add_content('server_alerts', entry, r_filter):
await utils.update_content('server_alerts', entry, r_filter)
'notification_channel': channel.id}
if not await utils.update_content('server_alerts', entry, key):
await utils.add_content('server_alerts', entry)
await ctx.send("I have just changed this server's 'notifications' channel"
"\nAll notifications will now go to `{}`".format(channel))
@ -119,7 +119,6 @@ class Mod:
@utils.custom_perms(kick_members=True)
async def usernotify(self, ctx, on_off: str):
"""This command can be used to set whether or not you want user notificaitons to show
This will save what channel you run this command in, that will be the channel used to send the notification to
Provide on, yes, or true to set it on; otherwise it will be turned off
EXAMPLE: !usernotify on
@ -127,12 +126,13 @@ class Mod:
# Join/Leave notifications can be kept separate from normal alerts
# So we base this channel on it's own and not from alerts
# When mod logging becomes available, that will be kept to it's own channel if wanted as well
on_off = ctx.message.channel.id if re.search("(on|yes|true)", on_off.lower()) else None
r_filter = {'server_id': ctx.message.guild.id}
on_off = True if re.search("(on|yes|true)", on_off.lower()) else False
key = ctx.message.guild.id
entry = {'server_id': ctx.message.guild.id,
'channel_id': on_off}
if not await utils.add_content('user_notifications', entry, r_filter):
await utils.update_content('user_notifications', entry, r_filter)
'join_leave': on_off}
if not await utils.update_content('user_notifications', entry, key):
await utils.add_content('user_notifications', entry)
fmt = "notify" if on_off else "not notify"
await ctx.send("This server will now {} if someone has joined or left".format(fmt))
@ -149,11 +149,20 @@ class Mod:
EXAMPLE: !nsfw add
RESULT: ;)"""
r_filter = {'channel_id': ctx.message.channel.id}
if await utils.add_content('nsfw_channels', r_filter, r_filter):
await ctx.send("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
key = ctx.message.guild.id
entry = {'server_id': key,
'nsfw_channels': [ctx.message.channel.id]}
update = {'nsfw_channels': r.row['nsfw_channels'].append(ctx.message.channel.id)}
server_settings = await utils.get_content('server_settings', key)
if server_settings and 'nsfw_channels' in server_settings[0].keys():
await utils.update_content('server_settings', update, key)
elif server_settings:
await utils.update_content('server_settings', entry, key)
else:
await ctx.send("This channel is already registered as 'nsfw'!")
await utils.add_content('server_settings', entry, key)
await ctx.send("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
@nsfw.command(name="remove", aliases=["delete"])
@utils.custom_perms(kick_members=True)
@ -162,11 +171,23 @@ class Mod:
EXAMPLE: !nsfw remove
RESULT: ;("""
r_filter = {'channel_id': ctx.message.channel.id}
if await utils.remove_content('nsfw_channels', r_filter):
await ctx.send("This channel has just been unregistered as a nsfw channel")
else:
await ctx.send("This channel is not registered as a ''nsfw' channel!")
key = ctx.message.guild.id
server_settings = await utils.get_content('server_settings', key)
channel = ctx.message.channel.id
try:
channels = server_settings[0]['nsfw_channels']
if channel in channels:
channels.remove(channel)
entry = {'nsfw_channels': channels}
await utils.update_content('server_settings', entry, key)
await ctx.send("This channel has just been unregistered as a nsfw channel")
return
except (TypeError, IndexError):
pass
await ctx.send("This channel is not registered as a 'nsfw' channel!")
@commands.command()
@utils.custom_perms(kick_members=True)
@ -195,18 +216,18 @@ class Mod:
"Valid permissions are: ```\n{}```".format("\n".join("{}".format(i) for i in valid_perms)))
return
r_filter = {'server_id': ctx.message.guild.id}
server_perms = await utils.get_content('custom_permissions', r_filter)
try:
server_perms = server_perms[0]
except TypeError:
server_perms = {}
cmd = self.bot.get_command(command)
if cmd is None:
await ctx.send("That is not a valid command!")
return
server_settings = await utils.get_content('server_settings', ctx.message.guild.id)
try:
server_perms = server_settings[0]['permissions']
except (TypeError, IndexError):
server_perms = {}
perms_value = server_perms.get(cmd.qualified_name)
if perms_value is None:
# If we don't find custom permissions, get the required permission for a command
@ -257,6 +278,13 @@ class Mod:
"`perms add <command> <permission>`")
return
cmd = self.bot.get_command(command)
if cmd is None:
await ctx.send(
"That command does not exist! You can't have custom permissions on a non-existant command....")
return
# If a user can run a command, they have to have send_messages permissions; so use this as the base
if permissions.lower() == "none":
permissions = "send_messages"
@ -272,13 +300,6 @@ class Mod:
return
perm_value = perm_obj.value
cmd = self.bot.get_command(command)
if cmd is None:
await ctx.send(
"That command does not exist! You can't have custom permissions on a non-existant command....")
return
# Two cases I use should never have custom permissions setup on them, is_owner for obvious reasons
# The other case is if I'm using the default has_permissions case
# Which means I do not want to check custom permissions at all
@ -288,19 +309,13 @@ class Mod:
await ctx.send("This command cannot have custom permissions setup!")
return
r_filter = {'server_id': ctx.message.guild.id}
key = ctx.message.guild.id
entry = {'server_id': ctx.message.guild.id,
cmd.qualified_name: perm_value}
'permissions': {cmd.qualified_name: perm_value}}
# In all other cases, I've used add_content before update_content
# In this case, I'm going the other way around, to make the least queries
# As custom permissions are probably going to be ran multiple times per server
# Whereas in most other cases, the command is probably going to be ran once/few times per server
if not await utils.update_content('custom_permissions', entry, r_filter):
await utils.add_content('custom_permissions', entry, r_filter)
if not await utils.update_content('server_settings', entry, key):
await utils.add_content('server_settings', entry)
# Same case as prefixes, for now, trigger a manual update
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
await ctx.send("I have just added your custom permissions; "
"you now need to have `{}` permissions to use the command `{}`".format(permissions, command))
@ -319,13 +334,10 @@ class Mod:
"That command does not exist! You can't have custom permissions on a non-existant command....")
return
r_filter = {'server_id': ctx.message.guild.id}
await utils.replace_content('custom_permissions', r.row.without(cmd.qualified_name), r_filter)
update = {'permissions': {cmd.qualified_name: None}}
await utils.update_content('custom_permissions', update, ctx.message.guild.id)
await ctx.send("I have just removed the custom permissions for {}!".format(cmd))
# Same case as prefixes, for now, trigger a manual update
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
@commands.command(no_pm=True)
@utils.custom_perms(manage_guild=True)
async def prefix(self, ctx, *, prefix: str):
@ -333,15 +345,15 @@ class Mod:
EXAMPLE: !prefix new_prefix
RESULT: You probably screwing it up and not realizing you now need to do new_prefixprefix"""
r_filter = {'server_id': ctx.message.guild.id}
key = ctx.message.guild.id
if prefix.lower().strip() == "none":
prefix = None
entry = {'server_id': ctx.message.guild.id,
'prefix': prefix}
if not await utils.add_content('prefixes', entry, r_filter):
await utils.update_content('prefixes', entry, r_filter)
if not await utils.update_content('server_settings', entry, key):
await utils.add_content('prefixes', entry)
if prefix is None:
fmt = "I have just cleared your custom prefix, the default prefix will have to be used now"
@ -439,16 +451,14 @@ class Mod:
EXAMPLE: !rules 5
RESULT: Rule 5 is printed"""
r_filter = {'server_id': ctx.message.guild.id}
rules = await utils.get_content('rules', r_filter)
try:
rules = rules[0]['rules']
except TypeError:
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
return
if len(rules) == 0:
server_settings = await utils.get_content('server_settings', ctx.message.guild.id)
rules = server_settings['rules']
if not rules or len(rules) == 0:
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
return
else:
rules = rules[0]
if rule is None:
try:
@ -472,12 +482,18 @@ class Mod:
EXAMPLE: !rules add No fun allowed in this server >:c
RESULT: No more fun...unless they break the rules!"""
r_filter = {'server_id': ctx.message.guild.id}
key = ctx.message.guild.id
entry = {'server_id': ctx.message.guild.id,
'rules': [rule]}
update = {'rules': r.row['rules'].append(rule)}
if not await utils.update_content('rules', update, r_filter):
await utils.add_content('rules', entry, r_filter)
server_settings = await utils.get_content('server_settings', key)
if server_settings and 'rules' in server_settings[0].keys():
await utils.update_content('server_settings', update, key)
elif server_settings:
await utils.update_content('server_settings', entry, key)
else:
await utils.add_content('server_settings', entry)
await ctx.send("I have just saved your new rule, use the rules command to view this server's current rules")
@ -489,9 +505,8 @@ class Mod:
EXAMPLE: !rules delete 5
RESULT: Freedom from opression!"""
r_filter = {'server_id': ctx.message.guild.id}
update = {'rules': r.row['rules'].delete_at(rule - 1)}
if not await utils.update_content('rules', update, r_filter):
if not await utils.update_content('server_settings', update, ctx.message.guild.id):
await ctx.send("That is not a valid rule number, try running the command again.")
else:
await ctx.send("I have just removed that rule from your list of rules!")

View file

@ -38,8 +38,7 @@ class Overwatch:
await ctx.message.channel.trigger_typing()
user = user or ctx.message.author
r_filter = {'member_id': user.id}
ow_stats = await utils.get_content('overwatch', r_filter)
ow_stats = await utils.get_content('overwatch', user.id)
if ow_stats is None:
await ctx.send("I do not have this user's battletag saved!")
@ -96,7 +95,7 @@ class Overwatch:
# Battletags are normally provided like name#id
# However the API needs this to be a -, so repliace # with - if it exists
bt = bt.replace("#", "-")
r_filter = {'member_id': ctx.message.author.id}
key = ctx.message.author.id
# This API sometimes takes a while to look up information, so send a message saying we're processing
await ctx.send("Looking up your profile information....")
@ -113,8 +112,8 @@ class Overwatch:
entry = {'member_id': ctx.message.author.id, 'battletag': bt}
update = {'battletag': bt}
# Try adding this first, if that fails, update the saved entry
if not await utils.add_content('overwatch', entry, r_filter):
await utils.update_content('overwatch', update, r_filter)
if not await utils.add_content('overwatch', entry):
await utils.update_content('overwatch', update, key)
await ctx.send("I have just saved your battletag {}".format(ctx.message.author.mention))
@ow.command(pass_context=True, name="delete", aliases=['remove'])
@ -124,8 +123,7 @@ class Overwatch:
EXAMPLE: !ow delete
RESULT: Your battletag is no longer saved"""
r_filter = {'member_id': ctx.message.author.id}
if await utils.remove_content('overwatch', r_filter):
if await utils.remove_content('overwatch', ctx.message.author.id):
await ctx.send("I no longer have your battletag saved {}".format(ctx.message.author.mention))
else:
await ctx.send("I don't even have your battletag saved {}".format(ctx.message.author.mention))

View file

@ -22,12 +22,12 @@ class Owner:
async def motd_push(self, ctx, *, message):
"""Used to push a new message to the message of the day"""
date = pendulum.utcnow().to_date_string()
r_filter = {'date': date}
key = date
entry = {'motd': message, 'date': date}
# Try to add this, if there's an entry for that date, lets update it to make sure only one motd is sent a day
# I should be managing this myself, more than one should not be sent in a day
if await utils.add_content('motd', entry, r_filter):
await utils.update_content('motd', entry, r_filter)
if await utils.add_content('motd', entry):
await utils.update_content('motd', entry, key)
await ctx.send("New motd update for {}!".format(date))
@commands.command()

View file

@ -51,7 +51,7 @@ class Picarto:
try:
while not self.bot.is_closed:
r_filter = {'notifications_on': 1}
picarto = await utils.get_content('picarto', r_filter)
picarto = await utils.filter_content('picarto', r_filter)
# Get all online users before looping, so that only one request is needed
online_users_list = await online_users()
old_online_users = {data['member_id']: data for data in picarto if data['live']}
@ -123,8 +123,7 @@ class Picarto:
RESULT: Info about their picarto stream"""
# If member is not given, base information on the author
member = member or ctx.message.author
r_filter = {'member_id': member.id}
picarto_entry = await utils.get_content('picarto', r_filter)
picarto_entry = await utils.get_content('picarto', member.id)
if picarto_entry is None:
await ctx.send("That user does not have a picarto url setup!")
return
@ -184,26 +183,25 @@ class Picarto:
"user? Silly")
return
r_filter = {'member_id': ctx.message.author.id}
key = ctx.message.author.id
entry = {'picarto_url': url,
'servers': [ctx.message.guild.id],
'notifications_on': 1,
'live': 0,
'member_id': ctx.message.author.id}
if await utils.add_content('picarto', entry, r_filter):
if await utils.add_content('picarto', entry):
await ctx.send(
"I have just saved your Picarto URL {}, this guild will now be notified when you go live".format(
ctx.message.author.mention))
else:
await utils.update_content('picarto', {'picarto_url': url}, r_filter)
await utils.update_content('picarto', {'picarto_url': url}, key)
await ctx.send("I have just updated your Picarto URL")
@picarto.command(name='remove', aliases=['delete'], no_pm=True)
@utils.custom_perms(send_messages=True)
async def remove_picarto_url(self, ctx):
"""Removes your picarto URL"""
r_filter = {'member_id': ctx.message.author.id}
if await utils.remove_content('picarto', r_filter):
if await utils.remove_content('picarto', ctx.message.author.id):
await ctx.send("I am no longer saving your picarto URL {}".format(ctx.message.author.mention))
else:
await ctx.send(
@ -218,8 +216,7 @@ class Picarto:
EXAMPLE: !picarto notify
RESULT: This guild will now be notified of you going live"""
r_filter = {'member_id': ctx.message.author.id}
result = await utils.get_content('picarto', r_filter)
result = await utils.get_content('picarto', ctx.message.author.id)
# Check if this user is saved at all
if result is None:
await ctx.send(
@ -230,7 +227,7 @@ class Picarto:
await ctx.send("I am already set to notify in this guild...")
else:
await utils.update_content('picarto', {'servers': r.row['servers'].append(ctx.message.guild.id)},
r_filter)
ctx.message.author.id)
@notify.command(name='on', aliases=['start,yes'], no_pm=True)
@utils.custom_perms(send_messages=True)
@ -239,8 +236,7 @@ class Picarto:
EXAMPLE: !picarto notify on
RESULT: Notifications are sent when you go live"""
r_filter = {'member_id': ctx.message.author.id}
await utils.update_content('picarto', {'notifications_on': 1}, r_filter)
await utils.update_content('picarto', {'notifications_on': 1}, ctx.message.author.id)
await ctx.send("I will notify if you go live {}, you'll get a bajillion followers I promise c:".format(
ctx.message.author.mention))
@ -251,8 +247,7 @@ class Picarto:
EXAMPLE: !picarto notify off
RESULT: No more notifications sent when you go live"""
r_filter = {'member_id': ctx.message.author.id}
await utils.update_content('picarto', {'notifications_on': 0}, r_filter)
await utils.update_content('picarto', {'notifications_on': 0}, ctx.message.author.id)
await ctx.send(
"I will not notify if you go live anymore {}, "
"are you going to stream some lewd stuff you don't want people to see?~".format(

View file

@ -74,8 +74,7 @@ class Raffle:
# No matter which one of these matches were met, the raffle has ended and we want to remove it
# We don't have to wait for it however, so create a task for it
r_filter = {'id': raffle_id}
self.bot.loop.create_task(utils.remove_content('raffles', r_filter))
self.bot.loop.create_task(utils.remove_content('raffles', raffle_id))
try:
await server.send(fmt)
except discord.Forbidden:
@ -89,7 +88,7 @@ class Raffle:
EXAMPLE: !raffles
RESULT: A list of the raffles setup on this server"""
r_filter = {'server_id': ctx.message.guild.id}
raffles = await utils.get_content('raffles', r_filter)
raffles = await utils.filter_content('raffles', r_filter)
if raffles is None:
await ctx.send("There are currently no raffles setup on this server!")
return
@ -114,7 +113,7 @@ class Raffle:
r_filter = {'server_id': ctx.message.guild.id}
author = ctx.message.author
raffles = await utils.get_content('raffles', r_filter)
raffles = await utils.filter_content('raffles', r_filter)
if raffles is None:
await ctx.send("There are currently no raffles setup on this server!")
return
@ -130,10 +129,8 @@ class Raffle:
return
entrants.append(author.id)
# Since we have no good thing to filter things off of, lets use the internal rethinkdb id
r_filter = {'id': raffles[0]['id']}
update = {'entrants': entrants}
await utils.update_content('raffles', update, r_filter)
await utils.update_content('raffles', update, raffles[0]['id'])
await ctx.send("{} you have just entered the raffle!".format(author.mention))
# Otherwise, make sure the author gave a valid raffle_id
elif raffle_id in range(raffle_count - 1):
@ -146,9 +143,8 @@ class Raffle:
entrants.append(author.id)
# Since we have no good thing to filter things off of, lets use the internal rethinkdb id
r_filter = {'id': raffles[raffle_id]['id']}
update = {'entrants': entrants}
await utils.update_content('raffles', update, r_filter)
await utils.update_content('raffles', update, raffles[raffle_id]['id'])
await ctx.send("{} you have just entered the raffle!".format(author.mention))
else:
fmt = "Please provide a valid raffle ID, as there are more than one setup on the server! " \

View file

@ -61,8 +61,7 @@ class Stats:
await ctx.send("`{}` is not a valid command".format(command))
return
r_filter = {'command': cmd.qualified_name}
command_stats = await utils.get_content('command_usage', r_filter)
command_stats = await utils.get_content('command_usage', cmd.qualified_name)
try:
command_stats = command_stats[0]
except TypeError:
@ -140,8 +139,7 @@ class Stats:
EXAMPLE: !mostboops
RESULT: You've booped @OtherPerson 351253897120935712093572193057310298 times!"""
r_filter = {'member_id': ctx.message.author.id}
boops = await utils.get_content('boops', r_filter)
boops = await utils.get_content('boops', ctx.message.author.id)
if boops is None:
await ctx.send("You have not booped anyone {} Why the heck not...?".format(ctx.message.author.mention))
return
@ -171,8 +169,7 @@ class Stats:
EXAMPLE: !listboops
RESULT: The list of your booped members!"""
r_filter = {'member_id': ctx.message.author.id}
boops = await utils.get_content('boops', r_filter)
boops = await utils.get_content('boops', ctx.message.author.id)
if boops is None:
await ctx.send("You have not booped anyone {} Why the heck not...?".format(ctx.message.author.mention))
return

View file

@ -131,7 +131,7 @@ class Strawpoll:
'polls': [sub_entry]}
update = {'polls': r.row['polls'].append(sub_entry)}
if not await config.update_content('strawpolls', update, r_filter):
await config.add_content('strawpolls', entry, {'poll_id': poll_id})
await config.add_content('strawpolls', entry)
await ctx.send("Link for your new strawpoll: https://strawpoll.me/{}".format(poll_id))
@strawpolls.command(name='delete', aliases=['remove', 'stop'], pass_context=True, no_pm=True)

View file

@ -35,7 +35,7 @@ class Tags:
EXAMPLE: !tag butts
RESULT: Whatever you setup for the butts tag!!"""
r_filter = lambda row: (row['server_id'] == ctx.message.guild.id) & (row['tag'] == tag)
tags = await utils.get_content('tags', r_filter)
tags = await utils.filter_content('tags', r_filter)
if tags is None:
await ctx.send('That tag does not exist!')
return
@ -73,13 +73,11 @@ class Tags:
entry = {'server_id': ctx.message.guild.id, 'tag': tag, 'result': tag_result}
r_filter = lambda row: (row['server_id'] == ctx.message.guild.id) & (row['tag'] == tag)
# Try to create new entry first, if that fails (it already exists) then we update it
if await utils.add_content('tags', entry, r_filter):
if await utils.filter_content('tags', entry, r_filter):
await ctx.send(
"I have just added the tag `{0}`! You can call this tag by entering !tag {0}".format(tag))
else:
await utils.update_content('tags', entry, r_filter)
await ctx.send(
"I have just updated the tag `{0}`! You can call this tag by entering !tag {0}".format(tag))
await ctx.send("That tag already exists!")
@tag.command(name='delete', aliases=['remove', 'stop'], no_pm=True)
@utils.custom_perms(kick_members=True)
@ -89,12 +87,14 @@ class Tags:
EXAMPLE: !tag delete stupid_tag
RESULT: Deletes that stupid tag"""
r_filter = lambda row: (row['server_id'] == ctx.message.guild.id) & (row['tag'] == tag)
await ctx.send("Temporarily disabled")
// TODO: Fix tags, this will inherently fix this method
"""r_filter = lambda row: (row['server_id'] == ctx.message.guild.id) & (row['tag'] == tag)
if await utils.remove_content('tags', r_filter):
await ctx.send('I have just removed the tag `{}`'.format(tag))
else:
await ctx.send(
"The tag {} does not exist! You can't remove something if it doesn't exist...".format(tag))
"The tag {} does not exist! You can't remove something if it doesn't exist...".format(tag))"""
def setup(bot):

View file

@ -45,7 +45,7 @@ class Twitch:
# Loop through as long as the bot is connected
try:
while not self.bot.is_closed:
twitch = await utils.get_content('twitch', {'notifications_on': 1})
twitch = await utils.filter_content('twitch', {'notifications_on': 1})
# Online/offline is based on whether they are set to such, in the utils file
# This means they were detected as online/offline before and we check for a change
online_users = {data['member_id']: data for data in twitch if data['live']}
@ -61,7 +61,7 @@ class Twitch:
server = self.bot.get_server(server_id)
if server is None:
continue
server_alerts = await utils.get_content('server_alerts', {'server_id': server_id})
server_alerts = await utils.get_content('server_alerts', server_id)
try:
channel_id = server_alerts[0]['channel_id']
except (IndexError, TypeError):
@ -161,7 +161,7 @@ class Twitch:
"What would be the point of adding a nonexistant twitch user? Silly")
return
r_filter = {'member_id': ctx.message.author.id}
key = ctx.message.author.id
entry = {'twitch_url': url,
'servers': [ctx.message.guild.id],
'notifications_on': 1,
@ -172,8 +172,8 @@ class Twitch:
# Check to see if this user has already saved a twitch URL
# If they have, update the URL, otherwise create a new entry
# Assuming they're not live, and notifications should be on
if not await utils.add_content('twitch', entry, r_filter):
await utils.update_content('twitch', update, r_filter)
if not await utils.add_content('twitch', entry):
await utils.update_content('twitch', update, key)
await ctx.send("I have just saved your twitch url {}".format(ctx.message.author.mention))
@twitch.command(name='remove', aliases=['delete'], no_pm=True)
@ -184,8 +184,7 @@ class Twitch:
EXAMPLE: !twitch remove
RESULT: I stop saving your twitch URL"""
# Just try to remove it, if it doesn't exist, nothing is going to happen
r_filter = {'member_id': ctx.message.author.id}
await utils.remove_content('twitch', r_filter)
await utils.remove_content('twitch', ctx.message.author.id)
await ctx.send("I am no longer saving your twitch URL {}".format(ctx.message.author.mention))
@twitch.group(no_pm=True, invoke_without_command=True)
@ -196,8 +195,8 @@ class Twitch:
EXAMPLE: !twitch notify
RESULT: This server will now be notified when you go live"""
r_filter = {'member_id': ctx.message.author.id}
result = await utils.get_content('twitch', r_filter)
key = ctx.message.author.id
result = await utils.get_content('twitch', key)
# Check if this user is saved at all
if result is None:
await ctx.send(
@ -207,7 +206,7 @@ class Twitch:
elif ctx.message.guild.id in result[0]['servers']:
await ctx.send("I am already set to notify in this server...")
else:
await utils.update_content('twitch', {'servers': r.row['servers'].append(ctx.message.guild.id)}, r_filter)
await utils.update_content('twitch', {'servers': r.row['servers'].append(ctx.message.guild.id)}, key)
await ctx.send("This server will now be notified if you go live")
@notify.command(name='on', aliases=['start,yes'], no_pm=True)
@ -217,8 +216,7 @@ class Twitch:
EXAMPLE: !twitch notify on
RESULT: Notifications will be sent when you go live"""
r_filter = {'member_id': ctx.message.author.id}
if await utils.update_content('twitch', {"notifications_on": 1}, r_filter):
if await utils.update_content('twitch', {"notifications_on": 1}, ctx.message.author.id):
await ctx.send("I will notify if you go live {}, you'll get a bajillion followers I promise c:".format(
ctx.message.author.mention))
else:
@ -231,8 +229,7 @@ class Twitch:
EXAMPLE: !twitch notify off
RESULT: Notifications will not be sent when you go live"""
r_filter = {'member_id': ctx.message.author.id}
if await utils.update_content('twitch', {"notifications_on": 1}, r_filter):
if await utils.update_content('twitch', {"notifications_on": 1}, ctx.message.author.id):
await ctx.send(
"I will not notify if you go live anymore {}, "
"are you going to stream some lewd stuff you don't want people to see?~".format(

View file

@ -7,10 +7,22 @@ from . import config
loop = asyncio.get_event_loop()
# The list of tables needed for the database
table_list = ['battle_records', 'battling', 'boops', 'bot_data', 'command_usage', 'custom_permissions',
'deviantart', 'motd', 'nsfw_channels', 'overwatch', 'picarto', 'prefixes', 'raffles',
'rules', 'server_alerts', 'strawpolls', 'tags', 'tictactoe', 'twitch', 'user_notifications']
# The tables needed for the database, as well as their primary keys
required_tables = {
'battle_records': 'member_id',
'boops': 'member_id',
'command_usage': 'command',
'deviantart': 'member_id',
'motd': 'date',
'overwatch': 'member_id',
'picarto': 'member_id',
'server_settings': 'guild_id',
'raffles': 'id',
'strawpolls': 'guild_id',
'tags': 'guild_id',
'tictactoe': 'member_id',
'twitch': 'member_id'
}
async def db_check():
@ -36,17 +48,17 @@ async def db_check():
print('Couldn\'t find database {}...creating now'.format(db_opts['db']))
await r.db_create(db_opts['db']).run(conn)
# Then add all the tables
for table in table_list:
for table, key in required_tables.items():
print("Creating table {}...".format(table))
await r.table_create(table).run(conn)
await r.table_create(table, primary_key=key).run(conn)
print("Done!")
else:
# Otherwise, if the database is setup, make sure all the required tables are there
tables = await r.table_list().run(conn)
for table in table_list:
for table, key in required_tables.items():
if table not in tables:
print("Creating table {}...".format(table))
await r.table_create(table).run(conn)
await r.table_create(table, primary_key=key).run(conn)
print("Done checking tables!")
@ -68,15 +80,12 @@ def custom_perms(**perms):
for perm, setting in perms.items():
setattr(required_perm, perm, setting)
perm_values = config.cache.get('custom_permissions').values
# Loop through and find this server's entry for custom permissions
# Find the command we're using, if it exists, then overwrite
# The required permissions, based on the value saved
if perm_values:
for x in perm_values:
if x['server_id'] == ctx.message.guild.id and x.get(ctx.command.qualified_name):
required_perm = discord.Permissions(x[ctx.command.qualified_name])
server_settings = config.cache.get('server_settings').values[ctx.message.guild.id]
try:
required_perm_value = server_settings['permissions'][ctx.command.qualified_name]
required_perm = discord.Permissions(required_perm_value)
except (TypeError, IndexError):
pass
# Now just check if the person running the command has these permissions
return member_perms >= required_perm

View file

@ -106,7 +106,7 @@ cache = {}
# We still need 'cache' for prefixes and custom permissions however, so for now, just include that
cache['prefixes'] = Cache('prefixes')
cache['custom_permissions'] = Cache('custom_permissions')
cache['server_settings'] = Cache('server_settings')
async def update_cache():
for value in cache.values():
@ -119,56 +119,45 @@ def command_prefix(bot, message):
# If the prefix does exist in the database and isn't in our cache; too bad, something has messed up
# But it is not worth a query for every single message the bot detects, to fix
try:
values = cache['prefixes'].values
prefix = [data['prefix'] for data in values if message.guild.id == data['server_id']][0]
prefix = cache['server_settings'].values[message.guild.id]['prefix']
return prefix or default_prefix
except (KeyError, TypeError, IndexError, AttributeError):
return default_prefix
async def add_content(table, content, r_filter=None):
async def add_content(table, content):
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
# First we need to make sure that this entry doesn't exist
# For all rethinkDB cares, multiple entries can exist with the same content
# For our purposes however, we do not want this
try:
if r_filter is not None:
cursor = await r.table(table).filter(r_filter).run(conn)
cur_content = await _convert_to_list(cursor)
if len(cur_content) > 0:
await conn.close()
return False
await r.table(table).insert(content).run(conn)
result = await r.table(table).insert(content).run(conn)
await conn.close()
return True
except r.ReqlOpFailedError:
# This means the table does not exist
await r.table_create(table).run(conn)
await r.table(table).insert(content).run(conn)
await conn.close()
return True
result = {}
return result.get('inserted', 0) > 0
async def remove_content(table, r_filter=None):
if r_filter is None:
r_filter = {}
async def remove_content(table, key):
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
try:
result = await r.table(table).filter(r_filter).delete().run(conn)
result = await r.table(table).get(key).delete().run(conn)
except r.ReqlOpFailedError:
result = {}
pass
await conn.close()
if table == 'prefixes' or table == 'custom_permissions':
if table == 'prefixes' or table == 'server_settings':
loop.create_task(cache[table].update())
return result.get('deleted', 0) > 0
async def update_content(table, content, r_filter=None):
if r_filter is None:
r_filter = {}
async def update_content(table, content, key):
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
# This method is only for updating content, so if we find that it doesn't exist, just return false
@ -176,36 +165,54 @@ async def update_content(table, content, r_filter=None):
# Update based on the content and filter passed to us
# rethinkdb allows you to do many many things inside of update
# This is why we're accepting a variable and using it, whatever it may be, as the query
result = await r.table(table).filter(r_filter).update(content).run(conn)
result = await r.table(table).get(key).update(content).run(conn)
except r.ReqlOpFailedError:
await conn.close()
result = {}
await conn.close()
if table == 'prefixes' or table == 'custom_permissions':
if table == 'prefixes' or table == 'server_settings':
loop.create_task(cache[table].update())
return result.get('replaced', 0) > 0 or result.get('unchanged', 0) > 0
async def replace_content(table, content, r_filter=None):
async def replace_content(table, content, key):
# This method is here because .replace and .update can have some different functionalities
if r_filter is None:
r_filter = {}
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
try:
result = await r.table(table).filter(r_filter).replace(content).run(conn)
result = await r.table(table).get(key).replace(content).run(conn)
except r.ReqlOpFailedError:
await conn.close()
result = {}
await conn.close()
if table == 'prefixes' or table == 'custom_permissions':
if table == 'prefixes' or table == 'server_settings':
loop.create_task(cache[table].update())
return result.get('replaced', 0) > 0 or result.get('unchanged', 0) > 0
async def get_content(table: str, r_filter=None):
if r_filter is None:
r_filter = {}
async def get_content(table, key=None):
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
try:
if key:
cursor = await r.table(table).get(key).run(conn)
else:
cursor = await r.table(table).run()
if cursor is None:
content = None
else:
content = await _convert_to_list(cursor)
if len(content) == 0:
content = None
except (IndexError, r.ReqlOpFailedError):
content = None
await conn.close()
if table == 'prefixes' or table == 'server_settings':
loop.create_task(cache[table].update())
return content
async def filter_content(table: str, r_filter):
r.set_loop_type("asyncio")
conn = await r.connect(**db_opts)
try:
@ -216,7 +223,7 @@ async def get_content(table: str, r_filter=None):
except (IndexError, r.ReqlOpFailedError):
content = None
await conn.close()
if table == 'prefixes' or table == 'custom_permissions':
if table == 'prefixes' or table == 'server_settings':
loop.create_task(cache[table].update())
return content

View file

@ -43,6 +43,17 @@ def get_subcommands(command):
except AttributeError:
pass
async def channel_is_nsfw(channel):
server = channel.guild.id
channel = channel.id
server_settings = await config.get_content('server_settings', server)
try:
return channel in server_settings[0]['nsfw_channels']
except (TypeError, IndexError):
return False
async def download_image(url):
"""Returns a file-like object based on the URL provided"""
@ -98,7 +109,7 @@ async def update_records(key, winner, loser):
# We're using the Harkness scale to rate
# http://opnetchessclub.wikidot.com/harkness-rating-system
r_filter = lambda row: (row['member_id'] == winner.id) | (row['member_id'] == loser.id)
matches = await config.get_content(key, r_filter)
matches = await config.filter_content(key, r_filter)
winner_stats = {}
loser_stats = {}
@ -148,7 +159,7 @@ async def update_records(key, winner, loser):
if not await config.update_content(key, winner_stats, {'member_id': winner.id}):
winner_stats['member_id'] = winner.id
await config.add_content(key, winner_stats, {'member_id': winner.id})
await config.add_content(key, winner_stats)
if not await config.update_content(key, loser_stats, {'member_id': loser.id}):
loser_stats['member_id'] = loser.id
await config.add_content(key, loser_stats, {'member_id': loser.id})
await config.add_content(key, loser_stats)