Exemplo n.º 1
0
    def process_gym(self, gym):
        # type: (Events.GymEvent) -> None
        """ Process a gym event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        gym.gym_name = self.__cache.gym_name(gym.gym_id, gym.gym_name)
        gym.gym_description = self.__cache.gym_desc(gym.gym_id,
                                                    gym.gym_description)
        gym.gym_image = self.__cache.gym_image(gym.gym_id, gym.gym_image)

        # Ignore changes to neutral
        if self._ignore_neutral and gym.new_team_id == 0:
            self._log.debug("%s gym update skipped: new team was neutral",
                            gym.name)
            return

        # Update Team Information
        gym.old_team_id = self.__cache.gym_team(gym.gym_id)
        self.__cache.gym_team(gym.gym_id, gym.new_team_id)

        # Check if notifications are on
        if self._gyms_enabled is False:
            self._log.debug("Gym ignored: gym notifications are disabled.")
            return

        # Doesn't look like anything to me
        if gym.new_team_id == gym.old_team_id:
            self._log.debug("%s gym update skipped: no change detected",
                            gym.gym_id)
            return

        # Calculate distance and direction
        if self.__location is not None:
            gym.distance = get_earth_dist([gym.lat, gym.lng], self.__location,
                                          self.__units)
            gym.direction = get_cardinal_dir([gym.lat, gym.lng],
                                             self.__location)

        # Check for Rules
        rules = self.__gym_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._gym_filters.keys(), self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(gym, self._gym_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(gym, rule.alarm_names, 'gym_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Gym %s passed %s rule(s) and triggered %s alarm(s).',
                gym.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Gym %s rejected by all rules.', gym.name)
Exemplo n.º 2
0
    def process_gym(self, gym):
        # type: (Events.GymEvent) -> None
        """ Process a gym event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        self.__cache.update_gym_info(gym.gym_id, gym.gym_name,
                                     gym.gym_description, gym.gym_image)

        # Ignore changes to neutral
        if self.__ignore_neutral and gym.new_team_id == 0:
            log.debug("%s gym update skipped: new team was neutral")
            return

        # Get the old team and update new team
        gym.old_team_id = self.__cache.get_gym_team(gym.gym_id)
        self.__cache.update_gym_team(gym.gym_id, gym.new_team_id)

        # Check if notifications are on
        if self.__gyms_enabled is False:
            log.debug("Gym ignored: gym notifications are disabled.")
            return

        # Update the cache with the gyms info
        info = self.__cache.get_gym_info(gym.gym_id)
        gym.gym_name = info['name']
        gym.gym_description = info['description']
        gym.gym_image = info['url']

        # Doesn't look like anything to me
        if gym.new_team_id == gym.old_team_id:
            log.debug("%s gym update skipped: no change detected", gym.gym_id)
            return

        # Calculate distance and direction
        if self.__location is not None:
            gym.distance = get_earth_dist([gym.lat, gym.lng], self.__location)
            gym.direction = get_cardinal_dir([gym.lat, gym.lng],
                                             self.__location)

        # Check for Rules
        rules = self.__gym_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__gym_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__gym_filters.get(f_name)
                passed = f.check_event(gym) and self.check_geofences(f, gym)
                if not passed:
                    continue  # go to next filter
                gym.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} gym notification"
                             " has been triggered in rule '{}'!"
                             "".format(gym.name, r_name))
                self._trigger_gym(gym, rule.alarm_names)
                break  # Next rule
Exemplo n.º 3
0
    def process_egg(self, egg):
        # type: (Events.EggEvent) -> None
        """ Process a egg event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        self.__cache.update_gym_info(egg.gym_id, egg.gym_name,
                                     egg.gym_description, egg.gym_image)

        # Make sure that eggs are enabled
        if self.__eggs_enabled is False:
            log.debug("Egg ignored: egg notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.get_egg_expiration(egg.gym_id) is not None:
            log.debug("Egg {} was skipped because it was previously "
                      "processed.".format(egg.gym_name))
            return
        self.__cache.update_egg_expiration(egg.gym_id, egg.hatch_time)

        # Check the time remaining
        seconds_left = (egg.hatch_time - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("Egg {} was skipped because only {} seconds remained"
                      "".format(egg.gym_name, seconds_left))
            return

        # Assigned cached info
        info = self.__cache.get_gym_info(egg.gym_id)
        egg.gym_name = info['name']
        egg.gym_description = info['description']
        egg.gym_image = info['url']

        # Calculate distance and direction
        if self.__location is not None:
            egg.distance = get_earth_dist([egg.lat, egg.lng], self.__location)
            egg.direction = get_cardinal_dir([egg.lat, egg.lng],
                                             self.__location)

        # Check for Rules
        rules = self.__egg_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__egg_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__egg_filters.get(f_name)
                passed = f.check_event(egg) and self.check_geofences(f, egg)
                if not passed:
                    continue  # go to next filter
                egg.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} egg notification"
                             " has been triggered to {}!"
                             "".format(egg.gym_name, egg.geofence))
                self._trigger_egg(egg, rule.alarm_names)
                break  # Next rule
Exemplo n.º 4
0
    def process_gym(self, gym):
        # type: (Events.GymEvent) -> None
        """ Process a gym event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        gym.gym_name = self.__cache.gym_name(gym.gym_id, gym.gym_name)
        gym.gym_description = self.__cache.gym_desc(
            gym.gym_id, gym.gym_description)
        gym.gym_image = self.__cache.gym_image(gym.gym_id, gym.gym_image)

        # Ignore changes to neutral
        if self._ignore_neutral and gym.new_team_id == 0:
            self._log.debug("%s gym update skipped: new team was neutral")
            return

        # Update Team Information
        gym.old_team_id = self.__cache.gym_team(gym.gym_id)
        self.__cache.gym_team(gym.gym_id, gym.new_team_id)

        # Check if notifications are on
        if self._gyms_enabled is False:
            self._log.debug("Gym ignored: gym notifications are disabled.")
            return

        # Doesn't look like anything to me
        if gym.new_team_id == gym.old_team_id:
            self._log.debug(
                "%s gym update skipped: no change detected", gym.gym_id)
            return

        # Calculate distance and direction
        if self.__location is not None:
            gym.distance = get_earth_dist(
                [gym.lat, gym.lng], self.__location, self.__units)
            gym.direction = get_cardinal_dir(
                [gym.lat, gym.lng], self.__location)

        # Check for Rules
        rules = self.__gym_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {"default": Rule(
                self._gym_filters.keys(), self._alarms.keys())}

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(
                gym, self._gym_filters, rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(
                    gym, rule.alarm_names, 'gym_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Gym %s passed %s rule(s) and triggered %s alarm(s).',
                gym.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Gym %s rejected by all rules.', gym.name)
Exemplo n.º 5
0
    def process_stop(self, stop):
        # type: (Events.StopEvent) -> None
        """ Process a stop event and notify alarms if it passes. """

        # Make sure that stops are enabled
        if self.__stops_enabled is False:
            log.debug("Stop ignored: stop notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.get_pokestop_expiration(stop.stop_id) is not None:
            log.debug("Stop {} was skipped because it was previously "
                      "processed.".format(stop.name))
            return
        self.__cache.update_pokestop_expiration(stop.stop_id, stop.expiration)

        # Check the time remaining
        seconds_left = (stop.expiration - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("Stop {} was skipped because only {} seconds remained"
                      "".format(stop.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            stop.distance = get_earth_dist([stop.lat, stop.lng],
                                           self.__location)
            stop.direction = get_cardinal_dir([stop.lat, stop.lng],
                                              self.__location)

        # Check the Filters
        passed = True
        for name, f in self.__stop_filters.iteritems():
            passed = f.check_event(stop) and self.check_geofences(f, stop)
            if passed:  # Stop checking
                stop.custom_dts = f.custom_dts
                break
        if not passed:  # Stop was rejected by all filters
            return

        # Generate the DTS for the event
        dts = stop.generate_dts(self.__locale, self.__timezone, self.__units)
        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location,
                                                      [stop.lat, stop.lng],
                                                      dts)

        if self.__quiet is False:
            log.info("Stop {} notification has been triggered!".format(
                stop.name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokestop_alert, dts))
        gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 6
0
    def process_stop(self, stop):
        # type: (Events.StopEvent) -> None
        """ Process a stop event and notify alarms if it passes. """

        # Make sure that stops are enabled
        if self._stops_enabled is False:
            self._log.debug("Stop ignored: stop notifications are disabled.")
            return

        # Check for lured
        if stop.expiration is None:
            self._log.debug("Stop ignored: stop was not lured")
            return

        # Check if previously processed and update expiration
        if self.__cache.stop_expiration(
                str(stop.stop_id) + str(stop.lure_type_id)) is not None:
            self._log.debug("Stop {} was skipped because it was "
                            "previously processed.".format(stop.name))
            return
        self.__cache.stop_expiration(
            str(stop.stop_id) + str(stop.lure_type_id), stop.expiration)

        # Check the time remaining
        seconds_left = (stop.expiration - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("Stop {} was skipped because only {} seconds "
                            "remained".format(stop.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            stop.distance = get_earth_dist([stop.lat, stop.lng],
                                           self.__location, self.__units)
            stop.direction = get_cardinal_dir([stop.lat, stop.lng],
                                              self.__location)

        # Check for Rules
        rules = self.__stop_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._stop_filters.keys(), self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(stop, self._stop_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(stop, rule.alarm_names, 'pokestop_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Stop %s passed %s rule(s) and triggered %s alarm(s).',
                stop.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Stop %s rejected by all rules.', stop.name)
Exemplo n.º 7
0
    def process_monster(self, mon):
        # type: (Events.MonEvent) -> None
        """ Process a monster event and notify alarms if it passes. """

        # Make sure that monsters are enabled
        if self.__mons_enabled is False:
            log.debug("Monster ignored: monster notifications are disabled.")
            return

        # Set the name for this event so we can log rejects better
        mon.name = self.__locale.get_pokemon_name(mon.monster_id)

        # Skip if previously processed
        if self.__cache.get_pokemon_expiration(mon.enc_id) is not None:
            log.debug("{} monster was skipped because it was previously "
                      "processed.".format(mon.name))
            return
        self.__cache.update_pokemon_expiration(mon.enc_id, mon.disappear_time)

        # Check the time remaining
        seconds_left = (mon.disappear_time - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("{} monster was skipped because only {} seconds remained"
                      "".format(mon.name, seconds_left))
            return

        # Calculate distance
        if self.__location is not None:
            mon.distance = get_earth_dist([mon.lat, mon.lng], self.__location)

        # Check the Filters
        passed = False
        for name, f in self.__mon_filters.iteritems():
            passed = f.check_event(mon) and self.check_geofences(f, mon)
            if passed:  # Stop checking
                mon.custom_dts = f.custom_dts
                break
        if not passed:  # Monster was rejected by all filters
            return

        # Generate the DTS for the event
        dts = mon.generate_dts(self.__locale)

        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location,
                                                      [mon.lat, mon.lng], dts)

        if self.__quiet is False:
            log.info("{} monster notification has been triggered!".format(
                mon.name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokemon_alert, dts))
        gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 8
0
    def process_monster(self, mon):
        # type: (Events.MonEvent) -> None
        """ Process a monster event and notify alarms if it passes. """

        # Make sure that monsters are enabled
        if self._mons_enabled is False:
            self._log.debug("Monster ignored: monster notifications "
                            "are disabled.")
            return

        # Set the name for this event so we can log rejects better
        mon.name = self.__locale.get_pokemon_name(mon.monster_id)

        # Check if previously processed and update expiration
        if self.__cache.monster_expiration(str(mon.enc_id) +
                                           str(mon.weight)) is not None:
            self._log.debug("{} monster was skipped because it was "
                            "previously processed.".format(mon.name))
            return
        self.__cache.monster_expiration(
            str(mon.enc_id) + str(mon.weight), mon.disappear_time)

        # Check the time remaining
        seconds_left = (mon.disappear_time - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("{} monster was skipped because only {} seconds "
                            "remained".format(mon.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            mon.distance = get_earth_dist([mon.lat, mon.lng], self.__location,
                                          self.__units)
            mon.direction = get_cardinal_dir([mon.lat, mon.lng],
                                             self.__location)

        # Check for Rules
        rules = self.__mon_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._mon_filters.keys(), self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(mon, self._mon_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(mon, rule.alarm_names, 'pokemon_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Monster %s passed %s rule(s) and triggered %s alarm(s).',
                mon.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Monster %s rejected by all rules.', mon.name)
Exemplo n.º 9
0
    def process_stop(self, stop):
        # type: (Events.StopEvent) -> None
        """ Process a stop event and notify alarms if it passes. """

        # Make sure that stops are enabled
        if self._stops_enabled is False:
            self._log.debug("Stop ignored: stop notifications are disabled.")
            return

        # Check for lured
        if stop.expiration is None:
            self._log.debug("Stop ignored: stop was not lured")
            return

        # Check if previously processed and update expiration
        if self.__cache.stop_expiration(stop.stop_id) is not None:
            self._log.debug("Stop {} was skipped because it was "
                            "previously processed.".format(stop.name))
            return
        self.__cache.stop_expiration(stop.stop_id, stop.expiration)

        # Check the time remaining
        seconds_left = (stop.expiration - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("Stop {} was skipped because only {} seconds "
                            "remained".format(stop.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            stop.distance = get_earth_dist(
                [stop.lat, stop.lng], self.__location, self.__units)
            stop.direction = get_cardinal_dir(
                [stop.lat, stop.lng], self.__location)

        # Check for Rules
        rules = self.__stop_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {"default": Rule(
                self._stop_filters.keys(), self._alarms.keys())}

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(
                stop, self._stop_filters, rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(
                    stop, rule.alarm_names, 'pokestop_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Stop %s passed %s rule(s) and triggered %s alarm(s).',
                stop.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Stop %s rejected by all rules.', stop.name)
Exemplo n.º 10
0
    def process_monster(self, mon):
        # type: (Events.MonEvent) -> None
        """ Process a monster event and notify alarms if it passes. """

        # Make sure that monsters are enabled
        if self._mons_enabled is False:
            self._log.debug("Monster ignored: monster notifications "
                            "are disabled.")
            return

        # Set the name for this event so we can log rejects better
        mon.name = self.__locale.get_pokemon_name(mon.monster_id)

        # Check if previously processed and update expiration
        if self.__cache.monster_expiration(mon.enc_id) is not None:
            self._log.debug("{} monster was skipped because it was "
                            "previously processed.".format(mon.name))
            return
        self.__cache.monster_expiration(mon.enc_id, mon.disappear_time)

        # Check the time remaining
        seconds_left = (mon.disappear_time
                        - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("{} monster was skipped because only {} seconds "
                            "remained".format(mon.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            mon.distance = get_earth_dist(
                [mon.lat, mon.lng], self.__location, self.__units)
            mon.direction = get_cardinal_dir(
                [mon.lat, mon.lng], self.__location)

        # Check for Rules
        rules = self.__mon_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._mon_filters.keys(), self._alarms.keys())}

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(
                mon, self._mon_filters, rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(
                    mon, rule.alarm_names, 'pokemon_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Monster %s passed %s rule(s) and triggered %s alarm(s).',
                mon.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Monster %s rejected by all rules.', mon.name)
Exemplo n.º 11
0
    def process_stop(self, stop):
        # type: (Events.StopEvent) -> None
        """ Process a stop event and notify alarms if it passes. """

        # Make sure that stops are enabled
        if self.__stops_enabled is False:
            log.debug("Stop ignored: stop notifications are disabled.")
            return

        # Check for lured
        if stop.expiration is None:
            log.debug("Stop ignored: stop was not lured")
            return

        # Check if previously processed and update expiration
        if self.__cache.stop_expiration(stop.stop_id) is not None:
            log.debug("Stop {} was skipped because it was previously "
                      "processed.".format(stop.name))
            return
        self.__cache.stop_expiration(stop.stop_id, stop.expiration)

        # Check the time remaining
        seconds_left = (stop.expiration - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("Stop {} was skipped because only {} seconds remained"
                      "".format(stop.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            stop.distance = get_earth_dist([stop.lat, stop.lng],
                                           self.__location, self.__units)
            stop.direction = get_cardinal_dir([stop.lat, stop.lng],
                                              self.__location)

        # Check for Rules
        rules = self.__stop_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__stop_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__stop_filters.get(f_name)
                passed = f.check_event(stop) and self.check_geofences(f, stop)
                if not passed:
                    continue  # go to next filter
                stop.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} stop notification"
                             " has been triggered in rule '{}'!"
                             "".format(stop.name, r_name))
                self._trigger_stop(stop, rule.alarm_names)
                break  # Next rule
Exemplo n.º 12
0
    def process_monster(self, mon):
        # type: (Events.MonEvent) -> None
        """ Process a monster event and notify alarms if it passes. """

        # Make sure that monsters are enabled
        if self.__mons_enabled is False:
            log.debug("Monster ignored: monster notifications are disabled.")
            return

        # Set the name for this event so we can log rejects better
        mon.name = self.__locale.get_pokemon_name(mon.monster_id)

        # Check if previously processed and update expiration
        if self.__cache.monster_expiration(mon.enc_id) is not None:
            log.debug("{} monster was skipped because it was previously "
                      "processed.".format(mon.name))
            return
        self.__cache.monster_expiration(mon.enc_id, mon.disappear_time)

        # Check the time remaining
        seconds_left = (mon.disappear_time - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("{} monster was skipped because only {} seconds remained"
                      "".format(mon.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            mon.distance = get_earth_dist([mon.lat, mon.lng], self.__location,
                                          self.__units)
            mon.direction = get_cardinal_dir([mon.lat, mon.lng],
                                             self.__location)

        # Check for Rules
        rules = self.__mon_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__mon_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__mon_filters.get(f_name)
                passed = f.check_event(mon) and self.check_geofences(f, mon)
                if not passed:
                    continue  # go to next filter
                mon.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} monster notification"
                             " has been triggered in rule '{}'!"
                             "".format(mon.name, r_name))
                self._trigger_mon(mon, rule.alarm_names)
                break  # Next rule
Exemplo n.º 13
0
    def process_quest(self, quest):
        # type: (Events.QuestEvent) -> None
        """ Process a quest event and notify alarms if it passes. """

        # Make sure that stops are enabled
        if self.__quest_enabled is False:
            log.debug("Quest ignored: quest notifications are disabled.")
            return

        # Check if previously processed and update expiration
        if self.__cache.quest_reward(quest.stop_id) is not None:
            log.debug("Quest {} was skipped because it was previously "
                      "processed.".format(quest.stop_name))
            return
        self.__cache.quest_reward(quest.stop_id, quest.reward)

        # Calculate distance and direction
        if self.__location is not None:
            quest.distance = get_earth_dist([quest.lat, quest.lng],
                                            self.__location, self.__units)
            quest.direction = get_cardinal_dir([quest.lat, quest.lng],
                                               self.__location)

        # Check for Rules
        rules = self.__quest_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__quest_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__quest_filters.get(f_name)
                passed = f.check_event(quest) and self.check_geofences(
                    f, quest)
                if not passed:
                    continue  # go to next filter
                quest.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} quest notification"
                             " has been triggered in rule '{}'!"
                             "".format(quest.stop_name, r_name))
                self._trigger_quest(quest, rule.alarm_names)
                break  # Next rule
Exemplo n.º 14
0
    def process_pokestop(self, stop):
        # Make sure that pokemon are enabled
        if self.__pokestop_settings['enabled'] is False:
            log.debug("Pokestop ignored: pokestop notifications are disabled.")
            return

        id_ = stop['id']

        # Check for previously processed
        if id_ in self.__pokestop_hist:
            log.debug(
                "Pokestop was skipped because it was previously processed.")
            return
        self.__pokestop_hist[id_] = stop['expire_time']

        # Check the time remaining
        seconds_left = (stop['expire_time'] -
                        datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info(
                    "Pokestop ({}) ignored: only {} seconds remaining.".format(
                        id_, seconds_left))
            return

        # Extract some basic information
        lat, lng = stop['lat'], stop['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        passed = False
        filters = self.__pokestop_settings['filters']
        for filt_ct in range(len(filters)):
            filt = filters[filt_ct]
            # Check the distance from the set location
            if dist != 'unkn':
                if filt.check_dist(dist) is False:
                    if self.__quiet is False:
                        log.info(
                            "Pokestop rejected: distance ({:.2f}) was not in range"
                            .format(dist) + " {:.2f} to {:.2f} (F #{})".format(
                                filt.min_dist, filt.max_dist, filt_ct))
                    continue
            else:
                log.debug(
                    "Pokestop dist was not checked because the manager has no location set."
                )

            # Nothing left to check, so it must have passed
            passed = True
            log.debug("Pokstop passed filter #{}".format(filt_ct))
            break

        if not passed:
            return

        # Check the geofences
        stop['geofence'] = self.check_geofences('Pokestop', lat, lng)
        if len(self.__geofences) > 0 and stop['geofence'] == 'unknown':
            log.info("Pokestop rejected: not within any specified geofence")
            return

        time_str = get_time_as_str(stop['expire_time'], self.__timezone)
        stop.update({
            "dist": get_dist_as_str(dist),
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
        })
        self.add_optional_travel_arguments(stop)

        if self.__quiet is False:
            log.info(
                "Pokestop ({}) notification has been triggered!".format(id_))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokestop_alert, stop))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 15
0
    def process_weather(self, weather):
        # type: (Events.WeatherEvent) -> None
        """ Process a weather event and notify alarms if it passes. """

        # Set the name for this event so we can log rejects better
        weather.name = self.__locale.get_weather_name(weather.s2_cell_id)

        # Make sure that weather changes are enabled
        if self._weather_enabled is False:
            self._log.debug("Weather ignored: weather change "
                            "notifications are disabled.")
            return

        # Calculate distance and direction
        if self.__location is not None:
            weather.distance = get_earth_dist([weather.lat, weather.lng],
                                              self.__location, self.__units)
            weather.direction = get_cardinal_dir([weather.lat, weather.lng],
                                                 self.__location)

        # Store copy of cache info
        cache_weather_id = self.__cache.cell_weather_id(weather.s2_cell_id)
        cache_day_or_night_id = self.__cache.day_or_night_id(
            weather.s2_cell_id)
        cache_severity_id = self.__cache.severity_id(weather.s2_cell_id)

        # Update cache info
        self.__cache.cell_weather_id(weather.s2_cell_id, weather.weather_id)
        self.__cache.day_or_night_id(weather.s2_cell_id,
                                     weather.day_or_night_id)
        self.__cache.severity_id(weather.s2_cell_id, weather.severity_id)

        # Check and see if the weather hasn't changed and ignore
        if weather.weather_id == cache_weather_id and \
                weather.day_or_night_id == cache_day_or_night_id and \
                weather.severity_id == cache_severity_id:
            self._log.debug(
                "weather of %s, alert of %s, and day or night of %s skipped: "
                "no change detected", weather.weather_id, weather.severity_id,
                weather.day_or_night_id)
            return

        # Check for Rules
        rules = self.__weather_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._weather_filters.keys(),
                                self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(weather, self._weather_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(weather, rule.alarm_names, 'weather_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Weather %s passed %s rule(s) and triggered %s alarm(s).',
                weather.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Weather %s rejected by all rules.',
                                weather.name)
Exemplo n.º 16
0
    def process_pokemon(self, pkmn):
        # Make sure that pokemon are enabled
        if self.__pokemon_settings['enabled'] is False:
            log.debug("Pokemon ignored: pokemon notifications are disabled.")
            return

        # Extract some base information
        id_ = pkmn['id']
        pkmn_id = pkmn['pkmn_id']
        name = self.__pokemon_name[pkmn_id]

        # Check for previously processed
        if id_ in self.__pokemon_hist:
            log.debug(
                "{} was skipped because it was previously processed.".format(
                    name))
            return
        self.__pokemon_hist[id_] = pkmn['disappear_time']

        # Check the time remaining
        seconds_left = (pkmn['disappear_time'] -
                        datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info("{} ignored: Only {} seconds remaining.".format(
                    name, seconds_left))
            return

        # Check that the filter is even set
        if pkmn_id not in self.__pokemon_settings['filters']:
            if self.__quiet is False:
                log.info("{} ignored: no filters are set".format(name))
            return

        # Extract some useful info that will be used in the filters
        passed = False
        lat, lng = pkmn['lat'], pkmn['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        iv = pkmn['iv']
        def_ = pkmn['def']
        atk = pkmn['atk']
        sta = pkmn['sta']
        quick_id = pkmn['quick_id']
        charge_id = pkmn['charge_id']
        size = pkmn['size']
        gender = pkmn['gender']
        form = pkmn['form']

        filters = self.__pokemon_settings['filters'][pkmn_id]
        for filt_ct in range(len(filters)):
            filt = filters[filt_ct]

            # Check the distance from the set location
            if dist != 'unkn':
                if filt.check_dist(dist) is False:
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: distance ({:.2f}) was not in range {:.2f} to {:.2f} (F #{})"
                            .format(name, dist, filt.min_dist, filt.max_dist,
                                    filt_ct))
                    continue
            else:
                log.debug(
                    "Filter dist was not checked because the manager has no location set."
                )

            # Check the IV percent of the Pokemon
            if iv != '?':
                if not filt.check_iv(iv):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: IV percent ({:.2f}) not in range {:.2f} to {:.2f} - (F #{})"
                            .format(name, iv, filt.min_iv, filt.max_iv,
                                    filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: 'IV' information was missing (F #{})".
                        format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon IV percent was not checked because it was missing."
                )

            # Check the Attack IV of the Pokemon
            if atk != '?':
                if not filt.check_atk(atk):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Attack IV ({}) not in range {} to {} - (F #{})"
                            .format(name, atk, filt.min_atk, filt.max_atk,
                                    filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Attack IV information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'atk' was not checked because it was missing.")

            # Check the Defense IV of the Pokemon
            if def_ != '?':
                if not filt.check_def(def_):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Defense IV ({}) not in range {} to {} - (F #{})"
                            .format(name, def_, filt.min_atk, filt.max_atk,
                                    filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Defense IV information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'def' was not checked because it was missing.")

            # Check the Stamina IV of the Pokemon
            if sta != '?':
                if not filt.check_sta(sta):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Stamina IV ({}) not in range {} to {} - (F #{})."
                            .format(name, def_, filt.min_sta, filt.max_sta,
                                    filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Stamina IV information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'sta' was not checked because it was missing.")

            # Check the Quick Move of the Pokemon
            if quick_id != '?':
                if not filt.check_quick_move(quick_id):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Quick move was not correct - (F #{})"
                            .format(name, filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Quick move information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'quick_id' was not checked because it was missing."
                )

            # Check the Quick Move of the Pokemon
            if charge_id != '?':
                if not filt.check_charge_move(charge_id):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Charge move was not correct - (F #{})"
                            .format(name, filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Charge move information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'charge_id' was not checked because it was missing."
                )

            # Check for a correct move combo
            if quick_id != '?' and charge_id != '?':
                if not filt.check_moveset(quick_id, charge_id):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Moveset was not correct - (F #{})".
                            format(name, filt_ct))
                    continue
            else:  # This will probably never happen? but just to be safe...
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Moveset information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'moveset' was not checked because it was missing."
                )

            # Check for a valid size
            if size != 'unknown':
                if not filt.check_size(size):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Size ({}) was not correct - (F #{})".
                            format(name, size, filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Size information was missing - (F #{})".
                        format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'size' was not checked because it was missing.")

            # Check for a valid gender
            if gender != 'unknown':
                if not filt.check_gender(gender):
                    if self.__quiet is False:
                        log.info(
                            "{} rejected: Gender ({}) was not correct - (F #{})"
                            .format(name, gender, filt_ct))
                    continue
            else:
                if filt.ignore_missing is True:
                    log.info(
                        "{} rejected: Gender information was missing - (F #{})"
                        .format(name, filt_ct))
                    continue
                log.debug(
                    "Pokemon 'gender' was not checked because it was missing.")

            # Nothing left to check, so it must have passed
            passed = True
            log.debug("{} passed filter #{}".format(name, filt_ct))
            break

        # If we didn't pass any filters
        if not passed:
            return

        # Check all the geofences
        pkmn['geofence'] = self.check_geofences(name, lat, lng)
        if len(self.__geofences) > 0 and pkmn['geofence'] == 'unknown':
            log.info("{} rejected: not inside geofence(s)".format(name))
            return

        # Finally, add in all the extra crap we waited to calculate until now
        time_str = get_time_as_str(pkmn['disappear_time'], self.__timezone)
        # If it has a form it's an unown and append form onto name
        if form != "unset":
            name = name + " - " + form
        pkmn.update({
            'pkmn': name,
            "dist": get_dist_as_str(dist) if dist != 'unkn' else 'unkn',
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
            'iv_0': "{:.0f}".format(iv) if iv != '?' else '?',
            'iv': "{:.1f}".format(iv) if iv != '?' else '?',
            'iv_2': "{:.2f}".format(iv) if iv != '?' else '?',
            'quick_move': self.__move_name.get(quick_id, 'unknown'),
            'charge_move': self.__move_name.get(charge_id, 'unknown')
        })
        self.add_optional_travel_arguments(pkmn)

        if self.__quiet is False:
            log.info("{} notification has been triggered!".format(name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokemon_alert, pkmn))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 17
0
    def process_raid(self, raid):
        # type: (Events.RaidEvent) -> None
        """ Process a raid event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        raid.gym_name = self.__cache.gym_name(raid.gym_id, raid.gym_name)
        raid.gym_description = self.__cache.gym_desc(raid.gym_id,
                                                     raid.gym_description)
        raid.gym_image = self.__cache.gym_image(raid.gym_id, raid.gym_image)

        # Update Team if Unknown
        if Unknown.is_(raid.current_team_id):
            raid.current_team_id = self.__cache.gym_team(raid.gym_id)

        # Make sure that raids are enabled
        if self.__raids_enabled is False:
            log.debug("Raid ignored: raid notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.raid_expiration(raid.gym_id) is not None:
            log.debug("Raid {} was skipped because it was previously "
                      "processed.".format(raid.name))
            return
        self.__cache.raid_expiration(raid.gym_id, raid.raid_end)

        # Check the time remaining
        seconds_left = (raid.raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("Raid {} was skipped because only {} seconds remained"
                      "".format(raid.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            raid.distance = get_earth_dist([raid.lat, raid.lng],
                                           self.__location, self.__units)
            raid.direction = get_cardinal_dir([raid.lat, raid.lng],
                                              self.__location)

        # Check for Rules
        rules = self.__raid_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self.__raid_filters.keys(),
                                self.__alarms.keys())
            }

        for r_name, rule in rules.iteritems():  # For all rules
            for f_name in rule.filter_names:  # Check Filters in Rules
                f = self.__raid_filters.get(f_name)
                passed = f.check_event(raid) and self.check_geofences(f, raid)
                if not passed:
                    continue  # go to next filter
                raid.custom_dts = f.custom_dts
                if self.__quiet is False:
                    log.info("{} raid notification"
                             " has been triggered in rule '{}'!"
                             "".format(raid.name, r_name))
                self._trigger_raid(raid, rule.alarm_names)
                break  # Next rule
Exemplo n.º 18
0
    def process_raid(self, raid):
        # type: (Events.RaidEvent) -> None
        """ Process a raid event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        raid.gym_name = self.__cache.gym_name(raid.gym_id, raid.gym_name)
        raid.gym_description = self.__cache.gym_desc(raid.gym_id,
                                                     raid.gym_description)
        raid.gym_image = self.__cache.gym_image(raid.gym_id, raid.gym_image)

        # Update Team if Unknown
        if Unknown.is_(raid.current_team_id):
            raid.current_team_id = self.__cache.gym_team(raid.gym_id)

        # Make sure that raids are enabled
        if self._raids_enabled is False:
            self._log.debug("Raid ignored: raid notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.raid_expiration(raid.gym_id) is not None:
            self._log.debug("Raid {} was skipped because it was "
                            "previously processed.".format(raid.name))
            return
        self.__cache.raid_expiration(raid.gym_id, raid.raid_end)

        # Check the time remaining
        seconds_left = (raid.raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("Raid {} was skipped because only {} seconds "
                            "remained".format(raid.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            raid.distance = get_earth_dist([raid.lat, raid.lng],
                                           self.__location, self.__units)
            raid.direction = get_cardinal_dir([raid.lat, raid.lng],
                                              self.__location)

        # Check for Rules
        rules = self.__raid_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._raid_filters.keys(), self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(raid, self._raid_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(raid, rule.alarm_names, 'raid_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Raid %s passed %s rule(s) and triggered %s alarm(s).',
                raid.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Raid %s rejected by all rules.', raid.name)
Exemplo n.º 19
0
    def process_gym(self, gym):
        # type: (Events.GymEvent) -> None
        """ Process a gym event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        self.__cache.update_gym_info(
            gym.gym_id, gym.gym_name, gym.gym_description, gym.gym_image)

        # Ignore changes to neutral
        if self.__ignore_neutral and gym.new_team_id == 0:
            log.debug("%s gym update skipped: new team was neutral")
            return

        # Get the old team and update new team
        gym.old_team_id = self.__cache.get_gym_team(gym.gym_id)
        self.__cache.update_gym_team(gym.gym_id, gym.new_team_id)

        # Check if notifications are on
        if self.__gyms_enabled is False:
            log.debug("Gym ignored: gym notifications are disabled.")
            return

        # Update the cache with the gyms info
        info = self.__cache.get_gym_info(gym.gym_id)
        gym.gym_name = info['name']
        gym.gym_description = info['description']
        gym.gym_image = info['url']

        # Doesn't look like anything to me
        if gym.new_team_id == gym.old_team_id:
            log.debug("%s gym update skipped: no change detected", gym.gym_id)
            return

        # Calculate distance and direction
        if self.__location is not None:
            gym.distance = get_earth_dist(
                [gym.lat, gym.lng], self.__location)
            gym.direction = get_cardinal_dir(
                [gym.lat, gym.lng], self.__location)

        # Check the Filters
        passed = True
        for name, f in self.__gym_filters.iteritems():
            passed = f.check_event(gym) and self.check_geofences(f, gym)
            if passed:  # Stop checking
                gym.custom_dts = f.custom_dts
                break
        if not passed:  # Gym was rejected by all filters
            return

        # Generate the DTS for the event
        dts = gym.generate_dts(self.__locale)
        dts.update(self.__cache.get_gym_info(gym.gym_id))  # update gym info
        if self.__loc_service:
            self.__loc_service.add_optional_arguments(
                self.__location, [gym.lat, gym.lng], dts)

        if self.__quiet is False:
            log.info(
                "{} gym notification has been triggered!".format(gym.name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.gym_alert, dts))
        gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 20
0
    def process_raid(self, raid):
        # Quick check for enabled
        if self.__raid_settings['enabled'] is False:
            log.debug("Raid ignored: notifications are disabled.")
            return

        gym_id = raid['id']

        pkmn_id = raid['pkmn_id']
        raid_end = raid['raid_end']

# DMS gym control reporting *************************************************************************************

        gteam = self.__gym_hist.get(gym_id)
        log.info("DMS Raid gym control team number:{}".format(gteam))
        
        if gteam == 1:
            gteamname = "Mystic"
        elif gteam == 2:
            gteamname = 'Valor'
        elif gteam  == 3:
            gteamname = 'Instinct'
        else:
            gteamname = 'Unknown/None'            
        
        log.info("DMS Raid gym control team string:{}".format(gteamname))

        #to_team_id = gym['new_team_id']
        #cur_team = self.__team_name[to_team_id]
#        gteam = gym_inf['new_team']
#        log.info("Raid gym control team:{}".format(gteam))

# DMS *************************************************************************************

# begin DMS eliminate raids in Great America  *************************************************************************************

        gname = self.__gym_info.get(gym_id, {}).get('name', 'unknown')
        log.info("DMS raid gym name {}".format(gname))

        if gname=='Ornate Elevated Vase':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA Ornate Elevated Vase".format(gname))
            return

        if gname=='The Demon':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA The Demon".format(gname))
            return

        if gname=='Frog Leg Pinwheel':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA Frog Leg Pinwheel".format(gname))
            return

        if gname=='On the Mic Karaoke':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA On the Mic Karaoke".format(gname))
            return

        if gname=='Boomerang Bay Torches':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA Boomerang Bay Torches".format(gname))
            return

        if gname=='Water Mushrooms':
            if self.__quiet is False:
                log.info("Raid on {} ignored: GA Water Mushrooms".format(gname))
            return

        if gname=='Castaway Creek':
            if self.__quiet is False:
                log.info("DMS Raid on {} ignored: GA Castaway Creek".format(gname))
            return
        
# end DMS changes *************************************************************************************

        # raid history will contain the end date and also the pokemon if it has hatched
        if gym_id in self.__raid_hist:
            old_raid_end = self.__raid_hist[gym_id]['raid_end']
            old_raid_pkmn = self.__raid_hist[gym_id].get('pkmn_id', 0)
            if old_raid_end == raid_end:
                if old_raid_pkmn == pkmn_id:  # raid with same end time exists and it has same pokemon id, skip it
                    if self.__quiet is False:
                        log.info("Raid {} ignored. Was previously processed.".format(gym_id))
                    return

        self.__raid_hist[gym_id] = dict(raid_end=raid_end, pkmn_id=pkmn_id)

        # don't alert about expired raids
        seconds_left = (raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info("Raid {} ignored. Only {} seconds left.".format(gym_id, seconds_left))
            return

        lat, lng = raid['lat'], raid['lng']
        dist = get_earth_dist([lat, lng], self.__location)

        # Check if raid is in geofences
        raid['geofence'] = self.check_geofences('Raid', lat, lng)
        if len(self.__geofences) > 0 and raid['geofence'] == 'unknown':
            if self.__quiet is False:
                log.info("Raid {} ignored: located outside geofences.".format(gym_id))
            return
        else:
            log.debug("Raid inside geofence was not checked because no geofences were set.")

        quick_id = raid['quick_id']
        charge_id = raid['charge_id']

        #  check filters for pokemon
        name = self.__locale.get_pokemon_name(pkmn_id)

        if pkmn_id not in self.__raid_settings['filters']:
            if self.__quiet is False:
                log.info("Raid on {} ignored: no filters are set".format(name))
            return

        raid_pkmn = {
            'pkmn': name,
            'cp': raid['cp'],
            'iv': 100,
            'level': 20,
            'def': 15,
            'atk': 15,
            'sta': 15,
            'gender': 'unknown',
            'size': 'unknown',
            'form_id': '?',
            'quick_id': quick_id,
            'charge_id': charge_id
        }

        filters = self.__raid_settings['filters'][pkmn_id]
        passed = self.check_pokemon_filter(filters, raid_pkmn, dist)
        # If we didn't pass any filters
        if not passed:
            log.debug("Raid {} did not pass pokemon check".format(gym_id))
            return

        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location, [lat, lng], raid)

        if self.__quiet is False:
            log.info("Raid ({}) notification has been triggered!".format(gym_id))

        time_str = get_time_as_str(raid['raid_end'], self.__timezone)
        start_time_str = get_time_as_str(raid['raid_begin'], self.__timezone)

        gym_info = self.__gym_info.get(gym_id, {})

        raid.update({
            'pkmn': name,
            "gym_name": gym_info.get('name', 'unknown'),
            "gym_description": gym_info.get('description', 'unknown'),
            "gym_url": gym_info.get('url', 'https://raw.githubusercontent.com/RocketMap/PokeAlarm/master/icons/gym_0.png'),
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'begin_time_left': start_time_str[0],
            'begin_12h_time': start_time_str[1],
#DMS raid gym control reporting hack            '24h_time': time_str[2],            
            '24h_time': gteamname,
            "dist": get_dist_as_str(dist),
            'dir': get_cardinal_dir([lat, lng], self.__location),
            'quick_move': self.__locale.get_move_name(quick_id),
            'charge_move': self.__locale.get_move_name(charge_id),
            'form': self.__locale.get_form_name(pkmn_id, raid_pkmn['form_id'])
        })

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.raid_alert, raid))

            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 21
0
    def handle_pokestop(self, stop):
        # Quick check for enabled
        if self.__pokestop_filter['enabled'] is False:
            log.debug("Pokestop ignored: notifications are disabled.")
            return

        id_ = stop['id']

        # Check for previously processed (and make sure previous lure hasn't expired)
        if id_ in self.__pokestop_hist and self.__pokestop_hist[
                id_] >= datetime.utcnow():
            if config['QUIET'] is False:
                log.debug(
                    "Pokestop ({}) ignored: because it was previously notified."
                    .format(id_))
            return

        self.__pokestop_hist[id_] = expire_time = stop['expire_time']

        # Check the time remaining
        seconds_left = (expire_time - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if config['QUIET'] is False:
                log.info(
                    "Pokestop ({}) ignored: only {} seconds remaining.".format(
                        id_, seconds_left))
            return

        filt = self.__pokestop_filter

        # Check the distance from the set location
        lat, lng = stop['lat'], stop['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        if dist != 'unkn':
            if dist < filt['min_dist'] or filt['max_dist'] < dist:
                if config['QUIET'] is False:
                    log.info(
                        "Pokestop ({}) ignored: distance was not in range {:.2f} to {:.2f}."
                        .format(id_, filt['min_dist'], filt['max_dist']))
                return
        else:
            log.debug(
                "Pokestop distance was not checked because no location was set."
            )

        # Check if in geofences
        if len(self.__geofences) > 0:
            inside = False
            for gf in self.__geofences:
                inside |= gf.contains(lat, lng)
            if not inside:
                if config['QUIET'] is False:
                    log.info("Pokestop ignored: located outside geofences.")
                return
        else:
            log.debug(
                "Pokestop inside geofences was not checked because no geofences were set."
            )

        time_str = get_time_as_str(expire_time, self.__timezone)
        stop.update({
            "dist": get_dist_as_str(dist) if dist != 'unkn' else 'unkn',
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
        })

        # Optional Stuff
        self.optional_arguments(stop)
        if config['QUIET'] is False:
            log.info(
                "Pokestop ({}) notification has been triggered!".format(id_))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokestop_alert, stop))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 22
0
    def handle_gym(self, gym):
        # Quick check for enabled
        if self.__gym_filter['enabled'] is False:
            log.debug("Gym ignored: notifications are disabled.")
            return
        log.debug("Gyms set to {}.".format(self.__gym_filter['enabled']))

        id_ = gym['id']
        team_id = gym['team_id']
        old_team = self.__gym_hist.get(id_)

        # Ignore gyms when there is no change
        if old_team == team_id:
            log.debug("Gym update ignored: team didn't change")
            return

        # Ignore changes to neutral
        if self.__gym_filter['ignore_neutral'] and team_id == 0:
            log.debug("Gym update ignored: changed to neutral")
            return

        self.__gym_hist[id_] = team_id

        # Ignore first time updates
        if old_team is None:
            log.debug("Gym update ignored: first time seeing gym")
            return

        if old_team not in self.__gym_filter and team_id not in self.__gym_filter:
            if config['QUIET'] is False:
                log.info("Gym update ignored: neither team is enabled")
            return

        lat, lng = gym['lat'], gym['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        if dist != 'unkn':
            old_range, new_range = False, False
            old_f = self.__gym_filter.get(old_team)
            if old_f is not None:
                old_range = old_f['min_dist'] <= dist <= old_f['max_dist']
            new_f = self.__gym_filter.get(team_id)
            if new_f is not None:
                new_range = new_f['min_dist'] <= dist <= new_f['max_dist']
            if old_range is False and new_range is False:
                if config['QUIET'] is False:
                    log.info("Gym update ignored: both teams outside range")
                return
        else:
            log.debug(
                "Gym distance was not checked because no location was set.")

        # Check if in geofences
        if len(self.__geofences) > 0:
            inside = False
            for gf in self.__geofences:
                inside |= gf.contains(lat, lng)
            if inside is False:
                if config['QUIET'] is False:
                    log.info("Gym update ignored: located outside geofences.")
                return
        else:
            log.debug(
                "Gym inside geofences was not checked because no geofences were set."
            )

        # Optional Stuff
        self.optional_arguments(gym)
        if config['QUIET'] is False:
            log.info("Gym ({}) notification has been triggered!".format(id_))

        gym.update({
            "dist": get_dist_as_str(dist) if dist != 'unkn' else 'unkn',
            'new_team': self.__team_name[team_id],
            'old_team': self.__team_name[old_team],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
        })

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.gym_alert, gym))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 23
0
    def process_raid(self, raid):
        # Quick check for enabled
        if self.__raid_settings['enabled'] is False:
            log.debug("Raid ignored: notifications are disabled.")
            return

        gym_id = raid['id']

        pkmn_id = raid['pkmn_id']
        raid_end = raid['raid_end']

        # raid history will contain the end date and also the pokemon if it has hatched
        if gym_id in self.__raid_hist:
            old_raid_end = self.__raid_hist[gym_id]['raid_end']
            old_raid_pkmn = self.__raid_hist[gym_id].get('pkmn_id', 0)
            if old_raid_end == raid_end:
                if old_raid_pkmn == pkmn_id:  # raid with same end time exists and it has same pokemon id, skip it
                    if self.__quiet is False:
                        log.info("Raid {} ignored. Was previously processed.".
                                 format(gym_id))
                    return

        self.__raid_hist[gym_id] = dict(raid_end=raid_end, pkmn_id=pkmn_id)

        # don't alert about expired raids
        seconds_left = (raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info("Raid {} ignored. Only {} seconds left.".format(
                    gym_id, seconds_left))
            return

        lat, lng = raid['lat'], raid['lng']
        dist = get_earth_dist([lat, lng], self.__location)

        # Check if raid is in geofences
        raid['geofence'] = self.check_geofences('Raid', lat, lng)
        if len(self.__geofences) > 0 and raid['geofence'] == 'unknown':
            if self.__quiet is False:
                log.info("Raid {} ignored: located outside geofences.".format(
                    gym_id))
            return
        else:
            log.debug(
                "Raid inside geofence was not checked because no geofences were set."
            )

        quick_id = raid['quick_id']
        charge_id = raid['charge_id']

        #  check filters for pokemon
        name = self.__locale.get_pokemon_name(pkmn_id)

        if pkmn_id not in self.__raid_settings['filters']:
            if self.__quiet is False:
                log.info("Raid on {} ignored: no filters are set".format(name))
            return

        raid_pkmn = {
            'pkmn': name,
            'cp': raid['cp'],
            'iv': 100,
            'level': 20,
            'def': 15,
            'atk': 15,
            'sta': 15,
            'gender': 'unknown',
            'size': 'unknown',
            'form_id': '?',
            'quick_id': quick_id,
            'charge_id': charge_id
        }

        filters = self.__raid_settings['filters'][pkmn_id]
        passed = self.check_pokemon_filter(filters, raid_pkmn, dist)
        # If we didn't pass any filters
        if not passed:
            log.debug("Raid {} did not pass pokemon check".format(gym_id))
            return

        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location,
                                                      [lat, lng], raid)

        if self.__quiet is False:
            log.info(
                "Raid ({}) notification has been triggered!".format(gym_id))

        time_str = get_time_as_str(raid['raid_end'], self.__timezone)
        start_time_str = get_time_as_str(raid['raid_begin'], self.__timezone)

        gym_info = self.__gym_info.get(gym_id, {})

        raid.update({
            'pkmn':
            name,
            #"gym_name": self.__gym_info.get(gym_id, {}).get('name', 'unknown'),
            #"gym_description": self.__gym_info.get(gym_id, {}).get('description', 'unknown'),
            #"gym_url": self.__gym_info.get(gym_id, {}).get('url', 'https://raw.githubusercontent.com/kvangent/PokeAlarm/master/icons/gym_0.png'),
            'time_left':
            time_str[0],
            '12h_time':
            time_str[1],
            '24h_time':
            time_str[2],
            'begin_time_left':
            start_time_str[0],
            'begin_12h_time':
            start_time_str[1],
            'begin_24h_time':
            start_time_str[2],
            "dist":
            get_dist_as_str(dist),
            'quick_move':
            self.__locale.get_move_name(quick_id),
            'charge_move':
            self.__locale.get_move_name(charge_id),
            #'team': self.__team_name[raid['team_id']],
            'dir':
            get_cardinal_dir([lat, lng], self.__location),
            'form':
            self.__locale.get_form_name(pkmn_id, raid_pkmn['form_id'])
        })

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.raid_alert, raid))

            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 24
0
    def handle_pokemon(self, pkmn):
        # Quick check for enabled
        if self.__pokemon_filter['enabled'] is False:
            log.debug("Pokemon ignored: notifications are disabled.")
            return

        id_ = pkmn['id']
        pkmn_id = pkmn['pkmn_id']
        name = self.__pokemon_name[pkmn_id]

        # Check for previously processed
        if id_ in self.__pokemon_hist:
            if config['QUIET'] is False:
                log.debug(
                    "{} was skipped because it was previously processed.".
                    format(name))
            return
        self.__pokemon_hist[id_] = pkmn['disappear_time']

        # Check that the filter is set
        if pkmn_id not in self.__pokemon_filter:
            if config['QUIET'] is False:
                log.info("{} ignored: filter was not set".format(name))
                return

        # Check the time remaining
        seconds_left = (pkmn['disappear_time'] -
                        datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if config['QUIET'] is False:
                log.info("{} ignored: {} seconds remaining.".format(
                    name, seconds_left))
            return

        filt = self.__pokemon_filter[pkmn_id]

        # Check the distance from the set location
        lat, lng = pkmn['lat'], pkmn['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        if dist != 'unkn':
            if dist < filt['min_dist'] or filt['max_dist'] < dist:
                if config['QUIET'] is False:
                    log.info(
                        "{} ignored: distance ({:.2f}) was not in range {:.2f} to {:.2f}."
                        .format(name, dist, filt['min_dist'],
                                filt['max_dist']))
                return
        else:
            log.debug(
                "Pokemon dist was not checked because no location was set.")

        # Check the IV's of the Pokemon
        iv = pkmn['iv']
        if iv != 'unkn':
            if iv < filt['min_iv'] or filt['max_iv'] < iv:
                if config['QUIET'] is False:
                    log.info(
                        "{} ignored: IVs ({:.2f}) not in range {:.2f} to {:.2f}."
                        .format(name, iv, filt['min_iv'], filt['max_iv']))
                return
        else:
            log.debug(
                "Pokemon IV's were not checked because they are unknown.")
            if filt['ignore_missing'] is True:
                log.info("{} ignored: IV information was missing".format(name))
                return

        # Check the moves of the Pokemon
        move_1_id = pkmn['move_1_id']
        move_2_id = pkmn['move_2_id']
        # TODO: Move damage
        if move_1_id != 'unknown' and move_2_id != 'unknown':
            move_1_f, move_2_f, moveset_f = filt['move_1'], filt[
                'move_2'], filt['moveset']
            if move_1_f is not None and move_1_id not in move_1_f:  # Check Move 1
                if config['QUIET'] is False:
                    log.info("{} ignored: Move 1 was incorrect.".format(name))
                return
            if move_2_f is not None and move_2_id not in move_2_f:  # Check Move 2
                if config['QUIET'] is False:
                    log.info("{} ignored: Move 2 was incorrect.".format(name))
                return
            if moveset_f is not None:  # Check for movesets
                correct_moves = False
                for filt in moveset_f:
                    correct_moves |= (move_1_id in filt and move_2_id in filt)
                if correct_moves is False:  # Wrong moveset
                    if config['QUIET'] is False:
                        log.info(
                            "{} ignored: Moveset was incorrect.".format(name))
                    return
        else:
            log.debug(
                "Pokemon moves were not checked because they are unknown.")
            if filt['ignore_missing'] is True:
                log.info(
                    "{} ignored: Moves information was missing".format(name))
                return

        # Check if in geofences
        if len(self.__geofences) > 0:
            inside = False
            for gf in self.__geofences:
                inside |= gf.contains(lat, lng)
            if not inside:
                if config['QUIET'] is False:
                    log.info(
                        "{} ignored: located outside geofences.".format(name))
                return
        else:
            log.debug(
                "Pokemon inside geofences was not checked because no geofences were set."
            )

        time_str = get_time_as_str(pkmn['disappear_time'], self.__timezone)
        pkmn.update({
            'pkmn': name,
            "dist": get_dist_as_str(dist) if dist != 'unkn' else 'unkn',
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
            'iv_0': "{:.0f}".format(iv) if iv != 'unkn' else 'unkn',
            'iv': "{:.1f}".format(iv) if iv != 'unkn' else 'unkn',
            'iv_2': "{:.2f}".format(iv) if iv != 'unkn' else 'unkn',
            'move_1': self.__move_name.get(move_1_id, 'unknown'),
            'move_1_damage': get_move_damage(move_1_id),
            'move_1_dps': get_move_dps(move_1_id),
            'move_1_duration': get_move_duration(move_1_id),
            'move_1_energy': get_move_energy(move_1_id),
            'move_2': self.__move_name.get(move_2_id, 'unknown'),
            'move_2_damage': get_move_damage(move_2_id),
            'move_2_dps': get_move_dps(move_2_id),
            'move_2_duration': get_move_duration(move_2_id),
            'move_2_energy': get_move_energy(move_2_id)
        })
        # Optional Stuff
        self.optional_arguments(pkmn)
        if config['QUIET'] is False:
            log.info("{} notification has been triggered!".format(name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokemon_alert, pkmn))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 25
0
    def process_gym(self, gym):
        gym_id = gym['id']

        # Update Gym details (if they exist)
        if gym_id not in self.__gym_info or gym['name'] != 'unknown':
            self.__gym_info[gym_id] = {
                "name": gym['name'],
                "description": gym['description'],
                "url": gym['url']
            }
            
# DMS raid control reporting********************************************************************
            to_team_id = gym['new_team_id']
            # Update gym's last known team
            self.__gym_hist[gym_id] = to_team_id
# DMS raid control reporting *********************************************************************

        if self.__gym_settings['enabled'] is False:
            log.debug("Gym ignored: notifications are disabled.")
            return

        # Extract some basic information
        to_team_id = gym['new_team_id']
        from_team_id = self.__gym_hist.get(gym_id)

        # Doesn't look like anything to me
        if to_team_id == from_team_id:
            log.debug("Gym ignored: no change detected")
            return
        # Ignore changes to neutral
        if self.__gym_settings['ignore_neutral'] and to_team_id == 0:
            log.debug("Gym update ignored: changed to neutral")
            return
        # Update gym's last known team
        self.__gym_hist[gym_id] = to_team_id

        # Ignore first time updates
        if from_team_id is None:
            log.debug("Gym update ignored: first time seeing this gym")
            return

        # Get some more info out used to check filters
        lat, lng = gym['lat'], gym['lng']
        dist = get_earth_dist([lat, lng], self.__location)
        cur_team = self.__locale.get_team_name(to_team_id)
        old_team = self.__locale.get_team_name(from_team_id)

        filters = self.__gym_settings['filters']
        passed = False
        for filt_ct in range(len(filters)):
            filt = filters[filt_ct]
            # Check the distance from the set location
            if dist != 'unkn':
                if filt.check_dist(dist) is False:
                    if self.__quiet is False:
                        log.info("Gym rejected: distance ({:.2f}) was not in range" +
                                 " {:.2f} to {:.2f} (F #{})".format(dist, filt.min_dist, filt.max_dist, filt_ct))
                    continue
            else:
                log.debug("Gym dist was not checked because the manager has no location set.")

            # Check the old team
            if filt.check_from_team(from_team_id) is False:
                if self.__quiet is False:
                    log.info("Gym rejected: {} as old team is not correct (F #{})".format(old_team, filt_ct))
                continue
            # Check the new team
            if filt.check_to_team(to_team_id) is False:
                if self.__quiet is False:
                    log.info("Gym rejected: {} as current team is not correct (F #{})".format(cur_team, filt_ct))
                continue

            # Nothing left to check, so it must have passed
            passed = True
            log.debug("Gym passed filter #{}".format(filt_ct))
            break

        if not passed:
            return

        # Check the geofences
        gym['geofence'] = self.check_geofences('Gym', lat, lng)
        if len(self.__geofences) > 0 and gym['geofence'] == 'unknown':
            log.info("Gym rejected: not inside geofence(s)")
            return

        # Check if in geofences
        if len(self.__geofences) > 0:
            inside = False
            for gf in self.__geofences:
                inside |= gf.contains(lat, lng)
            if inside is False:
                if self.__quiet is False:
                    log.info("Gym update ignored: located outside geofences.")
                return
        else:
            log.debug("Gym inside geofences was not checked because no geofences were set.")

        gym_info = self.__gym_info.get(gym_id, {})

        gym.update({
            "gym_name": gym_info.get('name', 'unknown'),
            "gym_description": gym_info.get('description', 'unknown'),
            "gym_url": gym_info.get('url', 'https://raw.githubusercontent.com/RocketMap/PokeAlarm/master/icons/gym_0.png'),
            "dist": get_dist_as_str(dist),
            'dir': get_cardinal_dir([lat, lng], self.__location),
            'new_team': cur_team,
            'new_team_id': to_team_id,
            'old_team': old_team,
            'old_team_id': from_team_id,
            'new_team_leader': self.__locale.get_leader_name(to_team_id),
            'old_team_leader': self.__locale.get_leader_name(from_team_id)
        })
        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location, [lat, lng], gym)

        if self.__quiet is False:
            log.info("Gym ({}) notification has been triggered!".format(gym_id))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.gym_alert, gym))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 26
0
    def process_raid(self, raid):
        # Make sure that pokemon are enabled
        if self.__raid_settings['enabled'] is False:
            log.debug("Raid ignored: raid notifications are disabled.")
            return

        id_ = raid['id']

        # Check for previously processed
        if id_ in self.__raid_hist:
            log.debug("Raid was skipped because it was previously processed.")
            return

        # Ignore if the Pokemon ID is still missing (it is an egg).
        # Store the raid start time in this case.
        if raid['pkmn_id'] == '?':
            log.info("Raid ({}) ignored: No pokemon exists.".format(id_))
            return

        else:
            # Store the raid end time and continue processing
            self.__raid_hist[id_] = raid['raid_end']

        # Extract some useful info that will be used in the filters
        passed = False
        lat, lng = raid['lat'], raid['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        level = raid['level']
        pkmn_id = raid['pkmn_id']
        name = self.__pokemon_name[pkmn_id]

        filters = self.__raid_settings['filters']
        for filt_ct in range(len(filters)):
            filt = filters[filt_ct]
            # Check the distance from the set location
            if dist != 'unkn':
                if filt.check_dist(dist) is False:
                    if self.__quiet is False:
                        log.info(
                            "Raid rejected: distance ({:.2f}) was not in range"
                            .format(dist) + " {:.2f} to {:.2f} (F #{})".format(
                                filt.min_dist, filt.max_dist, filt_ct))
                    continue
            else:
                log.debug(
                    "Raid dist was not checked because the manager has no location set."
                )

            if not filt.check_level(level):
                if self.__quiet is False:
                    log.info(
                        "Raid rejected: Level ({}) not in range {} to {} - (F #{})"
                        .format(level, filt.min_level, filt.max_level,
                                filt_ct))
                continue

            # Nothing left to check, so it must have passed
            passed = True
            log.debug("Raid passed filter #{}".format(filt_ct))
            break

        if not passed:
            return

        # Check the geofences
        raid['geofence'] = self.check_geofences('Raid', lat, lng)
        if len(self.__geofences) > 0 and raid['geofence'] == 'unknown':
            log.info("Raid rejected: not within any specified geofence")
            return

        time_str = get_time_as_str(raid['raid_end'], self.__timezone)
        raid.update({
            "dist": get_dist_as_str(dist),
            'pkmn': name,
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
        })
        self.add_optional_travel_arguments(raid)

        if self.__quiet is False:
            log.info("Raid ({}/{}) notification has been triggered!".format(
                id_, name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.raid_alert, raid))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 27
0
    def process_pokemon(self, pkmn):
        # Make sure that pokemon are enabled
        if self.__pokemon_settings['enabled'] is False:
            log.debug("Pokemon ignored: pokemon notifications are disabled.")
            return

        # Extract some base information
        id_ = pkmn['id']
        pkmn_id = pkmn['pkmn_id']
        name = self.__locale.get_pokemon_name(pkmn_id)

        # Check for previously processed
        if id_ in self.__pokemon_hist:
            log.debug(
                "{} was skipped because it was previously processed.".format(
                    name))
            return
        self.__pokemon_hist[id_] = pkmn['disappear_time']

        # Check the time remaining
        seconds_left = (pkmn['disappear_time'] -
                        datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info("{} ignored: Only {} seconds remaining.".format(
                    name, seconds_left))
            return

        # Check that the filter is even set
        if pkmn_id not in self.__pokemon_settings['filters']:
            if self.__quiet is False:
                log.info("{} ignored: no filters are set".format(name))
            return

        # Extract some useful info that will be used in the filters

        lat, lng = pkmn['lat'], pkmn['lng']
        dist = get_earth_dist([lat, lng], self.__location)
        form_id = pkmn.get('form_id', 0)
        if form_id == '?':
            form_id = 0

        pkmn['pkmn'] = name

        filters = self.__pokemon_settings['filters'][pkmn_id]
        passed = self.check_pokemon_filter(filters, pkmn, dist)
        # If we didn't pass any filters
        if not passed:
            return

        quick_id = pkmn['quick_id']
        charge_id = pkmn['charge_id']
        weather_id = pkmn['weather']

        # Check all the geofences
        pkmn['geofence'] = self.check_geofences(name, lat, lng)
        if len(self.__geofences) > 0 and pkmn['geofence'] == 'unknown':
            log.info("{} rejected: not inside geofence(s)".format(name))
            return

        # Finally, add in all the extra crap we waited to calculate until now
        time_str = get_time_as_str(pkmn['disappear_time'], self.__timezone)
        iv = pkmn['iv']

        pkmn.update({
            'pkmn':
            name,
            "dist":
            get_dist_as_str(dist) if dist != 'unkn' else 'unkn',
            'time_left':
            time_str[0],
            '12h_time':
            time_str[1],
            '24h_time':
            time_str[2],
            'dir':
            get_cardinal_dir([lat, lng], self.__location),
            'iv_0':
            "{:.0f}".format(iv) if iv != '?' else '?',
            'iv':
            "{:.1f}".format(iv) if iv != '?' else '?',
            'iv_2':
            "{:.2f}".format(iv) if iv != '?' else '?',
            'quick_move':
            self.__locale.get_move_name(quick_id),
            'charge_move':
            self.__locale.get_move_name(charge_id),
            'form_id':
            (chr(64 + int(form_id))) if form_id and int(form_id) > 0 else '',
            'weather':
            self.__locale.get_weather_name(weather_id)
        })
        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location,
                                                      [lat, lng], pkmn)

        if self.__quiet is False:
            log.info("{} notification has been triggered!".format(name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.pokemon_alert, pkmn))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 28
0
    def process_gym_details(self, gym_details):
        if self.__gym_settings['enabled'] is False:
            log.debug("Gym ignored: notifications are disabled.")
            return

        # Extract some basic information
        gym_id = gym_details['id']
        to_team_id = gym_details['team_id']
        from_team_id = self.__gym_hist.get(gym_id)

        # Doesn't look like anything to me
        if to_team_id == from_team_id:
            log.debug("Gym ignored: no change detected")
            return
        # Ignore changes to neutral
        if self.__gym_settings['ignore_neutral'] and to_team_id == 0:
            log.debug("Gym update ignored: changed to neutral")
            return
        # Update gym's last known team
        self.__gym_hist[gym_id] = to_team_id
        # Ignore first time updates
        if from_team_id is None:
            log.debug("Gym update ignored: first time seeing this gym")
            return

        # Get some more info out used to check filters
        lat, lng = gym_details['lat'], gym_details['lng']
        dist = get_earth_dist([lat, lng], self.__latlng)
        cur_team = self.__team_name[to_team_id]
        old_team = self.__team_name[from_team_id]

        filters = self.__gym_settings['filters']
        passed = False
        for filt_ct in range(len(filters)):
            filt = filters[filt_ct]
            # Check the distance from the set location
            if dist != 'unkn':
                if filt.check_dist(dist) is False:
                    if self.__quiet is False:
                        log.info(
                            "Gym rejected: distance ({:.2f}) was not in range"
                            + " {:.2f} to {:.2f} (F #{})".format(
                                dist, filt.min_dist, filt.max_dist, filt_ct))
                    continue
            else:
                log.debug(
                    "Pokestop dist was not checked because the manager has no location set."
                )

            # Check the old team
            if filt.check_from_team(from_team_id) is False:
                if self.__quiet is False:
                    log.info(
                        "Gym rejected: {} as old team is not correct (F #{})".
                        format(old_team, filt_ct))
                continue
            # Check the new team
            if filt.check_to_team(to_team_id) is False:
                if self.__quiet is False:
                    log.info(
                        "Gym rejected: {} as current team is not correct (F #{})"
                        .format(cur_team, filt_ct))
                continue

            # Nothing left to check, so it must have passed
            passed = True
            log.debug("Gym passed filter #{}".format(filt_ct))
            break

        if not passed:
            return

        # Check the geofences
        gym['geofence'] = self.check_geofences('Gym', lat, lng)
        if len(self.__geofences) > 0 and gym['geofence'] == 'unknown':
            log.info("Gym rejected: not inside geofence(s)")
            return

        # Check if in geofences
        if len(self.__geofences) > 0:
            inside = False
            for gf in self.__geofences:
                inside |= gf.contains(lat, lng)
            if inside is False:
                if self.__quiet is False:
                    log.info("Gym update ignored: located outside geofences.")
                return
        else:
            log.debug(
                "Gym inside geofences was not checked because no geofences were set."
            )

        gym_details.update({
            'name': gym_details['name'],
            "dist": get_dist_as_str(dist),
            'dir': get_cardinal_dir([lat, lng], self.__latlng),
            'new_team': cur_team,
            'old_team': old_team,
            'defenders': gym_details['defenders']
        })
        self.add_optional_travel_arguments(gym_details)

        if self.__quiet is False:
            log.info(
                "Gym ({}) notification has been triggered!".format(gym_id))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.gym_alert, gym_details))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 29
0
    def process_egg(self, egg):
        # Quick check for enabled
        if self.__egg_settings['enabled'] is False:
            log.debug("Egg ignored: notifications are disabled.")
            return

        gym_id = egg['id']

        raid_end = egg['raid_end']

        # raid history will contains any raid processed
        if gym_id in self.__raid_hist:
            old_raid_end = self.__raid_hist[gym_id]['raid_end']
            if old_raid_end == raid_end:
                if self.__quiet is False:
                    log.info(
                        "Raid {} ignored. Was previously processed.".format(
                            gym_id))
                return

        self.__raid_hist[gym_id] = dict(raid_end=raid_end, pkmn_id=0)

        # don't alert about (nearly) hatched eggs
        seconds_left = (egg['raid_begin'] - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            if self.__quiet is False:
                log.info("Egg {} ignored. Egg hatch in {} seconds".format(
                    gym_id, seconds_left))
            return

        lat, lng = egg['lat'], egg['lng']
        dist = get_earth_dist([lat, lng], self.__location)

        # Check if raid is in geofences
        egg['geofence'] = self.check_geofences('Raid', lat, lng)
        if len(self.__geofences) > 0 and egg['geofence'] == 'unknown':
            if self.__quiet is False:
                log.info("Egg {} ignored: located outside geofences.".format(
                    gym_id))
            return
        else:
            log.debug(
                "Egg inside geofence was not checked because no geofences were set."
            )

        # check if the level is in the filter range or if we are ignoring eggs
        passed = self.check_egg_filter(self.__egg_settings, egg)

        if not passed:
            log.debug("Egg {} did not pass filter check".format(gym_id))
            return

        if self.__loc_service:
            self.__loc_service.add_optional_arguments(self.__location,
                                                      [lat, lng], egg)

        if self.__quiet is False:
            log.info(
                "Egg ({}) notification has been triggered!".format(gym_id))

        time_str = get_time_as_str(egg['raid_end'], self.__timezone)
        start_time_str = get_time_as_str(egg['raid_begin'], self.__timezone)

        gym_info = self.__gym_info.get(gym_id, {})

        egg.update({
            #"gym_name": self.__gym_info.get(gym_id, {}).get('name', 'unknown'),
            #"gym_description": self.__gym_info.get(gym_id, {}).get('description', 'unknown'),
            #"gym_url": self.__gym_info.get(gym_id, {}).get('url', 'https://raw.githubusercontent.com/kvangent/PokeAlarm/master/icons/gym_0.png'),
            'time_left': time_str[0],
            '12h_time': time_str[1],
            '24h_time': time_str[2],
            'begin_time_left': start_time_str[0],
            'begin_12h_time': start_time_str[1],
            'begin_24h_time': start_time_str[2],
            "dist": get_dist_as_str(dist),
            'dir': get_cardinal_dir([lat, lng], self.__location),
            #'team': self.__team_name[egg['team_id']]
        })

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.raid_egg_alert, egg))
            gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 30
0
    def process_raid(self, raid):
        # type: (Events.RaidEvent) -> None
        """ Process a raid event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        raid.gym_name = self.__cache.gym_name(raid.gym_id, raid.gym_name)
        raid.gym_description = self.__cache.gym_desc(
            raid.gym_id, raid.gym_description)
        raid.gym_image = self.__cache.gym_image(raid.gym_id, raid.gym_image)

        # Update Team if Unknown
        if Unknown.is_(raid.current_team_id):
            raid.current_team_id = self.__cache.gym_team(raid.gym_id)

        # Make sure that raids are enabled
        if self._raids_enabled is False:
            self._log.debug("Raid ignored: raid notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.raid_expiration(raid.gym_id) is not None:
            self._log.debug("Raid {} was skipped because it was "
                            "previously processed.".format(raid.name))
            return
        self.__cache.raid_expiration(raid.gym_id, raid.raid_end)

        # Check the time remaining
        seconds_left = (raid.raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            self._log.debug("Raid {} was skipped because only {} seconds "
                            "remained".format(raid.name, seconds_left))
            return

        # Calculate distance and direction
        if self.__location is not None:
            raid.distance = get_earth_dist(
                [raid.lat, raid.lng], self.__location, self.__units)
            raid.direction = get_cardinal_dir(
                [raid.lat, raid.lng], self.__location)

        # Check for Rules
        rules = self.__raid_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {"default": Rule(
                self._raid_filters.keys(), self._alarms.keys())}

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(
                raid, self._raid_filters, rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(
                    raid, rule.alarm_names, 'raid_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Raid %s passed %s rule(s) and triggered %s alarm(s).',
                raid.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Raid %s rejected by all rules.', raid.name)
Exemplo n.º 31
0
    def process_raid(self, raid):
        # type: (Events.RaidEvent) -> None
        """ Process a raid event and notify alarms if it passes. """

        # Update Gym details (if they exist)
        self.__cache.update_gym_info(
            raid.gym_id, raid.gym_name, raid.gym_description, raid.gym_image)

        # Make sure that raids are enabled
        if self.__raids_enabled is False:
            log.debug("Raid ignored: raid notifications are disabled.")
            return

        # Skip if previously processed
        if self.__cache.get_raid_expiration(raid.gym_id) is not None:
            log.debug("Raid {} was skipped because it was previously "
                      "processed.".format(raid.name))
            return
        self.__cache.update_raid_expiration(raid.gym_id, raid.raid_end)

        # Check the time remaining
        seconds_left = (raid.raid_end - datetime.utcnow()).total_seconds()
        if seconds_left < self.__time_limit:
            log.debug("Raid {} was skipped because only {} seconds remained"
                      "".format(raid.name, seconds_left))
            return

        # Assigned cached info
        info = self.__cache.get_gym_info(raid.gym_id)
        raid.current_team_id = self.__cache.get_gym_team(raid.gym_id)
        raid.gym_name = info['name']
        raid.gym_description = info['description']
        raid.gym_image = info['url']

        # Calculate distance and direction
        if self.__location is not None:
            raid.distance = get_earth_dist(
                [raid.lat, raid.lng], self.__location)
            raid.direction = get_cardinal_dir(
                [raid.lat, raid.lng], self.__location)

        # Check the Filters
        passed = True
        for name, f in self.__raid_filters.iteritems():
            passed = f.check_event(raid) and self.check_geofences(f, raid)
            if passed:  # Stop checking
                raid.custom_dts = f.custom_dts
                break
        if not passed:  # Raid was rejected by all filters
            return

        # Generate the DTS for the event
        dts = raid.generate_dts(self.__locale)
        dts.update(self.__cache.get_gym_info(raid.gym_id))  # update gym info
        if self.__loc_service:
            self.__loc_service.add_optional_arguments(
                self.__location, [raid.lat, raid.lng], dts)

        if self.__quiet is False:
            log.info(
                "{} raid notification has been triggered!".format(raid.name))

        threads = []
        # Spawn notifications in threads so they can work in background
        for alarm in self.__alarms:
            threads.append(gevent.spawn(alarm.raid_alert, dts))
        gevent.sleep(0)  # explict context yield

        for thread in threads:
            thread.join()
Exemplo n.º 32
0
    def process_weather(self, weather):
        # type: (Events.WeatherEvent) -> None
        """ Process a weather event and notify alarms if it passes. """

        # Set the name for this event so we can log rejects better
        weather.name = self.__locale.get_weather_name(weather.s2_cell_id)

        # Make sure that weather changes are enabled
        if self._weather_enabled is False:
            self._log.debug("Weather ignored: weather change "
                            "notifications are disabled.")
            return

        # Calculate distance and direction
        if self.__location is not None:
            weather.distance = get_earth_dist(
                [weather.lat, weather.lng], self.__location, self.__units)
            weather.direction = get_cardinal_dir(
                [weather.lat, weather.lng], self.__location)

        # Store copy of cache info
        cache_weather_id = self.__cache.cell_weather_id(weather.s2_cell_id)
        cache_day_or_night_id = self.__cache.day_or_night_id(
            weather.s2_cell_id)
        cache_severity_id = self.__cache.severity_id(weather.s2_cell_id)

        # Update cache info
        self.__cache.cell_weather_id(weather.s2_cell_id,
                                     weather.weather_id)
        self.__cache.day_or_night_id(
            weather.s2_cell_id, weather.day_or_night_id)
        self.__cache.severity_id(weather.s2_cell_id, weather.severity_id)

        # Check and see if the weather hasn't changed and ignore
        if weather.weather_id == cache_weather_id and \
                weather.day_or_night_id == cache_day_or_night_id and \
                weather.severity_id == cache_severity_id:
            self._log.debug(
                "weather of %s, alert of %s, and day or night of %s skipped: "
                "no change detected",
                weather.weather_id, weather.severity_id,
                weather.day_or_night_id)
            return

        # Check for Rules
        rules = self.__weather_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {"default": Rule(
                self._weather_filters.keys(), self._alarms.keys())}

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(
                weather, self._weather_filters, rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(
                    weather, rule.alarm_names, 'weather_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Weather %s passed %s rule(s) and triggered %s alarm(s).',
                weather.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info(
                'Weather %s rejected by all rules.', weather.name)
Exemplo n.º 33
0
    def process_quest(self, quest):
        # type: (Events.QuestEvent) -> None
        """ Process a quest event and notify alarms if it passes. """

        # Set the name for this event so we can log rejects better
        quest.name = quest.stop_id

        # Make sure that quest changes are enabled
        if self._quest_enabled is False:
            self._log.debug("Quest ignored: quest notifications are disabled.")
            return

        # Calculate distance and direction
        if self.__location is not None:
            quest.distance = get_earth_dist([quest.lat, quest.lng],
                                            self.__location, self.__units)
            quest.direction = get_cardinal_dir([quest.lat, quest.lng],
                                               self.__location)

        # Store a copy of cache info
        previous_modified = self.__cache.quest_expiration(quest.stop_id)

        # Check if previously processed
        if self.__cache.quest_expiration(quest.stop_id, quest.last_modified)\
                == previous_modified:
            self._log.debug("Quest {} was skipped because it was "
                            "previously processed.".format(quest.name))
            return

        # Check against previous copy from cache
        previous_reward, previous_task, last_modified = \
            self.__cache.quest_reward(quest.stop_id)
        if quest.reward_type_raw == previous_reward \
                and quest.quest_type_raw == previous_task:
            self._log.debug("Quest ignored: Reward previously alerted!")
            return

        # Update cache info
        self.__cache.quest_reward(quest.stop_id, quest.reward_type_raw,
                                  quest.quest_type_raw)

        # Check for Rules
        rules = self.__quest_rules
        if len(rules) == 0:  # If no rules, default to all
            rules = {
                "default": Rule(self._quest_filters.keys(),
                                self._alarms.keys())
            }

        rule_ct, alarm_ct = 0, 0
        for r_name, rule in rules.iteritems():  # For all rules
            passed = self._check_filters(quest, self._quest_filters,
                                         rule.filter_names)
            if passed:
                rule_ct += 1
                alarm_ct += len(rule.alarm_names)
                self._notify_alarms(quest, rule.alarm_names, 'quest_alert')

        if rule_ct > 0:
            self._rule_log.info(
                'Quest %s passed %s rule(s) and triggered %s alarm(s).',
                quest.name, rule_ct, alarm_ct)
        else:
            self._rule_log.info('Quest %s rejected by all rules.', quest.name)