コード例 #1
0
ファイル: sun.py プロジェクト: gacbert/accent
class Sun(object):
    """A wrapper around a calculator for sunrise and sunset times."""
    def __init__(self, geocoder):
        self.astral = Astral(geocoder=GeocoderWrapper, wrapped=geocoder)
        self.local_time = LocalTime(geocoder)

    def rewrite_cron(self, cron, after, user):
        """Replaces references to sunrise and sunset in a cron expression."""

        # Skip if there is nothing to rewrite.
        if 'sunrise' not in cron and 'sunset' not in cron:
            return cron

        # Determine the first two days of the cron expression after the
        # reference, which covers all candidate sunrises and sunsets.
        yesterday = after - timedelta(days=1)
        midnight_cron = cron.replace('sunrise', '0 0').replace('sunset', '0 0')
        try:
            first_day = croniter(midnight_cron, yesterday).get_next(datetime)
            second_day = croniter(midnight_cron, first_day).get_next(datetime)
        except ValueError as e:
            raise DataError(e)

        zone = self.local_time.zone(user)
        try:
            home = self.astral[user.get('home')]
        except (AstralError, KeyError) as e:
            raise DataError(e)

        # Calculate the closest future sunrise time and replace the term in the
        # cron expression with minutes and hours.
        if 'sunrise' in cron:
            sunrises = map(lambda x: home.sunrise(x).astimezone(zone),
                           [first_day, second_day])
            next_sunrise = min(filter(lambda x: x >= after, sunrises))
            sunrise_cron = cron.replace(
                'sunrise', '%d %d' % (next_sunrise.minute, next_sunrise.hour))
            info('Rewrote cron: (%s) -> (%s), after %s' %
                 (cron, sunrise_cron,
                  after.strftime('%A %B %d %Y %H:%M:%S %Z')))
            return sunrise_cron

        # Calculate the closest future sunset time and replace the term in the
        # cron expression with minutes and hours.
        if 'sunset' in cron:
            sunsets = map(lambda x: home.sunset(x).astimezone(zone),
                          [first_day, second_day])
            next_sunset = min(filter(lambda x: x >= after, sunsets))
            sunset_cron = cron.replace(
                'sunset', '%d %d' % (next_sunset.minute, next_sunset.hour))
            info(
                'Rewrote cron: (%s) -> (%s), after %s' %
                (cron, sunset_cron, after.strftime('%A %B %d %Y %H:%M:%S %Z')))
            return sunset_cron

    def is_daylight(self, user):
        """Calculates whether the sun is currently up."""

        # Find the sunrise and sunset times for today.
        time = self.local_time.now(user)
        zone = self.local_time.zone(user)
        try:
            home = self.astral[user.get('home')]
        except (AstralError, KeyError) as e:
            raise DataError(e)
        sunrise = home.sunrise(time).astimezone(zone)
        sunset = home.sunset(time).astimezone(zone)

        is_daylight = time > sunrise and time < sunset

        info('Daylight: %s (%s)' %
             (is_daylight, time.strftime('%A %B %d %Y %H:%M:%S %Z')))

        return is_daylight
コード例 #2
0
class Sun(object):
    """A wrapper around a calculator for sunrise and sunset times."""

    def __init__(self, geocoder):
        self._astral = Astral(geocoder=GeocoderWrapper, wrapped=geocoder)
        self._local_time = LocalTime(geocoder)

    def rewrite_cron(self, cron, reference, user, forward=True):
        """Replaces references to sunrise and sunset in a cron expression."""

        # Skip if there is nothing to rewrite.
        if 'sunrise' not in cron and 'sunset' not in cron:
            return cron

        # Determine the two days surrounding the cron expression for the
        # reference time, which covers all candidate sunrises and sunsets.
        yesterday = reference - timedelta(days=2)
        midnight_cron = cron.replace('sunrise', '0 0').replace('sunset', '0 0')
        try:
            prev_day = croniter(midnight_cron, yesterday).get_next(datetime)
            current_day = croniter(midnight_cron, prev_day).get_next(datetime)
            next_day = croniter(midnight_cron, current_day).get_next(datetime)

        except ValueError as e:
            raise DataError(e)

        zone = self._local_time.zone(user)
        try:
            home = self._astral[user.get('home')]
        except (AstralError, KeyError) as e:
            raise DataError(e)

        # Set the candidate days and filter based on direction
        candidate_days = []
        direction_filter = None
        sorter = None

        def forward_filter(x):
            return x >= reference

        def backward_filter(x):
            return x <= reference

        if forward:
            candidate_days.extend([current_day, next_day])
            direction_filter = forward_filter
            sorter = min
        else:
            candidate_days.extend([prev_day, current_day])
            direction_filter = backward_filter
            sorter = max

        # Calculate the closest sunrise time and replace the term in the
        # cron expression with minutes and hours.
        if 'sunrise' in cron:
            sunrises = map(
                    lambda x: home.sunrise(x).astimezone(zone),
                    candidate_days)
            next_sunrise = sorter(filter(direction_filter, sunrises))
            sunrise_cron = cron.replace('sunrise', '%d %d' % (
                next_sunrise.minute, next_sunrise.hour))
            info('Rewrote cron: (%s) -> (%s), reference %s' % (
                cron,
                sunrise_cron,
                reference.strftime('%A %B %d %Y %H:%M:%S %Z')))
            return sunrise_cron

        # Calculate the closest future sunset time and replace the term in the
        # cron expression with minutes and hours.
        if 'sunset' in cron:
            sunsets = map(
                    lambda x: home.sunset(x).astimezone(zone),
                    candidate_days)
            next_sunset = sorter(filter(direction_filter, sunsets))
            sunset_cron = cron.replace('sunset', '%d %d' % (next_sunset.minute,
                                                            next_sunset.hour))
            info('Rewrote cron: (%s) -> (%s), reference %s' % (
                cron,
                sunset_cron,
                reference.strftime('%A %B %d %Y %H:%M:%S %Z')))
            return sunset_cron

    def is_daylight(self, user):
        """Calculates whether the sun is currently up."""

        # Find the sunrise and sunset times for today.
        time = self._local_time.now(user)
        zone = self._local_time.zone(user)
        try:
            home = self._astral[user.get('home')]
        except (AstralError, KeyError) as e:
            raise DataError(e)
        sunrise = home.sunrise(time).astimezone(zone)
        sunset = home.sunset(time).astimezone(zone)

        is_daylight = time > sunrise and time < sunset

        info('Daylight: %s (%s)' % (is_daylight,
                                    time.strftime('%A %B %d %Y %H:%M:%S %Z')))

        return is_daylight