๐Ÿ“… Calendar file generator for triathlonlive.tv upcoming events triathlon-live-calendar.fly.dev

Minor cache refactor

+14 -14
+11 -9
triathlon_live_calendar/cache.py
··· 6 6 7 7 8 8 @dataclass 9 - class Response: 9 + class Value: 10 10 content: str 11 11 expires_on: datetime 12 12 13 13 14 14 @dataclass 15 15 class Cache: 16 - _response: Optional[Response] = None 16 + _value: Optional[Value] = None 17 17 18 18 @property 19 - def response(self) -> Optional[str]: 20 - if not self._response: 21 - return None 19 + def is_expired(self) -> bool: 20 + if not self._value: 21 + return True 22 + return self._value.expires_on < datetime.now() 22 23 23 - if self._response.expires_on < datetime.now(): 24 + @property 25 + def value(self) -> Optional[str]: 26 + if self._value is None or self.is_expired: 24 27 return None 25 - 26 - return self._response.content 28 + return self._value.content 27 29 28 30 def save(self, content: str, expires_in: Optional[timedelta] = None) -> None: 29 31 expires_in = expires_in or DEFAULT_EXPIRES_IN 30 - self._response = Response(content, datetime.now() + expires_in) 32 + self._value = Value(content, datetime.now() + expires_in)
+1 -1
triathlon_live_calendar/scraper.py
··· 24 24 begin = datetime.strptime(data["start_time"], DATE_FORMAT).replace( 25 25 tzinfo=timezone.utc 26 26 ) 27 - logger.debug(f"Parsed {url}\n Title: {name}\n Begin: {begin}") 27 + logger.debug((f"Parsed {url}", f" Title: {name}", f" Begin: {begin}")) 28 28 return Event( 29 29 name=name, 30 30 begin=begin,
+2 -4
triathlon_live_calendar/server.py
··· 19 19 @app.get("/", response_class=PlainTextResponse) 20 20 async def home(response: PlainTextResponse): 21 21 response.headers.update(DEFAULT_HEADERS) 22 - 23 - cached = cache.response 24 - if cached: 22 + if cached := cache.value: 25 23 return cached 26 24 27 - contents = str(await calendar(logger)) 25 + contents = (await calendar(logger)).serialize() 28 26 cache.save(contents) 29 27 return contents