示例#1
0
    def __init__(self, bot:utils.Bot):
        super().__init__(bot)
        self._channels = []  # Populated automatically

        # Set up our redis handlers baybee
        task = bot.loop.create_task
        self.handlers = [
            task(self.channel_handler('DBLVote', lambda data: bot.dbl_votes.__setitem__(data['user_id'], dt.strptime(data['datetime'], "%Y-%m-%dT%H:%M:%S.%f")))),
            task(self.channel_handler('ProposalCacheAdd', lambda data: bot.proposal_cache.raw_add(**data))),
            task(self.channel_handler('ProposalCacheRemove', lambda data: bot.proposal_cache.raw_remove(*data))),
            task(self.channel_handler('BlockedUserAdd', lambda data: bot.blocked_users[data['user_id']].append(data['blocked_user_id']))),
            task(self.channel_handler('BlockedUserRemove', lambda data: bot.blocked_users[data['user_id']].remove(data['blocked_user_id']))),
            task(self.channel_handler('EvalAll', self.eval_all)),
            task(self.channel_handler('UpdateGuildPrefix', self.update_guild_prefix)),
            task(self.channel_handler('UpdateFamilyMaxMembers', self.update_max_family_members)),
            task(self.channel_handler('UpdateIncestAllowed', self.update_incest_alllowed)),
            task(self.channel_handler('UpdateMaxChildren', self.update_max_children)),
            task(self.channel_handler('UpdateGifsEnabled', self.update_gifs_enabled)),
            task(self.channel_handler('SendUserMessage', self.send_user_message)),
            task(self.channel_handler('AddGoldUser', self.add_gold_user)),
        ]
        # if not self.bot.is_server_specific:
        self.handlers.extend([
            task(self.channel_handler('TreeMemberUpdate', lambda data: utils.FamilyTreeMember(**data))),
        ])
示例#2
0
    async def recachefamily(self, ctx:utils.Context, user:utils.converters.UserID, guild_id:int=0):
        """Recaches a user's family tree member object, but through their whole family"""

        # Get connections
        db = await self.bot.database.get_connection()
        re = await self.bot.redis.get_connection()

        # Loop through their tree
        family = utils.FamilyTreeMember.get(user, guild_id).span(expand_upwards=True, add_parent=True)[:]
        for i in family:
            parent = await db('SELECT parent_id FROM parents WHERE child_id=$1 AND guild_id=$2', i.id, guild_id)
            children = await db('SELECT child_id FROM parents WHERE parent_id=$1 AND guild_id=$2', i.id, guild_id)
            partner = await db('SELECT partner_id FROM marriages WHERE user_id=$1 AND guild_id=$2', i.id, guild_id)

            # Load data into cache
            children = [i['child_id'] for i in children]
            parent_id = parent[0]['parent_id'] if len(parent) > 0 else None
            partner_id = partner[0]['partner_id'] if len(partner) > 0 else None
            f = utils.FamilyTreeMember(
                i.id,
                children=children,
                parent_id=parent_id,
                partner_id=partner_id,
                guild_id=guild_id,
            )

            # Push update via redis
            await re.publish_json('TreeMemberUpdate', f.to_json())

        # Disconnect from database
        await db.disconnect()
        await re.disconnect()

        # Output to user
        await ctx.send(f"Published `{len(family)}` updates.")
示例#3
0
    async def recache(self, ctx:utils.Context, user:utils.converters.UserID, guild_id:int=0):
        """Recaches a user's family tree member object"""

        # Read data from DB
        async with self.bot.database() as db:
            parent = await db('SELECT parent_id FROM parents WHERE child_id=$1 AND guild_id=$2', user, guild_id)
            children = await db('SELECT child_id FROM parents WHERE parent_id=$1 AND guild_id=$2', user, guild_id)
            partner = await db('SELECT partner_id FROM marriages WHERE user_id=$1 AND guild_id=$2', user, guild_id)

        # Load data into cache
        children = [i['child_id'] for i in children]
        parent_id = parent[0]['parent_id'] if len(parent) > 0 else None
        partner_id = partner[0]['partner_id'] if len(partner) > 0 else None
        f = utils.FamilyTreeMember(
            user,
            children=children,
            parent_id=parent_id,
            partner_id=partner_id,
            guild_id=guild_id,
        )

        # Push update via redis
        async with self.bot.redis() as re:
            await re.publish_json('TreeMemberUpdate', f.to_json())

        # Output to user
        await ctx.send("Published update for user.")
 def handle_partner(row):
     utils.FamilyTreeMember(
         discord_id=row['user_id'],
         children=[],
         parent_id=None,
         partner_id=row['partner_id'],
         guild_id=row['guild_id'],
     )
示例#5
0
    async def cache_setup(self, db):
        """
        Set up the cache for the users.
        """

        # Get family data from database
        try:
            if self.bot.config['is_server_specific']:
                partnerships = await db(
                    "SELECT * FROM marriages WHERE guild_id<>0")
                parents = await db("SELECT * FROM parents WHERE guild_id<>0")
            else:
                partnerships = await db(
                    "SELECT * FROM marriages WHERE guild_id=0")
                parents = await db("SELECT * FROM parents WHERE guild_id=0")
        except Exception as e:
            self.logger.critical(
                f"Ran into an error selecting either marriages or parents: {e}"
            )
            exit(1)

        # Clear the current cache
        self.logger.info(f"Clearing the cache of all family tree members")
        localutils.FamilyTreeMember.all_users.clear()

        # Cache the family data - partners
        self.logger.info(
            f"Caching {len(partnerships)} partnerships from partnerships")
        for i in partnerships:
            localutils.FamilyTreeMember(discord_id=i['user_id'],
                                        children=[],
                                        parent_id=None,
                                        partner_id=i['partner_id'],
                                        guild_id=i['guild_id'])

        # - children
        self.logger.info(
            f"Caching {len(parents)} parents/children from parents")
        for i in parents:
            parent = localutils.FamilyTreeMember.get(i['parent_id'],
                                                     i['guild_id'])
            parent._children.append(i['child_id'])
            child = localutils.FamilyTreeMember.get(i['child_id'],
                                                    i['guild_id'])
            child._parent = i['parent_id']

        # And done
        return True
    def __init__(self, bot: utils.CustomBot):
        super().__init__(bot)
        self._channels = []  # Populated automatically

        # Set up our redis handlers baybee
        task = bot.loop.create_task
        self.handlers = [
            task(
                self.channel_handler(
                    'DBLVote', lambda data: bot.dbl_votes.__setitem__(
                        data['user_id'],
                        dt.strptime(data['datetime'], "%Y-%m-%dT%H:%M:%S.%f")))
            ),
            task(
                self.channel_handler(
                    'ProposalCacheAdd',
                    lambda data: bot.proposal_cache.raw_add(**data))),
            task(
                self.channel_handler(
                    'ProposalCacheRemove',
                    lambda data: bot.proposal_cache.raw_remove(*data))),
            task(
                self.channel_handler(
                    'BlockedUserAdd', lambda data: bot.blocked_users[data[
                        'user_id'].append(data['blocked_user_id'])])),
            task(
                self.channel_handler(
                    'BlockedUserRemove', lambda data: bot.blocked_users[data[
                        'user_id'].remove(data['blocked_user_id'])])),
            task(self.channel_handler('EvalAll', self.eval_all)),
            task(
                self.channel_handler('UpdateGuildPrefix',
                                     self.update_guild_prefix)),
        ]
        # if not self.bot.is_server_specific:
        self.handlers.extend([
            task(
                self.channel_handler(
                    'TreeMemberUpdate',
                    lambda data: utils.FamilyTreeMember(**data))),
        ])
 def tree_member_update(self, payload):
     utils.FamilyTreeMember(**payload)
示例#8
0
    async def startup(self):
        """The startup method for the bot - clears all the caches and reads
        everything out again from the database, essentially starting anew
        as if rebooted"""

        # Remove caches
        self.logger.debug("Clearing family tree member cache")
        utils.FamilyTreeMember.all_users.clear()
        self.logger.debug("Clearing blacklisted guilds cache")
        self.blacklisted_guilds.clear()
        self.logger.debug("Clearing guild settings cache")
        self.guild_settings.clear()
        self.logger.debug("Clearing DBL votes cache")
        self.dbl_votes.clear()
        self.logger.debug("Clearing blocked users cache")
        self.blocked_users.clear()
        self.logger.debug("Clearing random text cache")
        utils.random_text.RandomText.original.all_random_text.clear()

        # Grab a database connection
        db: utils.DatabaseConnection = await self.database.get_connection()

        # Load in all of the random text
        try:
            random_text = await db('SELECT * FROM random_text')
        except Exception as e:
            self.logger.critical(
                f"Ran into an errorr selecting random text: {e}")
            exit(1)
        self.logger.debug(f"Caching {len(random_text)} lines of random text")
        for row in random_text:
            utils.random_text.RandomText.original.all_random_text[
                row['command_name']][row['event_name']].append(row['string'])

        # Pick up the blacklisted guilds from the db
        try:
            blacklisted = await db('SELECT * FROM blacklisted_guilds')
        except Exception as e:
            self.logger.critical(
                f"Ran into an error selecting blacklisted guilds: {e}")
            exit(1)
        self.logger.debug(f"Caching {len(blacklisted)} blacklisted guilds")
        self.blacklisted_guilds = [i['guild_id'] for i in blacklisted]

        # Pick up the blocked users
        try:
            blocked = await db('SELECT * FROM blocked_user')
        except Exception as e:
            self.logger.critical(
                f"Ran into an error selecting blocked users: {e}")
            exit(1)
        self.logger.debug(f"Caching {len(blocked)} blocked users")
        for user in blocked:
            self.blocked_users[user['user_id']].append(user['blocked_user_id'])

        # Grab the command prefixes per guild
        try:
            all_settings = await db('SELECT * FROM guild_settings')
        except Exception as e:
            self.logger.critical(
                f"Ran into an error selecting guild settings: {e}")
            exit(1)
        self.logger.debug(f"Caching {len(all_settings)} guild settings")
        for items in all_settings:
            current_settings = self.guild_settings[
                items]  # Get current (which should include defaults)
            current_settings.update(**dict(items))  # Update from db
            if self.is_server_specific:
                current_settings['prefix'] = current_settings['gold_prefix']
            self.guild_settings[items['guild_id']] = current_settings  # Cache

        # Grab the last vote times of each user
        try:
            votes = await db(
                "SELECT * FROM dbl_votes WHERE timestamp > NOW() - INTERVAL '12 hours'"
            )
        except Exception as e:
            self.logger.critical(f"Ran into an error selecting DBL votes: {e}")
            exit(1)
        self.logger.debug(f"Caching {len(votes)} DBL votes")
        for v in votes:
            self.dbl_votes[v['user_id']] = v['timestamp']

        # Wait for the bot to cache users before continuing
        self.logger.debug(
            "Waiting until ready before completing startup method.")
        await self.wait_until_ready()

        # Look through and find what servers the bot is allowed to be on, if server specific
        if self.is_server_specific:
            try:
                allowed_guilds = await db(
                    'SELECT guild_id FROM guild_specific_families')
            except Exception as e:
                self.logger.critical(
                    f"Ran into an error selecting server specific guilds: {e}")
                exit(1)
            allowed_guild_ids = [i['guild_id'] for i in allowed_guilds]
            current_guild_ids = self._connection._guilds.keys()
            guild_ids_to_leave = [
                i for i in current_guild_ids if i not in allowed_guild_ids
            ]
            for guild_id in guild_ids_to_leave:
                guild = self.get_guild(guild_id)
                self.logger.warn(
                    f"Automatically left guild {guild.name} ({guild.id}) for non-subscription"
                )
                await guild.leave()

        # Get family data from database
        try:
            if self.is_server_specific:
                partnerships = await db(
                    'SELECT * FROM marriages WHERE guild_id<>0')
                parents = await db('SELECT * FROM parents WHERE guild_id<>0')
            else:
                partnerships = await db(
                    'SELECT * FROM marriages WHERE guild_id=0')
                parents = await db('SELECT * FROM parents WHERE guild_id=0')
        except Exception as e:
            self.logger.critical(
                f"Ran into an error selecting either marriages or parents: {e}"
            )
            exit(1)

        # Cache the family data - partners
        self.logger.debug(
            f"Caching {len(partnerships)} partnerships from partnerships")
        for i in partnerships:
            utils.FamilyTreeMember(discord_id=i['user_id'],
                                   children=[],
                                   parent_id=None,
                                   partner_id=i['partner_id'],
                                   guild_id=i['guild_id'])

        # - children
        self.logger.debug(
            f"Caching {len(parents)} parents/children from parents")
        for i in parents:
            parent = utils.FamilyTreeMember.get(i['parent_id'], i['guild_id'])
            parent._children.append(i['child_id'])
            child = utils.FamilyTreeMember.get(i['child_id'], i['guild_id'])
            child._parent = i['parent_id']

        # Disconnect from the database
        await db.disconnect()

        # Save all available names to redis
        async with self.redis() as re:
            for user in self.users:
                await re.set(f'UserName-{user.id}', str(user))

        # And update DBL
        await self.post_guild_count()