def opsi_task_delay(self, recon_scan=False, submarine_call=False, ap_limit=False):
        """
        Delay the NextRun of all OpSi tasks.

        Args:
            recon_scan (bool): True to delay all tasks requiring recon scan 30 min.
            submarine_call (bool): True to delay all tasks requiring submarine call 60 min.
            ap_limit (bool): True to delay all tasks requiring action points 360 min.
        """
        if not recon_scan and not submarine_call and not ap_limit:
            return None
        kv = dict_to_kv({'recon_scan': recon_scan, 'submarine_call': submarine_call, 'ap_limit': ap_limit})

        def delay_tasks(task_list, minutes):
            next_run = datetime.now().replace(microsecond=0) + timedelta(minutes=minutes)
            for task in task_list:
                keys = f'{task}.Scheduler.NextRun'
                current = deep_get(self.data, keys=keys, default=datetime(2020, 1, 1, 0, 0))
                if current < next_run:
                    logger.info(f'Delay task `{task}` to {next_run} ({kv})')
                    self.modified[keys] = next_run

        def is_submarine_call(task):
            return deep_get(self.data, keys=f'{task}.OpsiFleet.Submarine', default=False) \
                   or 'submarine' in deep_get(self.data, keys=f'{task}.OpsiFleetFilter.Filter', default='').lower()

        def is_force_run(task):
            return deep_get(self.data, keys=f'{task}.OpsiExplore.ForceRun', default=False) \
                   or deep_get(self.data, keys=f'{task}.OpsiObscure.ForceRun', default=False) \
                   or deep_get(self.data, keys=f'{task}.OpsiAbyssal.ForceRun', default=False) \
                   or deep_get(self.data, keys=f'{task}.OpsiStronghold.ForceRun', default=False)

        def is_special_radar(task):
            return deep_get(self.data, keys=f'{task}.OpsiExplore.SpecialRadar', default=False)

        if recon_scan:
            tasks = SelectedGrids(['OpsiExplore', 'OpsiObscure', 'OpsiStronghold'])
            tasks = tasks.delete(tasks.filter(is_force_run)).delete(tasks.filter(is_special_radar))
            delay_tasks(tasks, minutes=30)
        if submarine_call:
            tasks = SelectedGrids(['OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiStronghold',
                                   'OpsiMeowfficerFarming'])
            tasks = tasks.filter(is_submarine_call).delete(tasks.filter(is_force_run))
            delay_tasks(tasks, minutes=60)
        if ap_limit:
            tasks = SelectedGrids(['OpsiExplore', 'OpsiDaily', 'OpsiObscure', 'OpsiAbyssal', 'OpsiStronghold',
                                   'OpsiMeowfficerFarming'])
            tasks = tasks.delete(tasks.filter(is_special_radar))
            delay_tasks(tasks, minutes=360)

        self.save()
    def _commission_choose(self, daily, urgent):
        """
        Args:
            daily (SelectedGrids):
            urgent (SelectedGrids):

        Returns:
            SelectedGrids, SelectedGrids: Chosen daily commission, Chosen urgent commission
        """
        # Count Commission
        total = daily.add_by_eq(urgent)
        self.max_commission = 4
        for comm in total:
            if comm.genre == 'event_daily':
                self.max_commission = 5
        running_count = int(np.sum([1 for c in total
                                    if c.status == 'running']))
        logger.attr('Running', f'{running_count}/{self.max_commission}')
        if running_count >= self.max_commission:
            return SelectedGrids([]), SelectedGrids([])

        # Filter
        COMMISSION_FILTER.load(self.config.Commission_CommissionFilter)
        run = COMMISSION_FILTER.apply(total.grids, func=self._commission_check)
        logger.attr('Filter_sort', ' > '.join([str(c) for c in run]))
        run = SelectedGrids(run)

        # Add shortest
        no_shortest = run.delete(SelectedGrids(['shortest']))
        if no_shortest.count + running_count < self.max_commission:
            if no_shortest.count < run.count:
                logger.info(
                    'Not enough commissions to run, add shortest daily commissions'
                )
                COMMISSION_FILTER.load(SHORTEST_FILTER)
                shortest = COMMISSION_FILTER.apply(daily,
                                                   func=self._commission_check)
                run = no_shortest.add_by_eq(SelectedGrids(shortest))
                logger.attr('Filter_sort', ' > '.join([str(c) for c in run]))
            else:
                logger.info('Not enough commissions to run')

        # Separate daily and urgent
        run = run[:self.max_commission - running_count]
        daily_choose = run.intersect_by_eq(daily)
        urgent_choose = run.intersect_by_eq(urgent)
        if daily_choose:
            logger.info('Choose daily commission')
            for comm in daily_choose:
                logger.info(comm)
        if urgent_choose:
            logger.info('Choose urgent commission')
            for comm in urgent_choose:
                logger.info(comm)

        return daily_choose, urgent_choose
Example #3
0
    def opsi_task_delay(self,
                        recon_scan=False,
                        submarine_call=False,
                        ap_limit=False):
        """
        Delay the NextRun of all OpSi tasks.

        Args:
            recon_scan (bool): True to delay all tasks requiring recon scan 30 min.
            submarine_call (bool): True to delay all tasks requiring submarine call 60 min.
            ap_limit (bool): True to delay all tasks requiring action points 360 min.
        """
        if not recon_scan and not submarine_call and not ap_limit:
            return None
        kv = dict_to_kv({
            "recon_scan": recon_scan,
            "submarine_call": submarine_call,
            "ap_limit": ap_limit,
        })

        def delay_tasks(task_list, minutes):
            next_run = datetime.now().replace(microsecond=0) + timedelta(
                minutes=minutes)
            for task in task_list:
                keys = f"{task}.Scheduler.NextRun"
                current = deep_get(self.data, keys=keys, default=DEFAULT_TIME)
                if current < next_run:
                    logger.info(f"Delay task `{task}` to {next_run} ({kv})")
                    self.modified[keys] = next_run

        def is_submarine_call(task):
            return (deep_get(
                self.data, keys=f"{task}.OpsiFleet.Submarine", default=False)
                    or "submarine" in deep_get(
                        self.data,
                        keys=f"{task}.OpsiFleetFilter.Filter",
                        default="").lower())

        def is_force_run(task):
            return (deep_get(
                self.data, keys=f"{task}.OpsiExplore.ForceRun", default=False)
                    or deep_get(self.data,
                                keys=f"{task}.OpsiObscure.ForceRun",
                                default=False)
                    or deep_get(self.data,
                                keys=f"{task}.OpsiAbyssal.ForceRun",
                                default=False)
                    or deep_get(self.data,
                                keys=f"{task}.OpsiStronghold.ForceRun",
                                default=False))

        def is_special_radar(task):
            return deep_get(self.data,
                            keys=f"{task}.OpsiExplore.SpecialRadar",
                            default=False)

        if recon_scan:
            tasks = SelectedGrids(
                ["OpsiExplore", "OpsiObscure", "OpsiStronghold"])
            tasks = tasks.delete(tasks.filter(is_force_run)).delete(
                tasks.filter(is_special_radar))
            delay_tasks(tasks, minutes=27)
        if submarine_call:
            tasks = SelectedGrids([
                "OpsiExplore",
                "OpsiDaily",
                "OpsiObscure",
                "OpsiAbyssal",
                "OpsiStronghold",
                "OpsiMeowfficerFarming",
            ])
            tasks = tasks.filter(is_submarine_call).delete(
                tasks.filter(is_force_run))
            delay_tasks(tasks, minutes=60)
        if ap_limit:
            tasks = SelectedGrids([
                "OpsiExplore",
                "OpsiDaily",
                "OpsiObscure",
                "OpsiAbyssal",
                "OpsiStronghold",
                "OpsiMeowfficerFarming",
            ])
            if get_os_reset_remain() > 0:
                delay_tasks(tasks, minutes=360)
            else:
                logger.info(
                    "Just less than 1 day to OpSi reset, delay 2.5 hours")
                delay_tasks(tasks, minutes=150)

        self.update()