Пример #1
0
 def post(self, status, media):
     if len(media) > 1:
         logger.error('Tweepy library cannot post multiple media')
     if media:
         self.api.update_with_media(media[0], status[:257], **self.kwargs)
     else:
         self.api.update_status(status[:280], **self.kwargs)
Пример #2
0
def calibrate_data(params, raw_data, calib_data):
    """'Calibrate' raw data, using a user-supplied function."""
    start = calib_data.before(datetime.max)
    if start is None:
        start = datetime.min
    start = raw_data.after(start + SECOND)
    if start is None:
        return start
    del calib_data[start:]
    calibrator = Calib(params, raw_data)
    count = 0
    for data in raw_data[start:]:
        idx = data['idx']
        count += 1
        if count % 10000 == 0:
            logger.info("calib: %s", idx.isoformat(' '))
        elif count % 500 == 0:
            logger.debug("calib: %s", idx.isoformat(' '))
        for key in ('rain', 'abs_pressure', 'temp_in'):
            if data[key] is None:
                logger.error('Ignoring invalid data at %s', idx.isoformat(' '))
                break
        else:
            calib_data[idx] = calibrator.calib(data)
    return start
Пример #3
0
def calibrate_data(params, raw_data, calib_data):
    """'Calibrate' raw data, using a user-supplied function."""
    start = calib_data.before(datetime.max)
    if start is None:
        start = datetime.min
    start = raw_data.after(start + SECOND)
    if start is None:
        return start
    del calib_data[start:]
    calibrator = Calib(params, raw_data)
    count = 0
    for data in raw_data[start:]:
        idx = data['idx']
        count += 1
        if count % 10000 == 0:
            logger.info("calib: %s", idx.isoformat(' '))
        elif count % 500 == 0:
            logger.debug("calib: %s", idx.isoformat(' '))
        for key in ('rain', 'abs_pressure', 'temp_in'):
            if data[key] is None:
                logger.error('Ignoring invalid data at %s', idx.isoformat(' '))
                break
        else:
            calib_data[idx] = calibrator.calib(data)
    return start
Пример #4
0
 def post(self, status, media):
     if len(media) > 1:
         logger.error('Tweepy library cannot post multiple media')
     if media:
         self.api.update_with_media(media[0], status[:257], **self.kwargs)
     else:
         self.api.update_status(status[:280], **self.kwargs)
Пример #5
0
 def fetch_logged(self, last_date, last_ptr):
     # offset last stored time by half logging interval
     last_stored = self.last_stored_time + timedelta(
         seconds=self.fixed_block['read_period'] * 30)
     if last_date <= last_stored:
         # nothing to do
         return
     # data_count includes record currently being updated every 48 seconds
     max_count = self.fixed_block['data_count'] - 1
     count = 0
     # initialise detection of data left after a station reboot
     saved_date = self.last_stored_time
     saved_ptr = self.last_stored_ptr
     self.last_stored_ptr = None
     duplicates = []
     while last_date > last_stored and count < max_count:
         data = self.ws.get_data(last_ptr)
         if last_ptr == saved_ptr:
             if any(data[key] != self.raw_data[saved_date][key]
                    for key in ('hum_in', 'temp_in', 'hum_out', 'temp_out',
                                'abs_pressure', 'wind_ave', 'wind_gust',
                                'wind_dir', 'rain', 'status')):
                 # pointer matches but data is different, so no duplicates
                 duplicates = None
                 saved_ptr = None
             else:
                 # potential duplicate data
                 duplicates.append(last_date)
                 saved_date = self.raw_data.before(saved_date)
                 saved_ptr = self.ws.dec_ptr(saved_ptr)
         if (data['delay'] is None or data['delay'] > max(
                 self.fixed_block['read_period'] * 2, 35)):
             logger.error('invalid data at %04x, %s', last_ptr,
                          last_date.isoformat(' '))
             last_date -= timedelta(minutes=self.fixed_block['read_period'])
         else:
             self.raw_data[last_date] = data
             count += 1
             last_date -= timedelta(minutes=data['delay'])
         last_ptr = self.ws.dec_ptr(last_ptr)
     if duplicates:
         for d in duplicates:
             del self.raw_data[d]
         count -= len(duplicates)
     last_date = self.raw_data.nearest(last_date) or datetime.max
     next_date = self.raw_data.after(last_date + SECOND)
     if next_date:
         gap = (next_date - last_date).seconds // 60
         gap -= self.fixed_block['read_period']
         if gap > 0:
             logger.critical("%d minutes gap in data detected", gap)
     logger.info("%d catchup records", count)
Пример #6
0
 def fetch_logged(self, last_date, last_ptr):
     # offset last stored time by half logging interval
     last_stored = self.last_stored_time + timedelta(
         seconds=self.fixed_block['read_period'] * 30)
     if last_date <= last_stored:
         # nothing to do
         return
     # data_count includes record currently being updated every 48 seconds
     max_count = self.fixed_block['data_count'] - 1
     count = 0
     # initialise detection of data left after a station reboot
     saved_date = self.last_stored_time
     saved_ptr = self.last_stored_ptr
     self.last_stored_ptr = None
     duplicates = []
     while last_date > last_stored and count < max_count:
         data = self.ws.get_data(last_ptr)
         if last_ptr == saved_ptr:
             if any(data[key] != self.raw_data[saved_date][key] for key in (
                     'hum_in', 'temp_in', 'hum_out', 'temp_out',
                     'abs_pressure', 'wind_ave', 'wind_gust', 'wind_dir',
                     'rain', 'status')):
                 # pointer matches but data is different, so no duplicates
                 duplicates = None
                 saved_ptr = None
             else:
                 # potential duplicate data
                 duplicates.append(last_date)
                 saved_date = self.raw_data.before(saved_date)
                 saved_ptr = self.ws.dec_ptr(saved_ptr)
         if (data['delay'] is None or
                 data['delay'] > max(self.fixed_block['read_period'] * 2, 35)):
             logger.error('invalid data at %04x, %s',
                          last_ptr, last_date.isoformat(' '))
             last_date -= timedelta(minutes=self.fixed_block['read_period'])
         else:
             self.raw_data[last_date] = data
             count += 1
             last_date -= timedelta(minutes=data['delay'])
         last_ptr = self.ws.dec_ptr(last_ptr)
     if duplicates:
         for d in duplicates:
             del self.raw_data[d]
         count -= len(duplicates)
     last_date = self.raw_data.nearest(last_date)
     next_date = self.raw_data.after(last_date + SECOND)
     if next_date:
         gap = (next_date - last_date).seconds // 60
         gap -= self.fixed_block['read_period']
         if gap > 0:
             logger.critical("%d minutes gap in data detected", gap)
     logger.info("%d catchup records", count)
Пример #7
0
 def calibgen(inputdata):
     """Internal generator function"""
     count = 0
     for data in inputdata:
         idx = data['idx']
         count += 1
         if count % 10000 == 0:
             logger.info("calib: %s", idx.isoformat(' '))
         elif count % 500 == 0:
             logger.debug("calib: %s", idx.isoformat(' '))
         for key in ('rain', 'abs_pressure', 'temp_in'):
             if data[key] is None:
                 logger.error('Ignoring invalid data at %s', idx.isoformat(' '))
                 break
         else:
             yield calibrator.calib(data)
Пример #8
0
 def calibgen(inputdata):
     """Internal generator function"""
     count = 0
     for data in inputdata:
         idx = data['idx']
         count += 1
         if count % 10000 == 0:
             logger.info("calib: %s", idx.isoformat(' '))
         elif count % 500 == 0:
             logger.debug("calib: %s", idx.isoformat(' '))
         for key in ('rain', 'abs_pressure', 'temp_in'):
             if data[key] is None:
                 logger.error('Ignoring invalid data at %s', idx.isoformat(' '))
                 break
         else:
             yield calibrator.calib(data)
Пример #9
0
    def process(self, live_data, template_file):
        def jump(idx, count):
            while count > 0:
                new_idx = data_set.after(idx + SECOND)
                if new_idx == None:
                    break
                idx = new_idx
                count -= 1
            while count < 0:
                new_idx = data_set.before(idx)
                if new_idx == None:
                    break
                idx = new_idx
                count += 1
            return idx, count == 0

        params = self.params
        if not live_data:
            idx = self.calib_data.before(datetime.max)
            if not idx:
                logger.error("No calib data - run pywws.process first")
                return
            live_data = self.calib_data[idx]
        # get default character encoding of template input & output files
        self.encoding = params.get('config', 'template encoding', 'iso-8859-1')
        file_encoding = self.encoding
        if file_encoding == 'html':
            file_encoding = 'ascii'
        # get conversions module to create its 'private' wind dir text
        # array, then copy it to deprecated wind_dir_text variable
        winddir_text(0)
        wind_dir_text = conversions._winddir_text_array
        hour_diff = self.computations.hour_diff
        rain_hour = self.computations.rain_hour
        rain_day = self.computations.rain_day
        rain_24hr = self.computations.rain_24hr
        pressure_offset = float(self.params.get('config', 'pressure offset'))
        fixed_block = literal_eval(self.status.get('fixed', 'fixed block'))
        # start off with no time rounding
        round_time = None
        # start off in hourly data mode
        data_set = self.hourly_data
        # start off in utc
        local_time = False
        # start off with default use_locale setting
        use_locale = self.use_locale
        # jump to last item
        idx, valid_data = jump(datetime.max, -1)
        if not valid_data:
            logger.error("No summary data - run pywws.process first")
            return
        data = data_set[idx]
        # open template file, if not already a file(like) object
        if hasattr(template_file, 'readline'):
            tmplt = template_file
        else:
            tmplt = open(template_file, 'rb')
        # do the text processing
        line = ''
        while True:
            new_line = tmplt.readline()
            if not new_line:
                break
            if isinstance(new_line, bytes) or sys.version_info[0] < 3:
                new_line = new_line.decode(file_encoding)
            line += new_line
            parts = line.split('#')
            if len(parts) % 2 == 0:
                # odd number of '#'
                line = line.rstrip('\r\n')
                continue
            for i, part in enumerate(parts):
                if i % 2 == 0:
                    # not a processing directive
                    if i == 0 or part != '\n':
                        yield part
                    continue
                if part and part[0] == '!':
                    # comment
                    continue
                # Python 2 shlex can't handle unicode
                if sys.version_info[0] < 3:
                    part = part.encode(file_encoding)
                command = shlex.split(part)
                if sys.version_info[0] < 3:
                    command = map(lambda x: x.decode(file_encoding), command)
                if command == []:
                    # empty command == print a single '#'
                    yield u'#'
                elif command[0] in list(data.keys()) + ['calc']:
                    # output a value
                    if not valid_data:
                        continue
                    # format is: key fmt_string no_value_string conversion
                    # get value
                    if command[0] == 'calc':
                        x = eval(command[1])
                        del command[1]
                    else:
                        x = data[command[0]]
                    # adjust time
                    if isinstance(x, datetime):
                        if round_time:
                            x += round_time
                        if local_time:
                            x = timezone.to_local(x)
                        else:
                            x = timezone.to_utc(x)
                    # convert data
                    if x is not None and len(command) > 3:
                        x = eval(command[3])
                    # get format
                    fmt = u'%s'
                    if len(command) > 1:
                        fmt = command[1]
                    # write output
                    if x is None:
                        if len(command) > 2:
                            yield command[2]
                    elif isinstance(x, datetime):
                        if sys.version_info[0] < 3:
                            fmt = fmt.encode(file_encoding)
                        x = x.strftime(fmt)
                        if sys.version_info[0] < 3:
                            if self.encoding == 'html':
                                x = x.decode('ascii', errors='xmlcharrefreplace')
                            else:
                                x = x.decode(file_encoding)
                        yield x
                    elif not use_locale:
                        yield fmt % (x)
                    elif sys.version_info >= (2, 7) or '%%' not in fmt:
                        yield locale.format_string(fmt, x)
                    else:
                        yield locale.format_string(
                            fmt.replace('%%', '##'), x).replace('##', '%')
                elif command[0] == 'monthly':
                    data_set = self.monthly_data
                    idx, valid_data = jump(datetime.max, -1)
                    data = data_set[idx]
                elif command[0] == 'daily':
                    data_set = self.daily_data
                    idx, valid_data = jump(datetime.max, -1)
                    data = data_set[idx]
                elif command[0] == 'hourly':
                    data_set = self.hourly_data
                    idx, valid_data = jump(datetime.max, -1)
                    data = data_set[idx]
                elif command[0] == 'raw':
                    data_set = self.calib_data
                    idx, valid_data = jump(datetime.max, -1)
                    data = data_set[idx]
                elif command[0] == 'live':
                    data_set = self.calib_data
                    idx = live_data['idx']
                    valid_data = True
                    data = live_data
                elif command[0] == 'timezone':
                    if command[1] == 'utc':
                        local_time = False
                    elif command[1] == 'local':
                        local_time = True
                    else:
                        logger.error("Unknown time zone: %s", command[1])
                        return
                elif command[0] == 'locale':
                    use_locale = eval(command[1])
                elif command[0] == 'encoding':
                    self.encoding = command[1]
                    file_encoding = self.encoding
                    if file_encoding == 'html':
                        file_encoding = 'ascii'
                elif command[0] == 'roundtime':
                    if eval(command[1]):
                        round_time = timedelta(seconds=30)
                    else:
                        round_time = None
                elif command[0] == 'jump':
                    prevdata = data
                    idx, valid_data = jump(idx, int(command[1]))
                    data = data_set[idx]
                elif command[0] == 'goto':
                    prevdata = data
                    time_str = command[1]
                    if '%' in time_str:
                        if local_time:
                            lcl = timezone.to_local(idx)
                        else:
                            lcl = timezone.to_utc(idx)
                        time_str = lcl.strftime(time_str)
                    new_idx = pywws.weatherstation.WSDateTime.from_csv(time_str)
                    if local_time:
                        new_idx = timezone.to_naive(timezone.localize(new_idx))
                    new_idx = data_set.after(new_idx)
                    if new_idx:
                        idx = new_idx
                        data = data_set[idx]
                        valid_data = True
                    else:
                        valid_data = False
                elif command[0] == 'loop':
                    loop_count = int(command[1])
                    loop_start = tmplt.tell()
                elif command[0] == 'endloop':
                    loop_count -= 1
                    if valid_data and loop_count > 0:
                        tmplt.seek(loop_start, 0)
                else:
                    logger.error("Unknown processing directive: #%s#", part)
                    return
            line = ''