From f9e5519661e6cdf511a9aca28f0209ccff976a69 Mon Sep 17 00:00:00 2001 From: Pachev Joseph Date: Mon, 1 Jan 2018 14:19:55 -0800 Subject: [PATCH 1/4] Renames member to character and adds server and member --- cogs/add.py | 8 ++++---- cogs/delete.py | 6 +++--- cogs/extras.py | 4 ++-- cogs/general.py | 6 +++--- cogs/listings.py | 16 +++++++-------- cogs/search.py | 20 +++++++++--------- cogs/update.py | 6 +++--- gsbot.py | 2 +- models/character.py | 49 +++++++++++++++++++++++++++++++++++++++++++++ models/member.py | 48 +++++++++----------------------------------- models/server.py | 17 ++++++++++++++++ utils.py | 6 ++++-- 12 files changed, 113 insertions(+), 75 deletions(-) create mode 100644 models/character.py create mode 100644 models/server.py diff --git a/cogs/add.py b/cogs/add.py index 2efb13a..8116016 100644 --- a/cogs/add.py +++ b/cogs/add.py @@ -3,7 +3,7 @@ from tabulate import tabulate from datetime import datetime -from models.member import Member +from models.character import Character from models.historical import Historical from utils import * @@ -17,7 +17,7 @@ async def __get_rank_and_discord_id(self, author, user, roles): if not user: discord_id = author.id rank = 'Officer' if ADMIN_USER in roles else 'Member' - if Member.objects(discord = author.id).count() >= 1: + if Character.objects(discord = author.id).count() >= 1: await self.bot.say(codify("Cannot add more than one character to this discord id. " "Try rerolling with gsbot reroll")) return (None, None) @@ -85,7 +85,7 @@ async def add(self, if rank is None or discord_id is None: return - member = Member.create({ + member = Character.create({ 'fam_name': fam_name, 'char_name': char_name, 'level': level, @@ -112,7 +112,7 @@ async def reroll(self, ctx, new_char_name, level: int, ap : int, dp: int, new_ch """Just for someone special: Allows you to reroll """ author = ctx.message.author.id - member = Member.objects(discord = author).first() + member = Character.objects(discord = author).first() date = datetime.now() if not member: await self.bot.say("Can't reroll if you're not in the database :(, try adding yoursell first") diff --git a/cogs/delete.py b/cogs/delete.py index 4b6dc45..edec435 100644 --- a/cogs/delete.py +++ b/cogs/delete.py @@ -2,7 +2,7 @@ from discord.ext import commands from tabulate import tabulate -from models.member import Member +from models.character import Character from utils import * @@ -20,9 +20,9 @@ async def delete(self, ctx, fam_name=''): try: author = ctx.message.author if not fam_name: - member = Member.objects(discord = author.id).first() + member = Character.objects(discord = author.id).first() else: - member = Member.objects(fam_name = fam_name, server = ctx.message.server.id).first() + member = Character.objects(fam_name = fam_name, server = ctx.message.server.id).first() roles = [u.name for u in author.roles] if ADMIN_USER not in roles: await self.bot.say("Only officers may perform this action") diff --git a/cogs/extras.py b/cogs/extras.py index 54199c0..f6d3776 100644 --- a/cogs/extras.py +++ b/cogs/extras.py @@ -3,7 +3,7 @@ from tabulate import tabulate from datetime import datetime -from models.member import Member +from models.character import Character from utils import * @@ -21,7 +21,7 @@ async def attach_pic(self, ctx, url): try: author = ctx.message.author - member = Member.objects(discord = author.id).first() + member = Character.objects(discord = author.id).first() member.gear_pic = url member.save() await self.bot.say(codify("Picture added successfully")) diff --git a/cogs/general.py b/cogs/general.py index b4bfd1a..ec64c6a 100644 --- a/cogs/general.py +++ b/cogs/general.py @@ -3,7 +3,7 @@ from discord.ext import commands from tabulate import tabulate -from models.member import Member +from models.character import Character from utils import * @@ -20,7 +20,7 @@ async def info(self, ctx): try: info = [] - members = Member.objects(server=ctx.message.server.id) + members = Character.objects(server=ctx.message.server.id) if members: officers = members(rank='Officer') average = members.average('gear_score') @@ -48,7 +48,7 @@ async def info(self, ctx): async def export(self): """Exports current guild data""" - members = Member.objects() + members = Character.objects() rows = get_row(members, False) rows.insert(0, HEADERS) try: diff --git a/cogs/listings.py b/cogs/listings.py index 269d073..6ae2f19 100644 --- a/cogs/listings.py +++ b/cogs/listings.py @@ -2,7 +2,7 @@ from discord.ext import commands from tabulate import tabulate -from models.member import Member +from models.character import Character from utils import * @@ -18,8 +18,8 @@ async def list(self,ctx,num=100): gear score""" try: print('server,', ctx.message.server.id) - members = Member.objects(server=ctx.message.server.id) - print(Member.objects().first().server) + members = Character.objects(server=ctx.message.server.id) + print(Character.objects().first().server) rows = get_row(members, True, num) data = tabulate(rows, @@ -36,7 +36,7 @@ async def list(self,ctx,num=100): async def over(self, ctx, num=400): """List all the members over a certain gear score""" try: - members = Member.objects(gear_score__gte = num, server = ctx.message.server.id) + members = Character.objects(gear_score__gte = num, server = ctx.message.server.id) rows = get_row(members,False) data = tabulate(rows, @@ -54,7 +54,7 @@ async def over(self, ctx, num=400): async def under(self, ctx, num=400): """List all the members under a certain gear score""" try: - members = Member.objects(gear_score__lte = num, server = ctx.message.server.id) + members = Character.objects(gear_score__lte = num, server = ctx.message.server.id) rows = get_row(members, False) data = tabulate(rows, HEADERS, @@ -77,7 +77,7 @@ async def sort_by(self, ctx): async def lvl(self, ctx, num=100): """ - Sorts list by level and progress with optional limiter""" try: - members = Member.objects(server = ctx.message.server.id).order_by('-level', '-progress') + members = Character.objects(server = ctx.message.server.id).order_by('-level', '-progress') rows = get_row(members, True, num) data = tabulate(rows, @@ -94,7 +94,7 @@ async def lvl(self, ctx, num=100): async def ap(self, ctx, num=100): """ - Sorts list by AP with optional limit""" try: - members = Member.objects(server=ctx.message.server.id).order_by('-ap') + members = Character.objects(server=ctx.message.server.id).order_by('-ap') rows = get_row(members, True, num) data = tabulate(rows, @@ -111,7 +111,7 @@ async def ap(self, ctx, num=100): async def dp(self, ctx, num=100): """ - Sorts list by DP with optional limit""" try: - members = Member.objects(server=ctx.message.server.id).order_by('-dp') + members = Character.objects(server=ctx.message.server.id).order_by('-dp') rows = get_row(members, True, num) data = tabulate(rows, diff --git a/cogs/search.py b/cogs/search.py index 7f3dea7..51eb497 100644 --- a/cogs/search.py +++ b/cogs/search.py @@ -3,7 +3,7 @@ from tabulate import tabulate from mongoengine import * -from models.member import Member +from models.character import Character from utils import * @@ -17,8 +17,8 @@ def __init__(self, bot): async def lookup(self, ctx, name=""): """Looks up a guild member by family name or character name""" try: - members = Member.objects(Q(fam_name__icontains = name) | Q(char_name__icontains = name), - server = ctx.message.server.id) + members = Character.objects(Q(fam_name__icontains = name) | Q(char_name__icontains = name), + server = ctx.message.server.id) rows = get_row(members, False) data = tabulate(rows, HEADERS, @@ -40,15 +40,15 @@ async def class_search(self, ctx, char_class=""): try: if char_class.lower() == "dk": - members = Member.objects(Q(char_class__iexact = char_class) - | Q(char_class__iexact = "dark") - | Q(char_class__iexact = "darkknight") - | Q(char_class__iexact = "dark knight")) + members = Character.objects(Q(char_class__iexact = char_class) + | Q(char_class__iexact = "dark") + | Q(char_class__iexact = "darkknight") + | Q(char_class__iexact = "dark knight")) elif char_class.lower() == "sorc": - members = Member.objects(Q(char_class__iexact = char_class) - | Q(char_class__iexact = "sorceress")) + members = Character.objects(Q(char_class__iexact = char_class) + | Q(char_class__iexact = "sorceress")) else: - members = Member.objects(char_class__iexact = char_class) + members = Character.objects(char_class__iexact = char_class) count = members(server = ctx.message.server.id).count() rows = get_row(members(server = ctx.message.server.id), False) diff --git a/cogs/update.py b/cogs/update.py index 7182052..7ecaca6 100644 --- a/cogs/update.py +++ b/cogs/update.py @@ -3,7 +3,7 @@ from tabulate import tabulate from datetime import datetime -from models.member import Member +from models.character import Character from models.historical import Historical from utils import * @@ -15,9 +15,9 @@ def __init__(self, bot): async def __get_member(self, author, fam_name, server_id): if not fam_name: - member = Member.objects(discord = author.id).first() + member = Character.objects(discord = author.id).first() else: - member = Member.objects(fam_name = fam_name, server = ctx.message.server.id).first() + member = Character.objects(fam_name = fam_name, server = ctx.message.server.id).first() roles = [u.name for u in author.roles] if ADMIN_USER not in roles: await self.bot.say("Only officers may perform this action") diff --git a/gsbot.py b/gsbot.py index 132da6e..12f2fdb 100644 --- a/gsbot.py +++ b/gsbot.py @@ -11,7 +11,7 @@ from discord.ext import commands from utils import * -from models.member import Member +from models.character import Character # Main connection function offered by mongoengine defaults are localhost:27017 connect(DB_NAME, diff --git a/models/character.py b/models/character.py new file mode 100644 index 0000000..7f2653a --- /dev/null +++ b/models/character.py @@ -0,0 +1,49 @@ +from mongoengine import * +from datetime import datetime +from configparser import ConfigParser +from utils import CHARACTER_COLLECTION +from .model_mixin import ModelMixin +from .historical import Historical + +class Character(Document, ModelMixin): + DB_COLUMNS = [ + 'rank', + 'fam_name', + 'char_name', + 'char_class', + 'server', + 'level', + 'ap', + 'dp', + 'gear_score', + 'updated', + 'progress', + 'gear_pic', + 'server', + 'primary', + 'hist_data' + ] + + rank = StringField(max_lenght=50) + fam_name = StringField(max_lenght=50) + char_name = StringField(max_lenght=50) + char_class = StringField(max_lenght=50) + server = StringField() + level = IntField(max_lenght=4) + ap = IntField(max_lenght=5) + dp = IntField(max_lenght=5) + gear_score = IntField(max_lenght=10) + updated = DateTimeField(default=datetime.now) + progress = FloatField(default=0.0) + gear_pic = URLField(default="https://i.imgur.com/UFViCXj.jpg") + server = IntField() + primary = BooleanField() + hist_data = ListField(ReferenceField(Historical)) + meta = { + 'collection' : CHARACTER_COLLECTION, + } + + @queryset_manager + def objects(doc_cls, queryset): + # default order is gear score descending + return queryset.order_by('-gear_score') \ No newline at end of file diff --git a/models/member.py b/models/member.py index 53d53f3..2c9d1fc 100644 --- a/models/member.py +++ b/models/member.py @@ -1,49 +1,19 @@ from mongoengine import * from datetime import datetime -from configparser import ConfigParser -from utils import COLLECTION +from utils import MEMBER_COLLECTION from .model_mixin import ModelMixin -from .historical import Historical +from .character import Character class Member(Document, ModelMixin): DB_COLUMNS = [ - 'rank', - 'fam_name', - 'char_name', - 'char_class', - 'discord', - 'server', - 'level', - 'ap', - 'dp', - 'gear_score', - 'updated', - 'progress', - 'gear_pic', - 'server', - 'hist_data' + 'characters', + 'discord', + 'servers', ] - rank = StringField(max_lenght=50) - fam_name = StringField(max_lenght=50) - char_name = StringField(max_lenght=50) - char_class = StringField(max_lenght=50) - discord = IntField() - server = StringField() - level = IntField(max_lenght=4) - ap = IntField(max_lenght=5) - dp = IntField(max_lenght=5) - gear_score = IntField(max_lenght=10) - updated = DateTimeField(default=datetime.now) - progress = FloatField(default=0.0) - gear_pic = URLField(default="https://i.imgur.com/UFViCXj.jpg") - server = IntField() - hist_data = ListField(ReferenceField(Historical)) + characters = ListField(ReferenceField(Character)) + discord = IntField + servers = ListField(IntField) meta = { - 'collection' : COLLECTION, + 'collection' : MEMBER_COLLECTION, } - - @queryset_manager - def objects(doc_cls, queryset): - # default order is gear score descending - return queryset.order_by('-gear_score') \ No newline at end of file diff --git a/models/server.py b/models/server.py new file mode 100644 index 0000000..63d846b --- /dev/null +++ b/models/server.py @@ -0,0 +1,17 @@ +from mongoengine import * +from datetime import datetime +from utils import MEMBER_COLLECTION +from .model_mixin import ModelMixin +from .member import Member + +class Server(Document, ModelMixin): + DB_COLUMNS = [ + 'id', + 'members', + ] + + id = IntField + members = ListField(ReferenceField(Member)) + meta = { + 'collection' : MEMBER_COLLECTION, + } diff --git a/utils.py b/utils.py index 295e710..cf35ee4 100644 --- a/utils.py +++ b/utils.py @@ -6,8 +6,10 @@ CONFIG = ConfigParser(allow_no_value=True) CONFIG.read('config.ini') -COLLECTION = CONFIG.get('db', 'collection') -HIST_COLLECTION = CONFIG.get('db', 'historical') +CHARACTER_COLLECTION = CONFIG.get('db', 'character_collection') +SERVER_COLLECTION = CONFIG.get('db', 'server_collection') +MEMBER_COLLECTION = CONFIG.get('db', 'member_collection') +HIST_COLLECTION = CONFIG.get('db', 'historical_collection') DB_NAME = CONFIG.get('db', 'name') DB_HOST = CONFIG.get('db', 'host') DB_USER = CONFIG.get('auth', 'user') From 9b35489af913aa0a9e5bc299097ba04612951f53 Mon Sep 17 00:00:00 2001 From: Pachev Joseph Date: Tue, 2 Jan 2018 19:27:17 -0800 Subject: [PATCH 2/4] Adds Add and Reroll command with new structure --- cogs/add.py | 99 +++++++++++++++++++++------------------------ models/character.py | 7 ++-- models/member.py | 4 +- utils.py | 29 +++++++++++++ 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/cogs/add.py b/cogs/add.py index 8116016..a2de08d 100644 --- a/cogs/add.py +++ b/cogs/add.py @@ -4,7 +4,9 @@ from datetime import datetime from models.character import Character +from models.member import Member from models.historical import Historical +from models.server import Server from utils import * class Add: @@ -16,11 +18,8 @@ def __init__(self, bot): async def __get_rank_and_discord_id(self, author, user, roles): if not user: discord_id = author.id + discord_username = author.name rank = 'Officer' if ADMIN_USER in roles else 'Member' - if Character.objects(discord = author.id).count() >= 1: - await self.bot.say(codify("Cannot add more than one character to this discord id. " - "Try rerolling with gsbot reroll")) - return (None, None) else: try: user_roles = [u.name for u in user.roles] @@ -29,11 +28,12 @@ async def __get_rank_and_discord_id(self, author, user, roles): rank = 'Member' print(e) discord_id = user.id + discord_username = user.name if ADMIN_USER not in roles: await self.bot.say(codify("Only officers may perform this action")) return (None, None) - return (rank, discord_id) + return rank, discord_id, discord_username @commands.command(pass_context=True) async def add(self, @@ -45,63 +45,51 @@ async def add(self, dp: int, char_class, user: discord.User = None): - """Adds yourself as a member to the database. This member is linked with your + """Adds your primary character to the guild. This character is linked with your discord id and can only be updated by either that member or an officer. **Officers can add a user by tagging them at the end. eg @drawven** Note: Total gear score and rank is auto calculated.""" + # Checks character name to make sure it is correct try: - # if char_class is shorthand for a class name (EX. DK = DARKKNIGHT) then set it to the real name - char_class = CHARACTER_CLASS_SHORT.get(char_class.upper()) if CHARACTER_CLASS_SHORT.get(char_class.upper()) else char_class - - # check for invalid class names - if char_class.upper() not in CHARACTER_CLASSES: - # find possible class names that user was trying to match - possible_classes = list(filter( - lambda class_name: char_class.upper() in class_name, - CHARACTER_CLASSES, - )) - if len(possible_classes) > 1: - await self.bot.say(codify("Character class not recognized.\n" - "Did you mean {}?".format(", ".join( - possible_classes[:-1]) + " or " + possible_classes[-1]) - )) - elif len(possible_classes) == 1: - await self.bot.say(codify("Character class not recognized.\n" - "Did you mean {}?".format(possible_classes[0]) - )) - else: - await self.bot.say( - codify("Character class not recognized, here is a list " - "of recognized classes\n " - + "\n ".join(CHARACTER_CLASSES))) - return + if not await check_character_name(self.bot, char_class): + return author = ctx.message.author + server = ctx.message.server.id roles = [u.name for u in author.roles] - rank, discord_id = await self.__get_rank_and_discord_id(author, user, roles) - + rank, discord_id, discord_username = await self.__get_rank_and_discord_id(author, user, roles) if rank is None or discord_id is None: return - member = Character.create({ + member = Member.objects(discord = discord_id).first() + character = Character.objects().first() + isPrimary = False if character else True + if not member: + member = Member.create({'discord': discord_id, 'servers': [server]}) + isPrimary = True + + character = Character.create({ + 'rank': rank, 'fam_name': fam_name, - 'char_name': char_name, + 'char_name': char_name.upper, + 'char_class': char_class.upper(), + 'server': server, 'level': level, 'ap': ap, 'dp': dp, - 'char_class': char_class, 'gear_score': ap + dp, - 'rank': rank, - 'discord': discord_id, - 'server': ctx.message.server.id + 'primary': isPrimary, + 'member': author.id, }) + member.characters.append(character) - row = get_row([member], False) + row = get_row([character], False) data = tabulate(row, HEADERS, 'simple') - await self.bot.say(codify("Success Adding User\n\n" + data)) + await self.bot.say(codify("Success Adding Character for member {}\n\n". + format(discord_username.upper()) + data)) except Exception as e: print(e) @@ -112,40 +100,43 @@ async def reroll(self, ctx, new_char_name, level: int, ap : int, dp: int, new_ch """Just for someone special: Allows you to reroll """ author = ctx.message.author.id - member = Character.objects(discord = author).first() + character = Character.objects(member = author, primary=True).first() date = datetime.now() - if not member: - await self.bot.say("Can't reroll if you're not in the database :(, try adding yoursell first") + if not character: + await self.bot.say("Can't reroll if you're not in the database :(, try adding a character first") + return + + if not await check_character_name(self.bot, new_char_class): return else: try: - ## Adds historical data to todabase + ## Adds historical data to databse update = Historical.create({ 'type': "reroll", - 'char_class': member.char_class, + 'char_class': character.char_class, 'timestamp': date, - 'level': member.level + (round(member.progress, 2) * .01), - 'ap': member.ap, - 'dp': member.dp, - 'gear_score': member.gear_score + 'level':float(str(character.level) + '.' + str(round(character.progress))) , + 'ap': character.ap, + 'dp': character.dp, + 'gear_score': character.gear_score }) - historical_data = member.hist_data + historical_data = character.hist_data historical_data.append(update) - member.update_attributes({ + character.update_attributes({ 'char_name': new_char_name, 'ap': ap, 'dp': dp, 'level': level, 'gear_score': ap + dp, - 'char_class': new_char_class, + 'char_class': new_char_class.upper(), 'updated': date, 'hist_data': historical_data }) - row = get_row([member], False) + row = get_row([character], False) data = tabulate(row, HEADERS, 'simple') await self.bot.say(codify("Success Rerolling\n\n" + data)) diff --git a/models/character.py b/models/character.py index 7f2653a..6082366 100644 --- a/models/character.py +++ b/models/character.py @@ -7,8 +7,8 @@ class Character(Document, ModelMixin): DB_COLUMNS = [ - 'rank', - 'fam_name', + 'rank', + 'fam_name', 'char_name', 'char_class', 'server', @@ -19,8 +19,8 @@ class Character(Document, ModelMixin): 'updated', 'progress', 'gear_pic', - 'server', 'primary', + 'member', 'hist_data' ] @@ -38,6 +38,7 @@ class Character(Document, ModelMixin): gear_pic = URLField(default="https://i.imgur.com/UFViCXj.jpg") server = IntField() primary = BooleanField() + member = IntField() hist_data = ListField(ReferenceField(Historical)) meta = { 'collection' : CHARACTER_COLLECTION, diff --git a/models/member.py b/models/member.py index 2c9d1fc..e436034 100644 --- a/models/member.py +++ b/models/member.py @@ -12,8 +12,8 @@ class Member(Document, ModelMixin): ] characters = ListField(ReferenceField(Character)) - discord = IntField - servers = ListField(IntField) + discord = IntField(primary_key=True) + servers = ListField(IntField()) meta = { 'collection' : MEMBER_COLLECTION, } diff --git a/utils.py b/utils.py index cf35ee4..94b351e 100644 --- a/utils.py +++ b/utils.py @@ -82,3 +82,32 @@ def paginate(data): for i in data.splitlines(): paginator.add_line(i) return paginator.pages + +async def check_character_name(bot, char_class): + # if char_class is shorthand for a class name (EX. DK = DARKKNIGHT) then set it to the real name + char_class = CHARACTER_CLASS_SHORT.get(char_class.upper()) if CHARACTER_CLASS_SHORT.get(char_class.upper()) else char_class + + # check for invalid class names + if char_class.upper() not in CHARACTER_CLASSES: + # find possible class names that user was trying to match + possible_classes = list(filter( + lambda class_name: char_class.upper() in class_name, + CHARACTER_CLASSES, + )) + if len(possible_classes) > 1: + await bot.say(codify("Character class not recognized.\n" + "Did you mean {}?".format(", ".join( + possible_classes[:-1]) + " or " + possible_classes[-1]) + )) + elif len(possible_classes) == 1: + await bot.say(codify("Character class not recognized.\n" + "Did you mean {}?".format(possible_classes[0]) + )) + else: + await bot.say( + codify("Character class not recognized, here is a list " + "of recognized classes\n " + + "\n ".join(CHARACTER_CLASSES))) + return False + + return True From 2165f51ec0a29da9ba1d7825f721f20cb0724e8d Mon Sep 17 00:00:00 2001 From: Pachev Joseph Date: Wed, 3 Jan 2018 17:43:48 -0800 Subject: [PATCH 3/4] Updates remaining server and adds two experimental commands --- cogs/add.py | 52 ++++++++++++++++++++++++++++++--------------- cogs/delete.py | 6 +++--- cogs/extras.py | 49 +++++++++++++++++++++++++++++++++++++++--- cogs/general.py | 2 +- cogs/listings.py | 18 ++++++++-------- cogs/search.py | 12 +++++------ cogs/update.py | 29 ++++++++++++------------- models/character.py | 7 +++++- models/member.py | 2 +- models/server.py | 7 +++--- 10 files changed, 124 insertions(+), 60 deletions(-) diff --git a/cogs/add.py b/cogs/add.py index a2de08d..e6ebce2 100644 --- a/cogs/add.py +++ b/cogs/add.py @@ -33,7 +33,26 @@ async def __get_rank_and_discord_id(self, author, user, roles): await self.bot.say(codify("Only officers may perform this action")) return (None, None) - return rank, discord_id, discord_username + return (rank, discord_id, discord_username) + + def __get_server_and_member(self, server_id, discord_id): + member = Member.objects(discord = discord_id).first() + server = Server.objects(id=server_id).first() + + if not server: + server = Server.create({'id': server_id}) + if not member: + member = Member.create({'discord': discord_id}) + + # Checks if member being added is in the server + server_member = Member.objects(servers=server_id, discord=discord_id).first() + if not server_member: + server.members.append(member) + server.save() + member.servers.append(server_id) + member.save() + + return (server, member) @commands.command(pass_context=True) async def add(self, @@ -56,34 +75,33 @@ async def add(self, if not await check_character_name(self.bot, char_class): return author = ctx.message.author - server = ctx.message.server.id + server_id= ctx.message.server.id roles = [u.name for u in author.roles] - rank, discord_id, discord_username = await self.__get_rank_and_discord_id(author, user, roles) + server, member = self.__get_server_and_member(server_id, discord_id) + if rank is None or discord_id is None: return - member = Member.objects(discord = discord_id).first() - character = Character.objects().first() + character = Character.primary_chars(member=discord_id).first() isPrimary = False if character else True - if not member: - member = Member.create({'discord': discord_id, 'servers': [server]}) - isPrimary = True + character = Character.create({ 'rank': rank, - 'fam_name': fam_name, - 'char_name': char_name.upper, + 'fam_name': fam_name.upper(), + 'char_name': char_name.upper(), 'char_class': char_class.upper(), - 'server': server, + 'server': server_id, 'level': level, 'ap': ap, 'dp': dp, 'gear_score': ap + dp, 'primary': isPrimary, - 'member': author.id, + 'member': discord_id, }) member.characters.append(character) + member.save() row = get_row([character], False) data = tabulate(row, HEADERS, 'simple') @@ -97,10 +115,10 @@ async def add(self, @commands.command(pass_context=True) async def reroll(self, ctx, new_char_name, level: int, ap : int, dp: int, new_char_class): - """Just for someone special: Allows you to reroll """ + """Just for someone special: Allows you to reroll your main character """ author = ctx.message.author.id - character = Character.objects(member = author, primary=True).first() + character = Character.primary_chars(member = author).first() date = datetime.now() if not character: await self.bot.say("Can't reroll if you're not in the database :(, try adding a character first") @@ -111,10 +129,10 @@ async def reroll(self, ctx, new_char_name, level: int, ap : int, dp: int, new_ch else: try: - ## Adds historical data to databse + ## Adds historical data to database update = Historical.create({ 'type': "reroll", - 'char_class': character.char_class, + 'char_class': character.char_class.upper(), 'timestamp': date, 'level':float(str(character.level) + '.' + str(round(character.progress))) , 'ap': character.ap, @@ -126,7 +144,7 @@ async def reroll(self, ctx, new_char_name, level: int, ap : int, dp: int, new_ch historical_data.append(update) character.update_attributes({ - 'char_name': new_char_name, + 'char_name': new_char_name.upper(), 'ap': ap, 'dp': dp, 'level': level, diff --git a/cogs/delete.py b/cogs/delete.py index edec435..6baf68f 100644 --- a/cogs/delete.py +++ b/cogs/delete.py @@ -14,15 +14,15 @@ def __init__(self, bot): @commands.command(pass_context=True) async def delete(self, ctx, fam_name=''): - """Deletes character from list. **officers can add an optional family name at the + """Deletes users's main character from list. **officers can add an optional family name at the end to delete a certain user""" try: author = ctx.message.author if not fam_name: - member = Character.objects(discord = author.id).first() + member = Character.primary_chars(discord = author.id).first() else: - member = Character.objects(fam_name = fam_name, server = ctx.message.server.id).first() + member = Character.primary_chars(fam_name = fam_name, server = ctx.message.server.id).first() roles = [u.name for u in author.roles] if ADMIN_USER not in roles: await self.bot.say("Only officers may perform this action") diff --git a/cogs/extras.py b/cogs/extras.py index f6d3776..9227878 100644 --- a/cogs/extras.py +++ b/cogs/extras.py @@ -21,14 +21,57 @@ async def attach_pic(self, ctx, url): try: author = ctx.message.author - member = Character.objects(discord = author.id).first() - member.gear_pic = url - member.save() + character = Character.primary_chars(member = author.id).first() + character.gear_pic = url + character.save() await self.bot.say(codify("Picture added successfully")) except Exception as e: print(e) await self.bot.say("Picture could not be added") + @commands.command(pass_context=True) + async def my_list(self,ctx): + """***Experimental***List all the characters that you have added to the database for this server""" + try: + print('server,', ctx.message.server.id) + members = Character.objects(member=ctx.message.author.id, server = ctx.message.server.id) + rows = get_row(members, False) + + data = tabulate(rows, + HEADERS, + 'simple',) + + for page in paginate(data): + await self.bot.say(page) + except Exception as e: + await self.bot.say("Something went horribly wrong") + print(e) + + @commands.command(pass_context=True) + async def set_main(self,ctx,num:int=0): + """***Experimental*** Changes primary character on server""" + if not int(num): + await self.bot.say(codify('Invalid Selection')) + return + try: + print('server,', ctx.message.server.id) + characters = Character.objects(member=ctx.message.author.id, server = ctx.message.server.id) + if num < 1 or num > len(characters): + await self.bot.say(codify('Invalid Selection')) + return + + num -= 1 + for char in characters: + char.primary = False + char.save() + main = characters[num] + main.primary = True + main.save() + await self.bot.say(codify('Main Character Switched Succesfuly to {}'.format(main.char_name))) + except Exception as e: + await self.bot.say("Something went horribly wrong") + print(e) + def setup(bot): bot.add_cog(Extras(bot)) diff --git a/cogs/general.py b/cogs/general.py index ec64c6a..d7326aa 100644 --- a/cogs/general.py +++ b/cogs/general.py @@ -20,7 +20,7 @@ async def info(self, ctx): try: info = [] - members = Character.objects(server=ctx.message.server.id) + members = Character.primary_chars(server=ctx.message.server.id) if members: officers = members(rank='Officer') average = members.average('gear_score') diff --git a/cogs/listings.py b/cogs/listings.py index 6ae2f19..33b3158 100644 --- a/cogs/listings.py +++ b/cogs/listings.py @@ -13,12 +13,12 @@ def __init__(self, bot): @commands.command(pass_context=True) async def list(self,ctx,num=100): - """List all the members and their gear score with optional limit. + """List all the main characters and their gear score with optional limit. Example. gsbot list returns first 100 by default and gsbot list 5 first 5 sorted by gear score""" try: print('server,', ctx.message.server.id) - members = Character.objects(server=ctx.message.server.id) + members = Character.primary_chars(server=ctx.message.server.id) print(Character.objects().first().server) rows = get_row(members, True, num) @@ -34,9 +34,9 @@ async def list(self,ctx,num=100): @commands.command(pass_context=True) async def over(self, ctx, num=400): - """List all the members over a certain gear score""" + """List all the main characters over a certain gear score""" try: - members = Character.objects(gear_score__gte = num, server = ctx.message.server.id) + members = Character.primary_chars(gear_score__gte = num, server = ctx.message.server.id) rows = get_row(members,False) data = tabulate(rows, @@ -52,9 +52,9 @@ async def over(self, ctx, num=400): @commands.command(pass_context=True) async def under(self, ctx, num=400): - """List all the members under a certain gear score""" + """List all the main characters under a certain gear score""" try: - members = Character.objects(gear_score__lte = num, server = ctx.message.server.id) + members = Character.primary_chars(gear_score__lte = num, server = ctx.message.server.id) rows = get_row(members, False) data = tabulate(rows, HEADERS, @@ -77,7 +77,7 @@ async def sort_by(self, ctx): async def lvl(self, ctx, num=100): """ - Sorts list by level and progress with optional limiter""" try: - members = Character.objects(server = ctx.message.server.id).order_by('-level', '-progress') + members = Character.primary_chars(server = ctx.message.server.id).order_by('-level', '-progress') rows = get_row(members, True, num) data = tabulate(rows, @@ -94,7 +94,7 @@ async def lvl(self, ctx, num=100): async def ap(self, ctx, num=100): """ - Sorts list by AP with optional limit""" try: - members = Character.objects(server=ctx.message.server.id).order_by('-ap') + members = Character.primary_chars(server=ctx.message.server.id).order_by('-ap') rows = get_row(members, True, num) data = tabulate(rows, @@ -111,7 +111,7 @@ async def ap(self, ctx, num=100): async def dp(self, ctx, num=100): """ - Sorts list by DP with optional limit""" try: - members = Character.objects(server=ctx.message.server.id).order_by('-dp') + members = Character.primary_chars(server=ctx.message.server.id).order_by('-dp') rows = get_row(members, True, num) data = tabulate(rows, diff --git a/cogs/search.py b/cogs/search.py index 51eb497..3e982ec 100644 --- a/cogs/search.py +++ b/cogs/search.py @@ -15,9 +15,9 @@ def __init__(self, bot): @commands.command(pass_context=True) async def lookup(self, ctx, name=""): - """Looks up a guild member by family name or character name""" + """Looks up main characters by family name or character name""" try: - members = Character.objects(Q(fam_name__icontains = name) | Q(char_name__icontains = name), + members = Character.primary_chars(Q(fam_name__icontains = name) | Q(char_name__icontains = name), server = ctx.message.server.id) rows = get_row(members, False) data = tabulate(rows, @@ -36,19 +36,19 @@ async def lookup(self, ctx, name=""): @commands.command(pass_context=True) async def class_search(self, ctx, char_class=""): - """Looks up guild members by class""" + """Looks up main characters by class""" try: if char_class.lower() == "dk": - members = Character.objects(Q(char_class__iexact = char_class) + members = Character.primary_chars(Q(char_class__iexact = char_class) | Q(char_class__iexact = "dark") | Q(char_class__iexact = "darkknight") | Q(char_class__iexact = "dark knight")) elif char_class.lower() == "sorc": - members = Character.objects(Q(char_class__iexact = char_class) + members = Character.primary_chars(Q(char_class__iexact = char_class) | Q(char_class__iexact = "sorceress")) else: - members = Character.objects(char_class__iexact = char_class) + members = Character.primary_chars(char_class__iexact = char_class) count = members(server = ctx.message.server.id).count() rows = get_row(members(server = ctx.message.server.id), False) diff --git a/cogs/update.py b/cogs/update.py index 7ecaca6..e1cb65d 100644 --- a/cogs/update.py +++ b/cogs/update.py @@ -15,45 +15,44 @@ def __init__(self, bot): async def __get_member(self, author, fam_name, server_id): if not fam_name: - member = Character.objects(discord = author.id).first() + character = Character.primary_chars(member = author.id).first() else: - member = Character.objects(fam_name = fam_name, server = ctx.message.server.id).first() + character = Character.primary_chars(fam_name = fam_name, server = server_id).first() roles = [u.name for u in author.roles] if ADMIN_USER not in roles: await self.bot.say("Only officers may perform this action") return - return member + return character @commands.command(pass_context=True) async def update(self, ctx, level: int, ap: int, dp: int, level_percent: float, fam_name=''): - """Updates a user's gear score. Each user is linked to a gear score in the database - and can only update their scores. **Officers can add an additional family name at + """Updates user's main character's gear score. **Officers can add an additional family name at the end of this command to update another user""" date = datetime.now() try: author = ctx.message.author - member = await self.__get_member(author, fam_name, ctx.message.server.id) - if member is None: + character = await self.__get_member(author, fam_name, ctx.message.server.id) + if character is None: return # Adds historical data to database update = Historical.create({ 'type': "update", - 'char_class': member.char_class, + 'char_class':character.char_class.upper(), 'timestamp': date, - 'level': member.level + (round(member.progress, 2) * .01), - 'ap': member.ap, - 'dp': member.dp, - 'gear_score': member.gear_score + 'level': float(str(character.level) + '.' + str(round(character.progress))) , + 'ap': character.ap, + 'dp': character.dp, + 'gear_score': character.gear_score }) - historical_data = member.hist_data + historical_data = character.hist_data historical_data.append(update) - member.update_attributes({ + character.update_attributes({ 'ap': ap, 'dp': dp, 'level': level, @@ -63,7 +62,7 @@ async def update(self, ctx, level: int, ap: int, dp: int, level_percent: float, 'hist_data': historical_data }) - row = get_row([member], False) + row = get_row([character], False) data = tabulate(row, HEADERS, 'simple') await self.bot.say(codify(data)) diff --git a/models/character.py b/models/character.py index 6082366..5ff39ab 100644 --- a/models/character.py +++ b/models/character.py @@ -47,4 +47,9 @@ class Character(Document, ModelMixin): @queryset_manager def objects(doc_cls, queryset): # default order is gear score descending - return queryset.order_by('-gear_score') \ No newline at end of file + return queryset.order_by('-gear_score') + + @queryset_manager + def primary_chars(doc_cls, queryset): + # default order is gear score descending + return queryset.filter(primary=True) diff --git a/models/member.py b/models/member.py index e436034..64f96b1 100644 --- a/models/member.py +++ b/models/member.py @@ -11,8 +11,8 @@ class Member(Document, ModelMixin): 'servers', ] + discord = IntField() characters = ListField(ReferenceField(Character)) - discord = IntField(primary_key=True) servers = ListField(IntField()) meta = { 'collection' : MEMBER_COLLECTION, diff --git a/models/server.py b/models/server.py index 63d846b..9d87df9 100644 --- a/models/server.py +++ b/models/server.py @@ -1,6 +1,5 @@ from mongoengine import * -from datetime import datetime -from utils import MEMBER_COLLECTION +from utils import SERVER_COLLECTION from .model_mixin import ModelMixin from .member import Member @@ -10,8 +9,8 @@ class Server(Document, ModelMixin): 'members', ] - id = IntField + id = IntField(primary_key=True) members = ListField(ReferenceField(Member)) meta = { - 'collection' : MEMBER_COLLECTION, + 'collection' : SERVER_COLLECTION, } From 1dc9dd13996857241dc96d39913dd521c0037eda Mon Sep 17 00:00:00 2001 From: Pachev Joseph Date: Sat, 6 Jan 2018 10:49:06 -0800 Subject: [PATCH 4/4] Adds name and avatar to member and server models --- cogs/add.py | 49 +++++++++++++++++++++++++++--------------------- models/member.py | 4 ++++ models/server.py | 4 ++++ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/cogs/add.py b/cogs/add.py index e6ebce2..e3cc992 100644 --- a/cogs/add.py +++ b/cogs/add.py @@ -15,10 +15,9 @@ class Add: def __init__(self, bot): self.bot = bot - async def __get_rank_and_discord_id(self, author, user, roles): + async def __get_rank_and_member(self, author, user, roles): if not user: - discord_id = author.id - discord_username = author.name + discord_user = author rank = 'Officer' if ADMIN_USER in roles else 'Member' else: try: @@ -27,29 +26,37 @@ async def __get_rank_and_discord_id(self, author, user, roles): except Exception as e: rank = 'Member' print(e) - discord_id = user.id - discord_username = user.name + discord_user = user if ADMIN_USER not in roles: await self.bot.say(codify("Only officers may perform this action")) return (None, None) - return (rank, discord_id, discord_username) + return (rank, discord_user) - def __get_server_and_member(self, server_id, discord_id): - member = Member.objects(discord = discord_id).first() - server = Server.objects(id=server_id).first() + def __get_server_and_member(self, discord_server, discord_user): + member = Member.objects(discord=discord_user.id).first() + server = Server.objects(id=discord_server.id).first() if not server: - server = Server.create({'id': server_id}) + server = Server.create({ + 'id': discord_server.id, + 'name': discord_server.name, + 'avatar': discord_server.avatar + }) + if not member: - member = Member.create({'discord': discord_id}) + member = Member.create({ + 'discord': discord_user.id, + 'name': discord_user.name, + 'avatar': discord_user.avatar + }) # Checks if member being added is in the server - server_member = Member.objects(servers=server_id, discord=discord_id).first() + server_member = Member.objects(servers=discord_server.id, discord=discord_user.id).first() if not server_member: server.members.append(member) server.save() - member.servers.append(server_id) + member.servers.append(discord_server.id) member.save() return (server, member) @@ -75,15 +82,15 @@ async def add(self, if not await check_character_name(self.bot, char_class): return author = ctx.message.author - server_id= ctx.message.server.id + server = ctx.message.server roles = [u.name for u in author.roles] - rank, discord_id, discord_username = await self.__get_rank_and_discord_id(author, user, roles) - server, member = self.__get_server_and_member(server_id, discord_id) + rank, discord_user = await self.__get_rank_and_discord_id(author, user, roles) + member = self.__get_server_and_member(server, discord_user) - if rank is None or discord_id is None: + if rank is None or discord_user.id is None: return - character = Character.primary_chars(member=discord_id).first() + character = Character.primary_chars(member=discord_user.id).first() isPrimary = False if character else True @@ -92,13 +99,13 @@ async def add(self, 'fam_name': fam_name.upper(), 'char_name': char_name.upper(), 'char_class': char_class.upper(), - 'server': server_id, + 'server': server.id, 'level': level, 'ap': ap, 'dp': dp, 'gear_score': ap + dp, 'primary': isPrimary, - 'member': discord_id, + 'member': discord_user.id, }) member.characters.append(character) member.save() @@ -107,7 +114,7 @@ async def add(self, data = tabulate(row, HEADERS, 'simple') await self.bot.say(codify("Success Adding Character for member {}\n\n". - format(discord_username.upper()) + data)) + format(discord_user.name.upper()) + data)) except Exception as e: print(e) diff --git a/models/member.py b/models/member.py index 64f96b1..c4d96cf 100644 --- a/models/member.py +++ b/models/member.py @@ -9,11 +9,15 @@ class Member(Document, ModelMixin): 'characters', 'discord', 'servers', + 'name', + 'avatar', ] discord = IntField() characters = ListField(ReferenceField(Character)) servers = ListField(IntField()) + name = StringField() + avatar = StringField() meta = { 'collection' : MEMBER_COLLECTION, } diff --git a/models/server.py b/models/server.py index 9d87df9..16a6ab4 100644 --- a/models/server.py +++ b/models/server.py @@ -7,10 +7,14 @@ class Server(Document, ModelMixin): DB_COLUMNS = [ 'id', 'members', + 'name', + 'avatar', ] id = IntField(primary_key=True) members = ListField(ReferenceField(Member)) + name = StringField() + avatar = StringField() meta = { 'collection' : SERVER_COLLECTION, }