Exemplo n.º 1
0
    async def task_reset(self, bot):
        """
        The scheduled task to reset user goals at midnight
        :param bot:
        :return:
        """
        # Find all the user_goal records which are due a reset
        now = int(time.time())

        records = self.__db.get_all_sql(
            'SELECT * FROM user_goals WHERE reset <= %s', [now])
        for record in records:

            # Calculate the next reset time for the goal, depending on its type.
            user = User(record['user'], 0)
            try:
                next = user.calculate_user_reset_time(record['type'])
                lib.debug('Setting next ' + record['type'] +
                          ' goal reset time for ' + str(record['user']) +
                          ' to: ' + str(next))
                self.__db.update('user_goals', {
                    'completed': 0,
                    'current': 0,
                    'reset': next
                }, {'id': record['id']})
            except pytz.exceptions.UnknownTimeZoneError:
                lib.out('[ERROR] Invalid timezone (' +
                        user.get_setting('timezone') + ') for user ' +
                        str(record['user']))

        return True
Exemplo n.º 2
0
    async def scheduled_tasks(self):
        """
        Execute the scheduled tasks.
        (I believe) this is going to happen for each shard, so if we have 5 shards for example, this loop will be running simultaneously on each of them.
        :return:
        """
        lib.debug('[' + str(self.shard_id) +
                  '] Checking for scheduled tasks...')

        try:
            await Task.execute_all(self)
        except Exception as e:
            lib.out('Exception: ' + str(e))
Exemplo n.º 3
0
    def update(self):
        """
        Run any database updates which are required
        :return:
        """
        db = Database.instance()

        version = lib.get('./version.json')
        version = version.db_version

        db_version = db.get('bot_settings', {'setting': 'version'})
        current_version = db_version['value'] if db_version else 0

        version = int(version)
        current_version = int(current_version)

        # Find all update files
        for file in os.listdir(f'data/updates'):

            # If it ends with .update then try to use it.
            if file.endswith(".update"):

                # Get the update version from the file name and convert to int for comparison.
                update_version = int(file[:-7])

                # Is this update due to run?
                if update_version > current_version:

                    # Load the file and the SQL to run.
                    update = lib.get('./data/updates/' + file)

                    # Loop through the array of SQL statements to run.
                    for sql in update:
                        lib.out('[UPDATE] Running query `' + sql + '`')
                        db.execute(sql, [])

        # Once it's done, update the version in the database.
        setting = db.get('bot_settings', {'setting': 'version'})
        if setting:
            db.update('bot_settings', {'value': version},
                      {'setting': 'version'})
        else:
            db.insert('bot_settings', {'setting': 'version', 'value': version})
Exemplo n.º 4
0
    async def task_reset(self, bot):
        """
        The scheduled task to reset user goals at midnight
        :param bot:
        :return:
        """
        # Find all the user_goal records which are due a reset
        now = int(time.time())

        records = self.__db.get_all_sql(
            'SELECT * FROM user_goals WHERE reset <= %s', [now])
        for record in records:

            # Calculate the next reset time for the goal, depending on its type.
            user = User(record['user'], 0)
            try:
                user.reset_goal(record)
            except pytz.exceptions.UnknownTimeZoneError:
                lib.out('[ERROR] Invalid timezone (' +
                        user.get_setting('timezone') + ') for user ' +
                        str(record['user']))

        return True
Exemplo n.º 5
0
    def load_commands(self):
        """
        Load all the commands from the cogs/ directory.
        :return: void
        """
        # Find all the command groups in the cogs/ directory
        for dir in self.COMMAND_GROUPS:

            # Then all the files inside the command group directory
            for file in os.listdir(f'cogs/{dir}'):

                # If it ends with .py then try to load it.
                if file.endswith(".py"):

                    cog = file[:-3]

                    try:
                        self.load_extension(f"cogs.{dir}.{cog}")
                        lib.out(f'[EXT][{dir}.{cog}] loaded')
                    except Exception as e:
                        lib.out(f'[EXT][{dir}.{cog}] failed to load')
                        lib.out(e)
Exemplo n.º 6
0
    def setup(self):
        """
        Run the bot setup
        :return:
        """
        lib.out('[BOT] Beginning boot process')

        # Install the database.
        db = Database.instance()
        db.install()
        lib.out('[DB] Database tables installed')

        # Run any database updates.
        self.update()

        # Setup the recurring tasks which need running.
        self.setup_recurring_tasks()
        lib.out('[TASK] Recurring tasks inserted')

        # Restart all tasks which are marked as processing, in case the bot dropped out during the process.
        db.update('tasks', {'processing': 0})

        # Remove the default 'help' command.
        self.remove_command('help')
Exemplo n.º 7
0
    async def run(self, bot):
        """
        Run this task
        TODO: In the future, make this better. For now it will do.
        :return: bool
        """

        # If the task is already processing, don't go any further.
        if self.is_processing():
            return True

        # Mark the task as processing so other shards don't pick it up.
        self.start_processing(1)

        # Build a variable to store the method name to run
        method = 'task_' + str(self.type)

        # Start off with a False and see if we can successfully run and turn that to True
        result = False

        # Sprint tasks.
        if self.object == 'sprint':

            from structures.sprint import Sprint

            sprint = Sprint.get(self.object_id)
            if sprint.is_valid():
                result = await getattr(sprint, method)(bot)
            else:
                # If the sprint doesn't exist, then we can just delete this task.
                result = True

        elif self.object == 'goal':

            from structures.goal import Goal

            goal = Goal()
            result = await getattr(goal, method)(bot)

        elif self.object == 'event':

            from structures.event import Event

            event = Event(self.object_id)
            if event.is_valid():
                result = await getattr(event, method)(bot)
            else:
                # If the event doesn't exist, then we can just delete this task.
                return True

        else:
            # Invalid task object. May as well just delete this task.
            lib.out('Invalid task object: ' + self.object)
            result = True

        # If we finished the task, and it's not a recurring one, delete it.
        if result is True and not self.is_recurring():
            self.delete()
        else:
            self.start_processing(0)

        # If it's a recurring task, set its next run time.
        if self.is_recurring():
            self.set_recur()

        return result