Browse Source

Start of the DB migration. Admin done and some ground work put in place.

tags/v2.2.0
Roxie Gibson 5 years ago
parent
commit
e63f894fed
5 changed files with 133 additions and 106 deletions
  1. +1
    -0
      requirements.txt
  2. +4
    -0
      roxbot.py
  3. +1
    -1
      roxbot/__init__.py
  4. +91
    -105
      roxbot/cogs/admin.py
  5. +36
    -0
      roxbot/db.py

+ 1
- 0
requirements.txt View File

@@ -5,3 +5,4 @@ numpy==1.14.3
youtube_dl
emoji==0.5.1
dataset==1.1.0
pony==0.7.9

+ 4
- 0
roxbot.py View File

@@ -35,6 +35,7 @@ from discord.ext import commands
import roxbot
from roxbot import guild_settings as gs
from roxbot import core
from roxbot import db


class term:
@@ -175,6 +176,9 @@ if __name__ == "__main__":
except ImportError:
print("{} FAILED TO LOAD. MISSING REQUIREMENTS".format(cog.split(".")[2]))

# This commits all the entities defined by the cogs. These are loaded above. Do Not Remove.
db.db.generate_mapping(create_tables=True)

print(term.seperator)
print("Client logging in...", end="\r")


+ 1
- 1
roxbot/__init__.py View File

@@ -29,7 +29,7 @@ from .enums import EmbedColours
from .config import config
from .exceptions import UserError, CogSettingDisabled

from . import checks, http, guild_settings, converters, utils, roxbotfacts, exceptions
from . import checks, http, guild_settings, converters, utils, roxbotfacts, exceptions, db


command_prefix = config["Roxbot"]["Command_Prefix"]

+ 91
- 105
roxbot/cogs/admin.py View File

@@ -24,23 +24,25 @@


import datetime
import time

import discord
from discord.ext import commands

import roxbot
from roxbot import guild_settings as gs
from roxbot.db import *


def _is_admin_or_mod(message):
if message.author.id == roxbot.owner:
return True
perm_roles = gs.get(message.channel.guild).perm_roles
for role in message.author.roles:
if role.id in perm_roles.get("admin") or role.id in perm_roles.get("mod"):
return True
return False
class AdminSingle(db.Entity):
warning_limit = Required(int, default=0)
guild = Required(int, unique=True, size=64)


class AdminWarnings(db.Entity):
user_id = Required(int, size=64)
warned_by = Required(int, size=64)
warning = Optional(str)
date = Required(datetime.datetime)
guild_id = Required(int, size=64)


class Admin:
@@ -126,7 +128,7 @@ class Admin:
@commands.bot_has_permissions(manage_messages=True, read_message_history=True)
@commands.cooldown(1, 5)
@commands.command()
async def purge(self, ctx, limit=0, *, author: roxbot.converters.User=None):
async def purge(self, ctx, limit=0, *, author: roxbot.converters.User = None):
"""Purges the text channel the command is execture in. You can specify a certain user to purge as well.

Options:
@@ -160,7 +162,7 @@ class Admin:
raise commands.CommandNotFound("Subcommand '{}' does not exist.".format(ctx.subcommand_passed))

@warn.command()
async def add(self, ctx, user: discord.User=None, *, warning=""):
async def add(self, ctx, user: discord.User = None, *, warning=""):
"""Adds a warning to a user.

Options:
@@ -173,29 +175,19 @@ class Admin:
"""

# Warning in the settings is a dictionary of user ids. The user ids are equal to a list of dictionaries.
settings = gs.get(ctx.guild)
warnings = settings["admin"]["warnings"]
warning_limit = settings["admin"]["warning_limit"]
warning_dict = {
"warned-by": ctx.author.id,
"date": time.time(),
"warning": warning
}
user_id = str(user.id)

if user_id not in warnings:
warnings[user_id] = []
with db_session:
warning_limit = AdminSingle.get(guild=ctx.guild.id).warning_limit
user_warnings = select(w for w in AdminWarnings if w.user_id == user.id and w.guild_id == ctx.guild.id)[:]
amount_warnings = len(user_warnings)

warn_limit = 10
if len(warnings[user_id]) > warn_limit:
if amount_warnings > warn_limit:
embed = discord.Embed(description=self.WARN_WARN_ADD_LIMIT_REACHED.format(warn_limit), colour=roxbot.EmbedColours.red)
return await ctx.send(embed=embed)

warnings[user_id].append(warning_dict)
settings["admin"]["warnings"] = warnings
settings.update(settings["admin"], "admin")
with db_session:
AdminWarnings(user_id=user.id, warned_by=ctx.author.id, date=datetime.datetime.utcnow(), warning=warning, guild_id=ctx.guild.id)

amount_warnings = len(warnings[user_id])
if amount_warnings >= warning_limit > 0:
await ctx.author.send(self.OK_WARN_ADD_USER_LIMIT_DM.format(str(user), amount_warnings, warning_limit))

@@ -203,7 +195,7 @@ class Admin:
return await ctx.send(embed=embed)

@warn.command()
async def list(self, ctx, *, user: roxbot.converters.User=None):
async def list(self, ctx, *, user: roxbot.converters.User = None):
"""Lists all warning in this guild or all the warnings for one user.

Options:
@@ -215,35 +207,35 @@ class Admin:
# List all warnings for @Roxbot
;warn list @Roxbot
"""
settings = gs.get(ctx.guild)
warnings = settings["admin"]["warnings"]

if user is None:
paginator = commands.Paginator()
for member in warnings:
# Remove users with no warning here instead of remove cause im lazy
if not warnings[member]:
warnings.pop(member)
else:
member_obj = discord.utils.get(ctx.guild.members, id=int(member))
if member_obj:
paginator.add_line("{}: {} Warning(s)".format(str(member_obj), len(warnings[member])))
warnings = {}
with db_session:
for warning in select(warn for warn in AdminWarnings if warn.guild_id == ctx.guild.id)[:]:
if warning.user_id not in warnings:
warnings[warning.user_id] = []
else:
paginator.add_line("{}: {} Warning(s)".format(member, len(warnings[member])))
warnings[warning.user_id].append(warning)

for u, warning in warnings.items():
member_obj = discord.utils.get(ctx.guild.members, id=u)
if member_obj:
paginator.add_line("{}: {} Warning(s)".format(str(member_obj), len(warnings[u])))
else:
paginator.add_line("{}: {} Warning(s)".format(u, len(warnings[u])))
# This is in case we have removed some users from the list.
settings["admin"]["warnings"] = warnings
settings.update(settings["admin"], "admin")

if not paginator.pages:
embed = discord.Embed(description=self.OK_WARN_LIST_NO_WARNINGS, colour=roxbot.EmbedColours.orange)
return await ctx.send(embed=embed)

for page in paginator.pages:
return await ctx.send(embed=discord.Embed(description=page, colour=roxbot.EmbedColours.pink))
return await ctx.send(page)
else:
user_id = str(user.id)
with db_session:
user_warnings = select(w for w in AdminWarnings if w.user_id == user.id and w.guild_id == ctx.guild.id)[:]

if not warnings.get(user_id):
if not user_warnings:
embed = discord.Embed(description=self.OK_WARN_LIST_USER_NO_WARNINGS, colour=roxbot.EmbedColours.orange)
return await ctx.send(embed=embed)

@@ -251,20 +243,20 @@ class Admin:
em.set_thumbnail(url=user.avatar_url)

x = 1
userlist = warnings[user_id]
for warning in userlist:
for warning in user_warnings:
try:
warned_by = str(await self.bot.get_user_info(warning["warned-by"]))
warned_by = str(ctx.guild.get_member(warning.warned_by))
if warned_by is None:
warned_by = str(await self.bot.get_user_info(warning.warned_by))
except discord.ext.commands.CommandInvokeError:
warned_by = warning["warned-by"]
date = roxbot.datetime.format(datetime.datetime.fromtimestamp(warning["date"]))
warn_reason = warning["warning"]
em.add_field(name="Warning %s" % x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warn_reason))
warned_by = warning.warned_by
date = datetime.datetime.strftime(warning.date, roxbot.datetime.strip("{:} UTC")+" UTC")
em.add_field(name="Warning %s" % x, value="Warned by: {}\nTime: {}\nReason: {}".format(warned_by, date, warning.warning))
x += 1
return await ctx.send(embed=em)

@warn.command()
async def remove(self, ctx, user: roxbot.converters.User=None, index=None):
async def remove(self, ctx, user: roxbot.converters.User, index=None):
"""Removes one or all of the warnings for a user.

Options:=
@@ -277,44 +269,40 @@ class Admin:
# Remove warning 2 for Roxbot
;warn remove Roxbot 2
"""
user_id = str(user.id)
settings = gs.get(ctx.guild)
warnings = settings["admin"]["warnings"]

if index:
try:
index = int(index)
index -= 1
warnings[user_id].pop(index)
if not warnings[user_id]:
warnings.pop(user_id)

settings["admin"]["warnings"] = warnings
settings.update(settings["admin"], "admin")
embed = discord.Embed(description=self.OK_WARN_REMOVE_REMOVED_WARNING.format(index+1, str(user)), colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)

except Exception as e:
embed = discord.Embed(colour=roxbot.EmbedColours.red)
if isinstance(e, IndexError):
embed.description = self.ERROR_WARN_REMOVE_INDEXERROR.format(len(settings["warnings"][user_id]))
elif isinstance(e, KeyError):
embed.description = self.WARN_WARN_REMOVE_USER_NOT_FOUND.format(str(user))
elif isinstance(e, ValueError):
embed.description = self.ERROR_WARN_REMOVE_VALUEERROR
with db_session:
if index:
try:
index = int(index) - 1
query = select(w for w in AdminWarnings if w.user_id == user.id and w.guild_id == ctx.guild.id)
if query:
user_warnings = query[:]
else:
raise KeyError
user_warnings[index].delete()

embed = discord.Embed(description=self.OK_WARN_REMOVE_REMOVED_WARNING.format(index+1, str(user)), colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)

except Exception as e:
embed = discord.Embed(colour=roxbot.EmbedColours.red)
if isinstance(e, IndexError):
embed.description = self.ERROR_WARN_REMOVE_INDEXERROR.format(len(user_warnings))
elif isinstance(e, KeyError):
embed.description = self.WARN_WARN_REMOVE_USER_NOT_FOUND.format(str(user))
elif isinstance(e, ValueError):
embed.description = self.ERROR_WARN_REMOVE_VALUEERROR
else:
raise e
return await ctx.send(embed=embed)
else:
query = select(w for w in AdminWarnings if w.user_id == user.id and w.guild_id == ctx.guild.id)
if query.exists():
delete(w for w in AdminWarnings if w.user_id == user.id and w.guild_id == ctx.guild.id)
embed = discord.Embed(description=self.OK_WARN_REMOVE_REMOVED_WARNINGS.format(str(user)), colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)
else:
raise e
return ctx.send(embed=embed)
else:
try:
warnings.pop(user_id)
settings["admin"]["warnings"] = warnings
settings.update(settings["admin"], "admin")
embed = discord.Embed(description=self.OK_WARN_REMOVE_REMOVED_WARNINGS.format(str(user)), colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)
except KeyError:
embed = discord.Embed(description=self.WARN_WARN_REMOVE_USER_NOT_FOUND.format(str(user)), colour=roxbot.EmbedColours.orange)
return await ctx.send(embed=embed)
embed = discord.Embed(description=self.WARN_WARN_REMOVE_USER_NOT_FOUND.format(str(user)), colour=roxbot.EmbedColours.red)
return await ctx.send(embed=embed)

@commands.bot_has_permissions(ban_members=True)
@warn.command()
@@ -331,17 +319,15 @@ class Admin:
# Dryrun the prune command to see how many warnings would be removed
;warn prune 1
"""
settings = gs.get(ctx.guild)
warnings = settings["admin"]["warnings"].copy()
count = 0
x = 0
for ban in await ctx.guild.bans():
for user in warnings:
if int(user) == ban.user.id:
with db_session:
query = select(w for w in AdminWarnings if w.user_id == ban.user.id and w.guild_id == ctx.guild.id)
if query.exists():
if dry_run == 0:
settings["admin"]["warnings"].pop(user)
count += 1
settings.update(settings["admin"], "admin")
embed = discord.Embed(description=self.OK_WARN_PRUNE_PRUNED.format(count), colour=roxbot.EmbedColours.pink)
query.delete()
x += 1
embed = discord.Embed(description=self.OK_WARN_PRUNE_PRUNED.format(x), colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)

@warn.command(aliases=["sl", "setlimit"])
@@ -353,10 +339,10 @@ class Admin:
"""
if number_of_warnings < 0:
raise commands.BadArgument(self.ERROR_WARN_SL_NEG)
settings = gs.get(ctx.guild)
admin = settings["admin"]
admin["warning_limit"] = number_of_warnings
settings.update(admin, "admin")
with db_session:
guild_settings = AdminSingle.get(guild=ctx.guild.id)
guild_settings.warning_limit = number_of_warnings
if number_of_warnings == 0:
embed = discord.Embed(description=self.OK_WARN_SL_SET_ZERO, colour=roxbot.EmbedColours.pink)
return await ctx.send(embed=embed)

+ 36
- 0
roxbot/db.py View File

@@ -0,0 +1,36 @@
#
# Copyright (c) 2017-2018 Roxanne Gibson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from os import getcwd
from pony.orm import *

db = Database()
db.bind("sqlite", getcwd() + "/roxbot/settings/db.sqlite", create_db=True)


# Entities are committed to the db in the main file during boot up

class Guilds(db.Entity):
name = Required(str)


class Blacklist(db.Entity):
user_id = Required(int, size=64)

Loading…
Cancel
Save