def update_weather(self, weather): zip = int(self.config.location) if not (1000 <= zip <= 9999): raise ValueError("Invalid Swiss ZIP code") date = datetime.utcnow() app.log(f"Fetching weather data...") for ix in range(60): url = f"https://www.meteoschweiz.admin.ch/product/output/forecast-chart/version__{(date - timedelta(minutes=ix)).strftime('%Y%m%d_%H%M')}/de/{zip}00.json" response = requests.get(url) if response.status_code != 404: break else: raise ValueError("No JSON data found within an hour") response.raise_for_status() data = response.json() for key, instant, value in itertools.chain( (('rain', dump_datetime(parse_datetime(hour[0])), hour[1]) for day in data for hour in day['rainfall']), (('sun', dump_datetime(parse_datetime(hour[0])), hour[1] / 100) for day in data for hour in day['sunshine']), (('temperature', dump_datetime(parse_datetime(hour[0])), hour[1]) for day in data for hour in day['temperature']), (('wind', dump_datetime(parse_datetime(hour[0])), hour[1]) for day in data for hour in day['wind']['data'])): hour_weather = weather.get(instant) if not hour_weather: hour_weather = HourlyWeather() weather[instant] = hour_weather setattr(hour_weather, key, value)
def json(self, verbose=False): result = { 'id': self.id, 'username': self.username, 'photo': self.photo, 'created_at': dump_datetime(self.created_at), 'updated_at': dump_datetime(self.updated_at), } if verbose: result['questions'] = [q.json() for q in self.questions.all()] return result
def json(self, verbose=False): result = { 'major': self.major, 'minor': self.minor, 'name': self.name, 'speaker_name': self.speaker_name, 'photo': self.photo, 'start_date': dump_datetime(self.start_date), 'end_date': dump_datetime(self.end_date), 'type': self.type, 'id': self.id } if verbose: result['created_at'] = dump_datetime(self.created_at) result['updated_at'] = dump_datetime(self.updated_at) return result
def serialize(self): return { 'id': self.id, 'created': dump_datetime(self.created), 'url': app.config["PICTURE_URL"] + self.file_name, 'pet_id': self.pet_id, 'user_id': self.user_id }
def serialize(self): """Return object data in easily serializeable format""" return { 'games': self.games, 'last_login': dump_datetime(self.last_login), 'wins': self.wins, 'streak': self.streak, 'cash': self.cash }
def json(self, verbose=False): result = { 'id': self.id, 'text': self.text, 'room_id': self.room_id, 'user_id': self.user.json(), 'status': self.status, 'created_at': dump_datetime(self.created_at) } if verbose: result['room_id'] = self.room.json() return result
def serialize(self): return { 'id': self.id, 'pet_name': self.name, 'last_seen_loc': db_session.scalar(self.last_seen_loc.wkt), 'search_polygon': db_session.scalar(self.search_polygon.wkt), 'last_seen_date': dump_datetime(self.last_seen_date), 'created': dump_datetime(self.created), 'user_id': self.user_id, 'age': self.age, 'vet': self.vet, 'fav_food': self.fav_food, 'known_words': self.known_words, 'house_broken': self.house_broken, 'approach': self.approach, 'personality': self.personality, 'last_seen_city': self.last_seen_city, 'last_seen_state': self.last_seen_date, # This is an example how to deal with Many2Many relations #'many2many': self.serialize_many2many }
def __init__(self, point_type: Type[TPoint], query: Union[str, Dict[str, Any]]): factory = get_factory(point_type) props: List[str] = factory.__self__.get_props() if isinstance(query, str): query = literal_eval_checked(query, dict) self.predicates = [] self.filter = { 'pointer_type': get_pointer_type(point_type), 'meta': {} } for key, value in query.items(): if key.startswith('!'): negate = True key = key[1:] else: negate = False ismeta = (key in ('meta', 'id')) or (key not in props) get = (lambda v, key=key: v['meta'][key]) if ismeta else (lambda v, key=key: v[key]) if isinstance(value, str): # special date handling match = PointQuery.__rxdate.fullmatch(value.strip()) if match: date = parse_datetime(match.group(2)) if not match.group(1): # exact date match, no local filtering required, but normalize the date format value = dump_datetime(date) else: if match.group(1) == 'before': op = operator.lt if not negate else operator.ge else: # match.group(1) == 'after': op = operator.gt if not negate else operator.le self.predicates.append(lambda v, get=get, op=op, date=date: op(parse_datetime(get(v)), date)) continue # special number handling match = PointQuery.__rxnum.fullmatch(value.strip()) if match: number = float(match.group(2)) if match.group(1) == 'least': op = operator.ge if not negate else operator.lt else: # match.group(1) == 'most': op = operator.le if not negate else operator.gt self.predicates.append(lambda v, get=get, op=op, number=number: op(float(get(v)), number)) continue if negate: self.predicates.append(lambda v, get=get, value=value: get(v) != value) elif ismeta: self.filter['meta'][key] = value else: self.filter[key] = value if not self.filter['meta']: del self.filter['meta'] device.log(f"Built remote filter {json.dumps(self.filter)} and {len(self.predicates)} local predicates", message_type='debug')
def execute(self): """ Refresh the weather data from the source and return it """ point = get_weather_point(self) weather = deserialize(Dict[str, HourlyWeather], point.meta) self.update_weather(weather) limit = dump_datetime( datetime.utcnow() - timedelta(hours=(self.config.maxage_hours or 96) + 1)) # The dates are in a sortable format for key in [key for key in weather if key <= limit ]: # clone keys since we're going to remove items del weather[key] point.meta = weather app.log(f"Storing {len(weather)} hourly weather records...") self.put_point(point)
def apply(self, updates: Dict[str, Any]): for key, value in updates.items(): if isinstance(value, str): offset = parse_offset(value) if offset: value = dump_datetime(utc_now() + offset) if key.startswith("+"): append = True key = key[1:] else: append = False ismeta = (key in ('meta', 'id')) or (key not in get_factory(type(self)).__self__.get_props()) data = self.meta if ismeta else self.__dict__ if append: data[key] += value elif value is None and ismeta: del data[key] else: data[key] = value device.log(f"Applied data update to point: {json.dumps(self)}", "debug")