Example #1
0
 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)
Example #2
0
 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
Example #3
0
 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
Example #4
0
 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
     }
Example #5
0
 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
     }
Example #6
0
 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
Example #7
0
 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
     }
Example #8
0
 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')
Example #9
0
 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)
Example #10
0
 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")