def test_parse_rfc3339() -> None: s = '2002-10-02T10:00:00-05:00' dt = dtutil.parse_rfc3339(s) assert '{:%Y-%m-%d %H:%M:%S %z}'.format(dt) == '2002-10-02 15:00:00 +0000' s = '2002-10-02T15:00:00Z' dt = dtutil.parse_rfc3339(s) assert '{:%Y-%m-%d %H:%M:%S %z}'.format(dt) == '2002-10-02 15:00:00 +0000' s = '2002-10-02T15:00:00.05Z' dt = dtutil.parse_rfc3339(s) assert '{:%Y-%m-%d %H:%M:%S %z}'.format(dt) == '2002-10-02 15:00:00 +0000'
def scryfall_last_updated() -> datetime.datetime: d = internal.fetch_json('https://api.scryfall.com/bulk-data') for o in d['data']: if o['type'] == 'default_cards': return dtutil.parse_rfc3339(o['updated_at']) raise InvalidDataException( f'Could not get the last updated date from Scryfall: {d}')
async def background_task_league_end(self) -> None: tournament_channel_id = configuration.get_int( 'tournament_reminders_channel_id') if not tournament_channel_id: logging.warning('tournament channel is not configured') return channel = self.get_channel(tournament_channel_id) if not isinstance(channel, discord.abc.Messageable): logging.warning('tournament channel could not be found') return while self.is_ready: try: league = await fetch_tools.fetch_json_async( fetcher.decksite_url('/api/league')) except fetch_tools.FetchException as e: logging.error( "Couldn't reach decksite or decode league json with error message(s) {e}", e='; '.join(str(x) for x in e.args)) logging.info('Sleeping for 5 minutes and trying again.') await asyncio.sleep(300) continue if not league: await asyncio.sleep(300) continue diff = round((dtutil.parse_rfc3339(league['end_date']) - datetime.datetime.now(tz=datetime.timezone.utc)) / datetime.timedelta(seconds=1)) embed = discord.Embed( title=league['name'], description= 'League ending soon - any active runs will be cut short.') if diff <= 60 * 60 * 24: embed.add_field(name='Ending in:', value=dtutil.display_time(diff, 2)) embed.set_image(url=fetcher.decksite_url('/favicon-152.png')) # See #2809. # pylint: disable=no-value-for-parameter,unexpected-keyword-arg await channel.send(embed=embed) if diff <= 5 * 60: # Five minutes, final warning. timer = 301 elif diff <= 1 * 60 * 60: # 1 hour. Sleep until five minute warning. timer = diff - 300 elif diff <= 24 * 60 * 60: # 1 day. Sleep until one hour warning. timer = diff - 1800 else: # Sleep for 1 day, plus enough to leave us with a whole number of days timer = 24 * 60 * 60 + diff % (24 * 60 * 60) if timer < 300: timer = 300 await asyncio.sleep(timer) logging.warning('naturally stopping league reminders')