Beispiel #1
0
    def __init__(self, participant_id_list: list, game: Game):
        # Initial list of participants
        self.__unselected_participants = participant_id_list
        # Game being played
        self.__game = game
        # Amount of games to be played
        self.__game_type = "bo3"

        # Get the list of maps for the game being played.
        self.__unselected_maps = [
            m.lower() for m in Config.get_config_property(
                "tenman", "maps", game.name.lower())
        ]
        self.__map_pick_ban_sequence = [
            MapPickBanEntry(s) for s in Config.get_config_property(
                "tenman", "mapPickBanSequence", game.name.lower(),
                self.__game_type).split("-")
        ]

        self.__teams_manager = None

        # List of maps to pay
        self.__picked_maps = []
        # Order captains pick players
        self.__player_pick_sequence = [
            TeamStatus.get(s) for s in Config.get_config_property(
                "tenman", "playerPickSequence").split("-")
        ]
        # Flag set when waiting for other team to pick side
        self.__wait_for_side_pick = False
        # Team that picks the side
        self.__side_pick_team = None
    async def free(self, ctx: commands.context.Context):
        """
        Removes roles from all participating players

        SYNOPSIS
            .tm_free
        """
        captain_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "captainRole"), ctx.guild.roles)
        captain_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "captainRole"), ctx.guild.roles)
        player_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "playerRole"), ctx.guild.roles)
        player_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "playerRole"), ctx.guild.roles)

        await ctx.channel.send(content="Beginning deconstruction.")
        teams = self.__ongoing.get_teams()

        for a, b in zip(teams[0].get_players(), teams[1].get_players()):
            await find(lambda u: u.id == a,
                       ctx.guild.members).remove_roles(captain_a_role,
                                                       player_a_role)
            await find(lambda u: u.id == b,
                       ctx.guild.members).remove_roles(captain_b_role,
                                                       player_b_role)
        await ctx.channel.send(content="Players freed.")

        self.__ongoing = None
Beispiel #3
0
def main():
    cogs = [
        "cogs.{0}cog".format(m) for m in Config.get_config_property("modules")
    ]

    bot = Goldbot(command_prefix=Config.get_config_property("prefix"))

    for cog in cogs:
        bot.load_extension(cog)

    bot.run(Config.get_config_property("discordApiKey"),
            bot=True,
            reconnect=True)
    async def make_role_subscribable(self, ctx):
        if len(ctx.message.role_mentions) < 1:
            raise commands.BadArgument(message="You are missing required arguments for this command:\n`role "
                                               "(@mention)`")
        if ctx.message.role_mentions[0].name in Config.get_config_property("server", "optionalRoles"):
            raise commands.BadArgument(message="Role is already a subscribable role.")

        role_list = Config.get_config_property("server", "optionalRoles")
        role_list.append(ctx.message.role_mentions[0].name)
        Config.update_config_property_and_write("server/optionalRoles", role_list)

        message = "{0} is now a subscribable role!\nSubscribe to the role using `{1}subscribe @{0}`" \
                   .format(ctx.message.role_mentions[0].name, Config.get_config_property("prefix"))
        await ctx.channel.send(content=message)
    async def get_leaderboard(self, ctx, *args):
        try:
            parsed_args = ServerArgParsers.LEADERBOARD_ARG_PARSER.parse_known_args(args)[0]
        except ArgumentParserError as e:
            raise commands.ArgumentParsingError(message=e.args[0])

        if parsed_args.mobile:
            headers = ["N", "S", "CS", "LS"]
        else:
            headers = ["Name", "Score", "Current Streak", "Longest Streak"]

        emoji = find(lambda em: str(em) == parsed_args.emoji, ctx.guild.emojis)

        try:
            if emoji.name not in Config.get_config_property("server", "leaderboard", "emojiMap").keys():
                raise commands.BadArgument("There is no leaderboard associated with the emoji.")
            relative_path = "{0}/leaderboards/{1}/{2}.json".format(Config.get_config_property("saveDir"),
                                                                   str(ctx.guild.id), emoji.name)
            with open(str(get_project_dir() / relative_path)) as f:
                leaderboard_json = json.load(f)

            entries = sorted(leaderboard_json, key=lambda e: (leaderboard_json[e]["score"],
                             leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]),
                             reverse=True)

        except AttributeError as e:
            LOGGER.error("ServerCog::leaderboard - Called with default emoji.")
            raise commands.BadArgument("Leaderboards don't exist for default emojis.")
        except FileNotFoundError as e:
            LOGGER.error("ServerCog::leaderboard - No leaderboard data found for called emoji")
            raise commands.BadArgument("No leaderboard data found for called emoji.")

        try:
            entries = entries[0:int(parsed_args.top)]
        except TypeError:
            pass
        except IndexError:
            LOGGER.warning("Specified a value that was larger than the amount of users with scores")
            pass
        except ValueError:
            LOGGER.error("ServerCog::leaderboard - " + parsed_args.top + " is not an int")
            raise commands.BadArgument("Bad argument for top parameter. Expected integer.")

        table = [[find(lambda u: str(u.id) == e, ctx.guild.members).name, leaderboard_json[e]["score"],
                  leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]] for e in entries]

        await ctx.channel.send("{0}*** Leaderboard ***{0}\n```{1}```".format(str(emoji), tabulate(table,
                                                                                                  headers=headers)))
 async def __move_user_to_proper_voice(ctx: commands.context.Context,
                                       user: discord.Member,
                                       status: TeamStatus):
     voice = find(
         lambda v: v.name == Config.get_config_property(
             "tenman", "team{0}".format(status.name), "voice"),
         ctx.guild.voice_channels)
     await user.move_to(voice)
Beispiel #7
0
    async def __leaderboard_job(self):
        tz = pytz.timezone(Config.get_config_property("server", "timezone"))
        await self.wait_until_ready()
        # List of timers as specified in the config
        timers = [(datetime.strptime(entry, "%H:%M")).time()
                  for entry in Config.get_config_property(
                      "server", "leaderboard", "emojiMap").values()]
        # Add the military time equivalents to the list
        timers.extend([
            timer.replace(hour=timer.hour + 12) for timer in timers
            if timer.hour != 12
        ])
        timers.sort()
        # This part only runs once, I want to find the time it started up so I can find the next available time to
        # schedule the job
        startup_time = tz.localize(datetime.now())
        # shift to the next closest time in the list
        i = 0
        while timers[0] < startup_time.time() and i < len(timers):
            t = timers[0]
            timers.remove(t)
            timers.append(t)
            i = i + 1
        # Make the timers list cycle infinitely
        timers = cycle(timers)

        while not self.is_closed():
            # At startup or after the job is done sleeping, get the current time so we can calculate how many seconds we
            # need to wait until the next job
            current_time = tz.localize(datetime.now())
            # Get the next available time in the timer list
            next_timer = next(timers)
            timer = current_time.replace(hour=next_timer.hour,
                                         minute=next_timer.minute + 2,
                                         second=0)
            if timer.time() < current_time.time():
                timer = timer + timedelta(days=1)
            LOGGER.info(
                "LeaderboardHandler scheduled to process more entries on " +
                timer.strftime("%d-%b-%Y (%H:%M)"))
            # Wait until the next time and then run the job
            delay = (timer - current_time).total_seconds()
            await asyncio.sleep(delay)
            LeaderboardHandler.get_leaderboard_handler().process_entries()
Beispiel #8
0
    def __process_score_reset(self):
        base_path = Config.get_config_property("saveDir") + "/leaderboards/307026836066533377/"
        global_path = base_path + "global.json"
        global_leaderboard = read_json_safe(global_path)
        aggregate_scores_dict = {}
        yesterday = datetime.now() - timedelta(days=1)
        emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap")

        try:
            os.makedirs(base_path + "old/" + str(yesterday.month) + "-" + str(yesterday.year))
        except OSError:
            pass

        for emoji in emoji_time_dict.keys():
            leaderboard_path = base_path + emoji + ".json"
            try:
                leaderboard_json = read_json_safe(leaderboard_path)
            except FileNotFoundError:
                continue

            score_sorted = sorted(leaderboard_json, key=lambda e: (leaderboard_json[e]["score"],
                                  leaderboard_json[e]["current_streak"], leaderboard_json[e]["longest_streak"]),
                                  reverse=True)
            for i, k in zip(range(len(score_sorted), 0, -1), score_sorted):
                try:
                    user_global_score = aggregate_scores_dict[k]
                except KeyError:
                    user_global_score = 0
                aggregate_scores_dict[k] = user_global_score + i

            shutil.move(leaderboard_path, base_path + "old/" + str(yesterday.month) + "-" + str(yesterday.year) + "/" +
                        emoji + ".json")

        for k in aggregate_scores_dict.keys():
            try:
                user_score = global_leaderboard[k]
            except KeyError:
                user_score = 0

            user_score = user_score + (aggregate_scores_dict[k] * 10)
            global_leaderboard[k] = user_score

        with open(global_path, "w") as f:
            json.dump(global_leaderboard, f, indent=4)
Beispiel #9
0
 def add_entry(self, user_id, timestamp, emote):
     emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap")
     for entry in self.__unprocessed_entries:
         if entry["user_id"] == user_id and entry["emote"] == emote:
             return
     if emote in emoji_time_dict.keys():
         fixed_timestamp = timestamp.time().replace(second=0, microsecond=0)
         r_time = datetime.strptime(emoji_time_dict[emote], "%H:%M").time()
         m_time = r_time.replace(hour=r_time.hour + 12)
         if fixed_timestamp == r_time or fixed_timestamp == m_time or fixed_timestamp == \
                 r_time.replace(minute=r_time.minute + 1) or fixed_timestamp == m_time.replace(minute=m_time.minute + 1):
             self.__unprocessed_entries.append({"user_id": user_id, "timestamp": timestamp, "emote": emote})
             LOGGER.info("LeaderboardHandler::add_entry - Adding message from " + str(user_id) +
                         " to the message queue for the emote " + emote)
Beispiel #10
0
    async def on_message(self, message):
        try:
            emoji = find(lambda e: str(e) == message.content,
                         message.guild.emojis)
        except AttributeError:
            return

        if emoji is not None:
            LeaderboardHandler.get_leaderboard_handler().add_entry(
                message.author.id,
                message.created_at.replace(tzinfo=pytz.utc).astimezone(
                    pytz.timezone(
                        Config.get_config_property("server", "timezone"))),
                emoji.name)

        await self.process_commands(message)
Beispiel #11
0
    async def init(self, ctx: commands.context.Context, *args):
        """
        Initializes ten man with users in the general channel.
        Requires 10 users in the general voice channel

        SYNOPSIS
            .tm_init [-h] game

        OPTIONS
            -h --help   Provides help messages during the work flow
        """
        # Check if there is already a game going on and if there is bail
        if self.__ongoing is not None:
            raise commands.CommandError("There is already an ongoing ten man.")

        # Get the arguments from the command message. Game command is necessary (CSGO/Valorant)
        try:
            parsed_args = TenManArgParsers.TM_INIT_ARG_PARSER.parse_known_args(
                args=args)[0]
        except ArgumentParserError:
            raise commands.MissingRequiredArgument(
                inspect.Parameter(
                    name="Game", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD))

        game = Game.get(parsed_args.game)

        self.__display_help = parsed_args.help

        # All players should be in a communal voice channel when this command is called. Get all 10 players in the
        # voice channel and creates a list of all their ids.
        general_voice = find(
            lambda v: v.name == Config.get_config_property(
                "tenman", "generalVoice"), ctx.guild.voice_channels)
        member_list = [m.id for m in general_voice.members]
        member_list = [
            148297442452963329, 727670795081351188, 727672213871919215,
            727672966539771934, 645696336469164107
        ]
        # If there are more than 10 or less than 10 members there is going to be a problem
        # if len(member_list) is not 10:
        #     raise commands.CommandError("There were not enough players in the voice channel to start a ten man.")

        self.__ongoing = TenMan(participant_id_list=member_list, game=game)

        # Pretty output for discord
        embed = discord.Embed(title=ctx.guild.name + " Ten Man",
                              description="Ten Man initialization completed!",
                              color=discord.Color.dark_grey())

        logo = self.__resources[game.name.lower() + "Logo"]

        embed.add_field(name="Game", value=game.name)
        embed.add_field(name="Type", value="Best of 3")
        embed.add_field(name="Player Pick Sequence",
                        value=Config.get_config_property(
                            "tenman", "playerPickSequence"))
        embed.add_field(name="Available Participants",
                        value="\n".join([
                            find(lambda u: u.id == p, ctx.guild.members).name
                            for p in member_list
                        ]))
        embed.add_field(name="Available Map Pool",
                        value="\n".join(self.__ongoing.get_remaining_maps()),
                        inline=False)

        embed.set_image(url=logo)
        self.__status_message = await ctx.channel.send(embed=embed)

        if self.__display_help:
            message = "***Help Message:***\nTen man has been initialized. Now it's time to pick captains. You can do " \
                      "so by either calling\n`.pick_captains`\nor\n`.pick_captains @captainA @captainB`"
            await ctx.channel.send(message)
import logging
from discord.ext import commands
from core.useraccounts import get_account
from _global.config import Config
from utilities.misc import get_project_dir

LOGGER = logging.getLogger("goldlog")

SERVER_SAVE_FILE = get_project_dir() / "{0}/server.pkl".format(Config.get_config_property("saveDir"))


class UserAccountCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        LOGGER.info("Initialized user account command cog.")

    @commands.command(name="set_friend_code")
    async def set_friend_code(self, ctx, friend_code: str):
        account = get_account(ctx.message.author)
        if account.set_friend_code(friend_code):
            await ctx.channel.send(content="Your friend code has been set!")
            LOGGER.info("UserCommand::get_friend_code called for " + ctx.message.author.name)
        else:
            LOGGER.warning("UserCommand::set_friend_code call failed for " + str(ctx.message.author.id) +
                           ". Invalid formatting")
            raise commands.BadArgument("Incorrect Friend Code formatting. Expecting formats:\n"
                                       "`1234-1234-1234`\n`SW-1234-1234-1234`\n`DS-1234-1234-1234`", friend_code)

    @commands.command(name="get_friend_code")
    async def get_friend_code(self, ctx):
        if len(ctx.message.mentions) < 1:
Beispiel #13
0
 def __role_is_optional(role):
     return role.name in Config.get_config_property("server", "optionalRoles")
Beispiel #14
0
    async def subscribable(self, ctx):

        await ctx.channel.send("```yaml\nsubscribable:\n - {0}```".format("\n - ".join(sorted(Config.get_config_property("server", "optionalRoles")))))
Beispiel #15
0
import yaml
from discord.ext import commands
from discord.ext.commands import UserConverter
from cogs.helper.challonge import tournamentcommands
from _global.config import Config
from utilities.misc import read_save_file, save_file
from _global.squadlockeconstants import ENCOUNTER_AREA_DICT, WEATHER_DICT
from _global.argparsers.squadlockeargparsers import SquadlockeArgParsers
from utilities.discordservices import build_embed
from core.model.squadlocke.routeencounter import RouteEncounter
from utilities.parsers.serebiiparser import SerebiiParser
from _global.argparsers.throwingargumentparser import ArgumentParserError

LOGGER = logging.getLogger("goldlog")

SQUADLOCKE_DATA_FILE_PATH = Config.get_config_property(
    "saveDir") + "/squadlocke/sldata.pkl"
SQUADLOCKE_ROLE = Config.get_config_property("squadlocke", "role")
SQUADLOCKE_NAME = Config.get_config_property("squadlocke",
                                             "defaultCheckpointName")
SL_SERIALIZE = read_save_file(SQUADLOCKE_DATA_FILE_PATH)
PARTICIPANTS = {} if len(SL_SERIALIZE) < 1 else SL_SERIALIZE[0]
CHECKPOINT = 1 if len(SL_SERIALIZE) < 2 else SL_SERIALIZE[1]

with open("bin/resources/squadlocke/resources.yml") as f:
    RESOURCES = yaml.load(f, Loader=yaml.FullLoader)

save_file([PARTICIPANTS, CHECKPOINT], SQUADLOCKE_DATA_FILE_PATH)


class SquadlockeCog(commands.Cog):
    def __init__(self, bot):
Beispiel #16
0
    async def pick_captains(self, ctx: commands.context.Context):
        """
        Makes mentioned players captain or selects two captains at random if none are provided

        SYNOPSIS
            .tm_pick_captains [@mention @mention]
        """
        # Caller tried to manually select too many captains
        if len(ctx.message.mentions) > 2:
            raise commands.TooManyArguments(
                "Attempted to pick too many captains.")

        # Create role objects for config
        captain_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "captainRole"), ctx.guild.roles)
        captain_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "captainRole"), ctx.guild.roles)

        # Get captains either randomly or manually (based on # of mentioned users)
        captain_ids = ctx.message.raw_mentions
        captains = self.__ongoing.set_or_pick_captains(captain_ids)
        captain_a = find(lambda c: c.id == captains[0], ctx.guild.members)
        captain_b = find(lambda c: c.id == captains[1], ctx.guild.members)
        await captain_a.add_roles(captain_a_role)
        await captain_b.add_roles(captain_b_role)

        # Pretty output for discord
        embed_a = discord.Embed(title="Captain Selected",
                                color=discord.Color.red())
        embed_a.set_thumbnail(url=captain_a.avatar_url)
        embed_a.add_field(name="Name", value=captain_a.name)
        embed_a.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_a.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        embed_b = discord.Embed(title="Captain Selected",
                                color=discord.Color.blue())
        embed_b.set_thumbnail(url=captain_b.avatar_url)
        embed_b.add_field(name="Name", value=captain_b.name)
        embed_b.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_b.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        await ctx.channel.send(embed=embed_a)
        await ctx.channel.send(embed=embed_b)

        try:
            await self.__move_user_to_proper_voice(ctx, captain_a,
                                                   TeamStatus.A)
            await self.__move_user_to_proper_voice(ctx, captain_b,
                                                   TeamStatus.B)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        rp_field = status_embed.fields[3]
        status_embed.set_field_at(
            index=3,
            name=rp_field.name,
            value="\n".join([
                find(lambda u: u.id == rp, ctx.guild.members).name
                for rp in self.__ongoing.get_remaining_participant_ids()
            ]))
        status_embed.insert_field_at(index=4,
                                     name="Team A",
                                     value=captain_a.name,
                                     inline=True)
        status_embed.insert_field_at(index=5,
                                     name="Team B",
                                     value=captain_b.name,
                                     inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            message = "***Help Message***:\nNow that captains have been selected, it is time for the captain of Team" \
                      "A to pick a player. They can do so by using the command\n`.pick_player @mention`"
            await ctx.channel.send(message)
Beispiel #17
0
class TenManCog(commands.Cog):
    """
    The `Ten Man` module allows members of the discord server to start a ten man. A ten man is a game type where 10
    players gather, form two teams, and compete against each other. A ten man can be orchestrated for
    `Counter-Strike: Global Offensive` or `Valorant`
    """
    def __init__(self, bot: commands.Bot):
        self.bot = bot
        # core.model.tenman
        self.__ongoing = None
        # Message for displaying the current status of the tenman (teams, map picks, etc.)
        self.__status_message = None
        # Print help messages to help new users know which commands need to come next
        self.__display_help = False

        with open(str(get_project_dir() /
                      "bin/resources/tenman/resources.yml")) as f:
            self.__resources = yaml.load(f, Loader=yaml.FullLoader)
        LOGGER.info("Initialized ten man command cog.")

    @commands.command(name="tm_init", aliases=["tm_start"])
    @commands.has_role(Config.get_config_property("tenman", "organizerRole"))
    async def init(self, ctx: commands.context.Context, *args):
        """
        Initializes ten man with users in the general channel.
        Requires 10 users in the general voice channel

        SYNOPSIS
            .tm_init [-h] game

        OPTIONS
            -h --help   Provides help messages during the work flow
        """
        # Check if there is already a game going on and if there is bail
        if self.__ongoing is not None:
            raise commands.CommandError("There is already an ongoing ten man.")

        # Get the arguments from the command message. Game command is necessary (CSGO/Valorant)
        try:
            parsed_args = TenManArgParsers.TM_INIT_ARG_PARSER.parse_known_args(
                args=args)[0]
        except ArgumentParserError:
            raise commands.MissingRequiredArgument(
                inspect.Parameter(
                    name="Game", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD))

        game = Game.get(parsed_args.game)

        self.__display_help = parsed_args.help

        # All players should be in a communal voice channel when this command is called. Get all 10 players in the
        # voice channel and creates a list of all their ids.
        general_voice = find(
            lambda v: v.name == Config.get_config_property(
                "tenman", "generalVoice"), ctx.guild.voice_channels)
        member_list = [m.id for m in general_voice.members]
        member_list = [
            148297442452963329, 727670795081351188, 727672213871919215,
            727672966539771934, 645696336469164107
        ]
        # If there are more than 10 or less than 10 members there is going to be a problem
        # if len(member_list) is not 10:
        #     raise commands.CommandError("There were not enough players in the voice channel to start a ten man.")

        self.__ongoing = TenMan(participant_id_list=member_list, game=game)

        # Pretty output for discord
        embed = discord.Embed(title=ctx.guild.name + " Ten Man",
                              description="Ten Man initialization completed!",
                              color=discord.Color.dark_grey())

        logo = self.__resources[game.name.lower() + "Logo"]

        embed.add_field(name="Game", value=game.name)
        embed.add_field(name="Type", value="Best of 3")
        embed.add_field(name="Player Pick Sequence",
                        value=Config.get_config_property(
                            "tenman", "playerPickSequence"))
        embed.add_field(name="Available Participants",
                        value="\n".join([
                            find(lambda u: u.id == p, ctx.guild.members).name
                            for p in member_list
                        ]))
        embed.add_field(name="Available Map Pool",
                        value="\n".join(self.__ongoing.get_remaining_maps()),
                        inline=False)

        embed.set_image(url=logo)
        self.__status_message = await ctx.channel.send(embed=embed)

        if self.__display_help:
            message = "***Help Message:***\nTen man has been initialized. Now it's time to pick captains. You can do " \
                      "so by either calling\n`.pick_captains`\nor\n`.pick_captains @captainA @captainB`"
            await ctx.channel.send(message)

    @commands.command(name="tm_pick_captains", aliases=["pick_captains"])
    @commands.has_role(Config.get_config_property("tenman", "organizerRole"))
    async def pick_captains(self, ctx: commands.context.Context):
        """
        Makes mentioned players captain or selects two captains at random if none are provided

        SYNOPSIS
            .tm_pick_captains [@mention @mention]
        """
        # Caller tried to manually select too many captains
        if len(ctx.message.mentions) > 2:
            raise commands.TooManyArguments(
                "Attempted to pick too many captains.")

        # Create role objects for config
        captain_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "captainRole"), ctx.guild.roles)
        captain_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "captainRole"), ctx.guild.roles)

        # Get captains either randomly or manually (based on # of mentioned users)
        captain_ids = ctx.message.raw_mentions
        captains = self.__ongoing.set_or_pick_captains(captain_ids)
        captain_a = find(lambda c: c.id == captains[0], ctx.guild.members)
        captain_b = find(lambda c: c.id == captains[1], ctx.guild.members)
        await captain_a.add_roles(captain_a_role)
        await captain_b.add_roles(captain_b_role)

        # Pretty output for discord
        embed_a = discord.Embed(title="Captain Selected",
                                color=discord.Color.red())
        embed_a.set_thumbnail(url=captain_a.avatar_url)
        embed_a.add_field(name="Name", value=captain_a.name)
        embed_a.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_a.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        embed_b = discord.Embed(title="Captain Selected",
                                color=discord.Color.blue())
        embed_b.set_thumbnail(url=captain_b.avatar_url)
        embed_b.add_field(name="Name", value=captain_b.name)
        embed_b.add_field(
            name="Selection Type",
            value="Manual" if len(ctx.message.mentions) == 2 else "Random")
        embed_b.add_field(name="Ten Man Status",
                          value="[Link](" + self.__status_message.jump_url +
                          ")")

        await ctx.channel.send(embed=embed_a)
        await ctx.channel.send(embed=embed_b)

        try:
            await self.__move_user_to_proper_voice(ctx, captain_a,
                                                   TeamStatus.A)
            await self.__move_user_to_proper_voice(ctx, captain_b,
                                                   TeamStatus.B)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        rp_field = status_embed.fields[3]
        status_embed.set_field_at(
            index=3,
            name=rp_field.name,
            value="\n".join([
                find(lambda u: u.id == rp, ctx.guild.members).name
                for rp in self.__ongoing.get_remaining_participant_ids()
            ]))
        status_embed.insert_field_at(index=4,
                                     name="Team A",
                                     value=captain_a.name,
                                     inline=True)
        status_embed.insert_field_at(index=5,
                                     name="Team B",
                                     value=captain_b.name,
                                     inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            message = "***Help Message***:\nNow that captains have been selected, it is time for the captain of Team" \
                      "A to pick a player. They can do so by using the command\n`.pick_player @mention`"
            await ctx.channel.send(message)

    @commands.command(name="tm_pick_player", aliases=["pick_player"])
    @commands.has_any_role(
        Config.get_config_property("tenman", "teamA", "captainRole"),
        Config.get_config_property("tenman", "teamB", "captainRole"))
    async def pick_player(self, ctx: commands.context.Context):
        """
        Adds player to calling captains team.

        SYNOPSIS
            .tm_pick_player @mention
        """
        if len(ctx.message.raw_mentions) > 1:
            raise commands.TooManyArguments(
                "Captain attempted to pick too many players.")

        captain_id = ctx.message.author.id
        try:
            pick = ctx.message.mentions[0]
        except IndexError:
            raise commands.MissingRequiredArgument(param=inspect.Parameter(
                name="Player", kind=inspect.Parameter.POSITIONAL_ONLY))
        captain_team_status = self.__ongoing.get_captain_team_status(
            captain_id)

        last_pick = self.__ongoing.pick_player(pick.id, captain_id)

        role_config_property = Config.get_config_property(
            "tenman", "team{0}".format(captain_team_status.name), "playerRole")
        role = find(lambda r: r.name == role_config_property, ctx.guild.roles)
        await ctx.message.mentions[0].add_roles(role)

        embed = discord.Embed(title="Player Selected",
                              color=discord.Color.red() if captain_team_status
                              == TeamStatus.A else discord.Color.blue())
        embed.add_field(name="Name", value=ctx.message.mentions[0].name)
        embed.add_field(name="Picked By",
                        value="Team {0}".format(captain_team_status.name))
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))
        embed.set_thumbnail(url=pick.avatar_url)
        await ctx.channel.send(embed=embed)

        try:
            await self.__move_user_to_proper_voice(ctx,
                                                   ctx.message.mentions[0],
                                                   captain_team_status)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        team_field = status_embed.fields[4 if captain_team_status ==
                                         TeamStatus.A else 5]
        status_embed.set_field_at(
            index=(4 if captain_team_status == TeamStatus.A else 5),
            name=team_field.name,
            value=(team_field.value + "\n" + pick.name))

        if last_pick[0] is not None and last_pick[1] is not None:
            last_pick_profile = find(lambda p: p.id == last_pick[0],
                                     ctx.guild.members)
            role_config_property_lp = Config.get_config_property(
                "tenman", "team{0}".format(last_pick[1].name), "playerRole")
            role_lp = find(lambda r: r.name == role_config_property_lp,
                           ctx.guild.roles)

            await last_pick_profile.add_roles(role_lp)

            embed_lp = discord.Embed(title="Last Pick",
                                     color=discord.Color.red() if last_pick[1]
                                     == TeamStatus.A else discord.Color.blue())
            embed_lp.set_thumbnail(url=last_pick_profile.avatar_url)
            embed_lp.add_field(name="Name", value=last_pick_profile.name)
            embed_lp.add_field(name="Picked for",
                               value="Team {0}".format(last_pick[1].name))
            embed_lp.add_field(name="Ten Man Status",
                               value="[Link]({0})".format(
                                   self.__status_message.jump_url))
            await ctx.channel.send(embed=embed_lp)
            status_embed.remove_field(index=3)
            status_embed.set_field_at(
                index=(3 if last_pick[0] == TeamStatus.A else 4),
                name=team_field.name,
                value="{0}\n{1}".format(team_field.value,
                                        last_pick_profile.name))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        else:
            rp_field = status_embed.fields[3]
            status_embed.set_field_at(
                index=3,
                name=rp_field.name,
                value="\n".join([
                    find(lambda u: u.id == rp, ctx.guild.members).name
                    for rp in self.__ongoing.get_remaining_participant_ids()
                ]))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            try:
                message = "***Help Message:***\nIt is Team {0}'s turn to pick the next player.\nThey can do so by " \
                          "using the command\n`.pick_player @player`".format(self.__ongoing.peek_next_player_pick().name)
            except IndexError:
                map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban()
                message = "***Help Message:***\nIt is now time to move on to the map pick/ban phase. Team " \
                          "{0.get_team_status().name} can {0.get_mode().name.lower()} the first map.\nThey can do so" \
                          "by using the command\n`{0.get_mode().name.lower()}_map map`".format(map_pick_ban_entry)
            await ctx.channel.send(message)

    @commands.command(name="tm_ban_map", aliases=["ban_map"])
    @commands.has_any_role(
        Config.get_config_property("tenman", "teamA", "captainRole"),
        Config.get_config_property("tenman", "teamB", "captainRole"))
    async def ban_map(self, ctx: commands.context.Context, map_name: str):
        """
        Bans map and removes it from the selection pool

        SYNOPSIS
            .tm_ban_map map

        :param map_name: Name of map selected for ban
        """
        map_name = map_name.lower().replace(" ", "")
        captain_id = ctx.message.author.id
        status = self.__ongoing.get_captain_team_status(captain_id)
        decider = self.__ongoing.ban_map(map_name, captain_id)

        embed = discord.Embed(title="Map Banned", color=discord.Color.red())
        embed.set_image(url=self.__resources[map_name])
        embed.add_field(name="Map Name", value=map_name.capitalize())
        embed.add_field(name="Banned by", value="Team {0}".format(status.name))
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))

        await ctx.channel.send(embed=embed)

        status_embed = self.__status_message.embeds[0]

        banned_text = "{0} - Team {1}".format(map_name.capitalize(),
                                              status.name)
        try:
            banned_field = status_embed.fields[6]
            status_embed.set_field_at(index=6,
                                      name=banned_field.name,
                                      value="{0}\n{1}".format(
                                          banned_field.value, banned_text))
        except IndexError:
            status_embed.add_field(name="Ban History", value=banned_text)
        finally:
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value="\n".join(
                                          self.__ongoing.get_remaining_maps()))

        if decider is not None:
            embed_decider = discord.Embed(title="Map Picked",
                                          color=discord.Color.dark_grey())
            embed_decider.set_image(url=self.__resources[decider])
            embed_decider.add_field(name="Map Name",
                                    value=decider.capitalize())
            embed_decider.add_field(name="Type", value="Decider")
            embed_decider.add_field(name="Ten Man Status",
                                    value="[Link]({0})".format(
                                        self.__status_message.jump_url))
            status_embed.add_field(name="Decider", value=decider.capitalize())
            status_embed.remove_field(index=5)
            await ctx.channel.send(embed=embed_decider)

        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban()
            try:
                message = "It is Team {0.get_team_status().name}'s turn to {0.get_mode().name.lower()} a map." \
                          "\nThey can do so by using the command\n`. {0.get_mode().name.lower}_map map`"\
                          .format(map_pick_ban_entry)
            except IndexError:
                message = "Map pick/ban phase is over. See you on the server!"
            await ctx.channel.send(message)

    @commands.command(name="tm_pick_map", aliases=["pick_map"])
    @commands.has_any_role(
        Config.get_config_property("tenman", "teamA", "captainRole"),
        Config.get_config_property("tenman", "teamB", "captainRole"))
    async def pick_map(self, ctx: commands.context.Context, map_name: str):
        """
        Selects map for play

        SYNOPSIS:
            .tm_pick_map map
        :param map_name: Map picked to be played
        """
        map_name = map_name.lower().replace(" ", "")
        captain_id = ctx.message.author.id
        status = self.__ongoing.get_captain_team_status(captain_id)
        self.__ongoing.pick_map(map_name, captain_id)

        embed = discord.Embed(title="Map Picked", color=discord.Color.green())
        embed.set_image(url=self.__resources[map_name])
        embed.add_field(name="Map Name", value=map_name.capitalize())
        embed.add_field(name="Picked by", value="Team " + status.name)
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))

        await ctx.channel.send(embed=embed)

        status_embed = self.__status_message.embeds[0]

        status_embed.add_field(name="Team {0}'s Pick".format(status.name),
                               value=map_name.capitalize())

        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            message = "It is Team {0}'s turn to pick a side.\nThey can do so by using the command\n`.pick_side side`" \
                      .format(self.__ongoing.get_side_pick_team().name)
            await ctx.channel.send(message)

    @commands.command(name="tm_pick_side", aliases=["pick_side"])
    @commands.has_any_role(
        Config.get_config_property("tenman", "teamA", "captainRole"),
        Config.get_config_property("tenman", "teamB", "captainRole"))
    async def pick_side(self, ctx: commands.context.Context, side: str):
        """
        Selects start side for team opposite of the one who last picked a map

        SYNOPSIS
            .tm_pick_side side

        :param side: selected side
        """
        captain_id = ctx.message.author.id
        side, decider = self.__ongoing.pick_side(captain_id, side)
        status = self.__ongoing.get_captain_team_status(captain_id)
        status_embed = self.__status_message.embeds[0]
        pick_field = status_embed.fields[len(status_embed.fields) - 1]
        status_embed.set_field_at(index=len(status_embed.fields) - 1,
                                  name=pick_field.name,
                                  value="{0}\n{1}'s Start Side: {2}".format(
                                      pick_field.value, status.name,
                                      side.name))
        await self.__status_message.edit(embed=status_embed)

        embed = discord.Embed(title="Side Selected",
                              color=discord.Color.red() if status
                              == TeamStatus.A else discord.Color.blue())
        embed.set_thumbnail(
            url=self.__resources["csgo{0}Logo".format(side.name)])
        embed.add_field(name="Side", value=side.name)
        embed.add_field(name="Team", value=status.name)
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))
        await ctx.channel.send(embed=embed)

        if decider is not None:
            embed_decider = discord.Embed(title="Map Picked",
                                          color=discord.Color.dark_grey())
            embed_decider.set_image(url=self.__resources[decider])
            embed_decider.add_field(name="Map Name",
                                    value=decider.capitalize())
            embed_decider.add_field(name="Type", value="Decider")
            embed_decider.add_field(name="Ten Man Status",
                                    value="[Link]({0})".format(
                                        self.__status_message.jump_url))
            status_embed.add_field(name="Decider",
                                   value="{0}\nB's Start Side: {1}".format(
                                       decider.capitalize(),
                                       Side(randint(0, 1)).name))
            status_embed.set_field_at(index=5, name="\u200b", value="\u200b")

            await ctx.channel.send(embed=embed_decider)

        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            try:
                map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban()
                message = "It is Team {0.get_team_status().name}'s turn to {0.get_mode().name.lower()} a map.\nThey " \
                          "can do so by using the command\n`.{0.get_mode().name.lower()}_map map`"\
                          .format(map_pick_ban_entry)
            except IndexError:
                message = "Map pick/ban phase is over. See you on the server!"
            await ctx.channel.send(message)

    @commands.command(name="tm_free", aliases=["free"])
    @commands.has_role(Config.get_config_property("tenman", "organizerRole"))
    async def free(self, ctx: commands.context.Context):
        """
        Removes roles from all participating players

        SYNOPSIS
            .tm_free
        """
        captain_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "captainRole"), ctx.guild.roles)
        captain_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "captainRole"), ctx.guild.roles)
        player_a_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamA", "playerRole"), ctx.guild.roles)
        player_b_role = find(
            lambda r: r.name == Config.get_config_property(
                "tenman", "teamB", "playerRole"), ctx.guild.roles)

        await ctx.channel.send(content="Beginning deconstruction.")
        teams = self.__ongoing.get_teams()

        for a, b in zip(teams[0].get_players(), teams[1].get_players()):
            await find(lambda u: u.id == a,
                       ctx.guild.members).remove_roles(captain_a_role,
                                                       player_a_role)
            await find(lambda u: u.id == b,
                       ctx.guild.members).remove_roles(captain_b_role,
                                                       player_b_role)
        await ctx.channel.send(content="Players freed.")

        self.__ongoing = None

    @staticmethod
    async def __move_user_to_proper_voice(ctx: commands.context.Context,
                                          user: discord.Member,
                                          status: TeamStatus):
        voice = find(
            lambda v: v.name == Config.get_config_property(
                "tenman", "team{0}".format(status.name), "voice"),
            ctx.guild.voice_channels)
        await user.move_to(voice)
import requests
import logging
from _global.config import Config

LOGGER = logging.getLogger("goldlog")
API_KEY = Config.get_config_property("tournament", "challongeApiKey")
CHALLONGE_USERNAME = Config.get_config_property("tournament", "challongeUsername")
BASE_URL = "https://" + CHALLONGE_USERNAME + ":" + API_KEY + "@api.challonge.com/v1/"


def index_tournaments():
    url = BASE_URL + "tournaments.json"
    r = requests.get(url=url)
    return r.json()


def create_tournament(tournament_name, extra_params):
    # TODO: Check if the URL is taken and adjust it if it is.
    params = {
        "tournament[name]": tournament_name,
        "tournament[url]": tournament_name
    }
    if extra_params is not None:
        for arg in extra_params:
            tokens = arg.split('=')
            trim_underscores = tokens[1].split('_')
            tokens[1] = ""
            for token in trim_underscores:
                tokens[1] += token + " "

            tokens[1] = tokens[1].strip()
Beispiel #19
0
    async def pick_player(self, ctx: commands.context.Context):
        """
        Adds player to calling captains team.

        SYNOPSIS
            .tm_pick_player @mention
        """
        if len(ctx.message.raw_mentions) > 1:
            raise commands.TooManyArguments(
                "Captain attempted to pick too many players.")

        captain_id = ctx.message.author.id
        try:
            pick = ctx.message.mentions[0]
        except IndexError:
            raise commands.MissingRequiredArgument(param=inspect.Parameter(
                name="Player", kind=inspect.Parameter.POSITIONAL_ONLY))
        captain_team_status = self.__ongoing.get_captain_team_status(
            captain_id)

        last_pick = self.__ongoing.pick_player(pick.id, captain_id)

        role_config_property = Config.get_config_property(
            "tenman", "team{0}".format(captain_team_status.name), "playerRole")
        role = find(lambda r: r.name == role_config_property, ctx.guild.roles)
        await ctx.message.mentions[0].add_roles(role)

        embed = discord.Embed(title="Player Selected",
                              color=discord.Color.red() if captain_team_status
                              == TeamStatus.A else discord.Color.blue())
        embed.add_field(name="Name", value=ctx.message.mentions[0].name)
        embed.add_field(name="Picked By",
                        value="Team {0}".format(captain_team_status.name))
        embed.add_field(name="Ten Man Status",
                        value="[Link]({0})".format(
                            self.__status_message.jump_url))
        embed.set_thumbnail(url=pick.avatar_url)
        await ctx.channel.send(embed=embed)

        try:
            await self.__move_user_to_proper_voice(ctx,
                                                   ctx.message.mentions[0],
                                                   captain_team_status)
        except discord.errors.HTTPException:
            pass

        status_embed = self.__status_message.embeds[0]
        team_field = status_embed.fields[4 if captain_team_status ==
                                         TeamStatus.A else 5]
        status_embed.set_field_at(
            index=(4 if captain_team_status == TeamStatus.A else 5),
            name=team_field.name,
            value=(team_field.value + "\n" + pick.name))

        if last_pick[0] is not None and last_pick[1] is not None:
            last_pick_profile = find(lambda p: p.id == last_pick[0],
                                     ctx.guild.members)
            role_config_property_lp = Config.get_config_property(
                "tenman", "team{0}".format(last_pick[1].name), "playerRole")
            role_lp = find(lambda r: r.name == role_config_property_lp,
                           ctx.guild.roles)

            await last_pick_profile.add_roles(role_lp)

            embed_lp = discord.Embed(title="Last Pick",
                                     color=discord.Color.red() if last_pick[1]
                                     == TeamStatus.A else discord.Color.blue())
            embed_lp.set_thumbnail(url=last_pick_profile.avatar_url)
            embed_lp.add_field(name="Name", value=last_pick_profile.name)
            embed_lp.add_field(name="Picked for",
                               value="Team {0}".format(last_pick[1].name))
            embed_lp.add_field(name="Ten Man Status",
                               value="[Link]({0})".format(
                                   self.__status_message.jump_url))
            await ctx.channel.send(embed=embed_lp)
            status_embed.remove_field(index=3)
            status_embed.set_field_at(
                index=(3 if last_pick[0] == TeamStatus.A else 4),
                name=team_field.name,
                value="{0}\n{1}".format(team_field.value,
                                        last_pick_profile.name))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        else:
            rp_field = status_embed.fields[3]
            status_embed.set_field_at(
                index=3,
                name=rp_field.name,
                value="\n".join([
                    find(lambda u: u.id == rp, ctx.guild.members).name
                    for rp in self.__ongoing.get_remaining_participant_ids()
                ]))
            status_embed.set_field_at(index=5,
                                      name=status_embed.fields[5].name,
                                      value=status_embed.fields[5].value,
                                      inline=True)
        await self.__status_message.edit(embed=status_embed)

        if self.__display_help:
            try:
                message = "***Help Message:***\nIt is Team {0}'s turn to pick the next player.\nThey can do so by " \
                          "using the command\n`.pick_player @player`".format(self.__ongoing.peek_next_player_pick().name)
            except IndexError:
                map_pick_ban_entry = self.__ongoing.peek_next_map_pick_ban()
                message = "***Help Message:***\nIt is now time to move on to the map pick/ban phase. Team " \
                          "{0.get_team_status().name} can {0.get_mode().name.lower()} the first map.\nThey can do so" \
                          "by using the command\n`{0.get_mode().name.lower()}_map map`".format(map_pick_ban_entry)
            await ctx.channel.send(message)
Beispiel #20
0
    def process_entries(self):
        LOGGER.info("LeaderboardHandler::process_entries - Processing leaderboard entries")
        emoji_time_dict = Config.get_config_property("server", "leaderboard", "emojiMap")
        today = datetime.now()
        if today.day == 1:
            self.__process_score_reset()

        for emoji in emoji_time_dict.keys():
            leaderboard_path = str(get_project_dir() / "{0}/leaderboards/307026836066533377/{1}.json"
                                    .format(Config.get_config_property("saveDir"), emoji))
            leaderboard_json = read_json_safe(leaderboard_path)

            entries = [entry for entry in self.__unprocessed_entries if entry["emote"] == emoji]
            time = datetime.strptime(emoji_time_dict[emoji], "%H:%M")
            for entry in entries:
                if (entry["timestamp"].hour == time.hour or entry["timestamp"].hour == time.hour + 12) and entry["timestamp"].minute == time.minute:
                    if entries.index(entry) == 0:
                        score = Config.get_config_property("server", "leaderboard", "scores", "max")
                    else:
                        score = Config.get_config_property("server", "leaderboard", "scores", "default")
                else:
                    score = Config.get_config_property("server", "leaderboard", "scores", "min")
                    entry["timestamp"] = None

                try:
                    user_score = leaderboard_json[str(entry["user_id"])]
                except KeyError:
                    user_score = {
                        "score": 0,
                        "current_streak": 1,
                        "longest_streak": 0,
                        "timestamp": None
                    }

                if user_score["score"] + score < 0:
                    user_score["score"] = 0
                else:
                    user_score["score"] = user_score["score"] + score

                try:
                    last_timestamp = datetime.strptime(user_score["timestamp"], "%m/%d/%Y")
                except TypeError:
                    last_timestamp = None
                try:
                    user_score["timestamp"] = datetime.strftime(entry["timestamp"], "%m/%d/%Y")
                except TypeError:
                    user_score["timestamp"] = None

                try:
                    if entry["timestamp"] is None:
                        user_score["current_streak"] = 0
                    elif (entry["timestamp"].date() - last_timestamp.date()).days == 1:
                        user_score["current_streak"] = user_score["current_streak"] + 1
                    elif (entry["timestamp"].date() - last_timestamp.date()).days > 1:
                        user_score["current_streak"] = 1
                except AttributeError:
                    pass

                if user_score["current_streak"] > user_score["longest_streak"]:
                    user_score["longest_streak"] = user_score["current_streak"]
                leaderboard_json[str(entry["user_id"])] = user_score
                self.__unprocessed_entries.remove(entry)

            current_day = datetime.now().date()
            for key in leaderboard_json:
                try:
                    score = leaderboard_json[key]
                    if (current_day - datetime.strptime(score["timestamp"], "%m/%d/%Y").date()).days > 1:
                        score["current_streak"] = 0
                        leaderboard_json[key] = score
                except (KeyError, TypeError):
                    pass

            with open(leaderboard_path, "w") as f:
                json.dump(leaderboard_json, f, indent=4)
from utilities.misc import read_save_file, save_file
from core.model.accounts.useraccount import UserAccount
from _global.config import Config

ACCOUNTS_FILE_PATH = Config.get_config_property("saveDir") + "/accounts/accounts.pkl"
ACCOUNTS = read_save_file(ACCOUNTS_FILE_PATH)


def get_account(prof):
    if prof.bot:
        return None
    return __get_or_create_account(prof.id)


def save_accounts():
    save_file(ACCOUNTS, ACCOUNTS_FILE_PATH)


def __get_or_create_account(_id):
    return_account = None
    for account in ACCOUNTS:
        if account.get_id() == _id:
            return_account = account
            break
    if return_account is None:
        return_account = __create_account(_id)
    return return_account


def __create_account(_id):
    account = UserAccount(_id)