def decorated_function(*args: List[Any], **kwargs: Dict[str, Any]) -> Callable: cache_key = key.format(id=request.full_path, locale=localization.get_locale()) # include querystring cache_policy = '' if not cacheable: cache_policy += ', no-store' # tells the browser not to cache at all else: if must_revalidate: # this looks contradicting if you haven't read the article. # no-cache doesn't mean "don't cache", it means it must check # (or "revalidate" as it calls it) with the server before # using the cached resource cache_policy += ', no-cache' else: # Also must-revalidate doesn't mean "must revalidate", it # means the local resource can be used if it's younger than # the provided max-age, otherwise it must revalidate cache_policy += ', must-revalidate' if client_only: cache_policy += ', private' else: cache_policy += ', public' actual_client_timeout = client_timeout actual_server_timeout = server_timeout if get_season_id() and get_season_id() != 0 and get_season_id() < rotation.current_season_num(): actual_client_timeout = 7 * 24 * 60 * 60 actual_server_timeout = 7 * 24 * 60 * 60 cache_policy += ', max-age={client_timeout}'.format(client_timeout=actual_client_timeout) headers = {} cache_policy = cache_policy.strip(',') headers['Cache-Control'] = cache_policy now = datetime.datetime.utcnow() client_etag = request.headers.get('If-None-Match') response = CACHE.get(cache_key) # type: ignore # Respect a hard refresh from the client, if sent. # Note: Safari/OSX does not send a Cache-Control (or any additional) header on a hard refresh so people using Safari can't bypass/refresh server cache. if response is not None and request.headers.get('Cache-Control', '') != 'no-cache': headers['X-Cache'] = 'HIT from Server' cached_etag = response.headers.get('ETag') if client_etag and cached_etag and client_etag == cached_etag: headers['X-Cache'] = 'HIT from Client' headers['X-Last-Modified'] = response.headers.get('X-LastModified') response = make_response('', 304) else: response = make_response(f(*args, **kwargs)) if response.status_code == 200 and request.method in ['GET', 'HEAD']: headers['X-Cache'] = 'MISS' # - Added the headers to the response object instead of the # headers dict so they get cached too # - If you can find any faster random algorithm go for it. response.headers.add('ETag', binascii.hexlify(os.urandom(4))) response.headers.add('X-Last-Modified', str(now)) CACHE.set(cache_key, response, timeout=actual_server_timeout) response.headers.extend(headers) return response
def card_history(c: Card) -> str: seasons = {} for format_name, status in c.legalities.items(): if 'Penny Dreadful ' in format_name and status == 'Legal': season_id = rotation.SEASONS.index( format_name.replace('Penny Dreadful ', '')) + 1 seasons[season_id] = True seasons[rotation.current_season_num()] = c.legalities.get('Penny Dreadful', None) == 'Legal' s = ' ' for i in range(1, rotation.current_season_num() + 1): s += f'{i} ' s += ':white_check_mark:' if seasons.get(i, False) else ':no_entry_sign:' s += ' ' s = s.strip() s += '\n' + fetcher.decksite_url('/seasons/all/cards/{name}/'.format( name=fetch_tools.escape(c.name, skip_double_slash=True))) return s
def title(self) -> str: if not self.page_title(): return 'pennydreadfulmagic.com' if get_season_id() == rotation.current_season_num(): season = '' elif get_season_id() == 'all': season = ' - All Time' else: season = ' - Season {n}'.format(n=get_season_id()) return '{page_title}{season} – pennydreadfulmagic.com'.format(page_title=self.page_title(), season=season)
def person_api(person: str, season_id: int = -1) -> Response: if season_id == -1: season_id = rotation.current_season_num() try: p = ps.load_person_by_discord_id_or_username(person, season_id) p.decks_url = url_for('person_decks_api', person=person, season_id=season_id) p.head_to_head = url_for('person_h2h_api', person=person, season_id=season_id) return return_json(p) except DoesNotExistException: return return_json(generate_error('NOTFOUND', 'Person does not exist'))
def pd_rotation_changes(season_id): # It doesn't really make sense to do this for 'all' so just show current season in that case. if season_id == 'all': season_id = rotation.current_season_num() try: from_format_id = multiverse.get_format_id_from_season_id(int(season_id) - 1) except InvalidArgumentException: from_format_id = -1 try: to_format_id = multiverse.get_format_id_from_season_id(season_id) except InvalidArgumentException: to_format_id = -1 return changes_between_formats(from_format_id, to_format_id)
def random_legal_deck() -> Optional[Deck]: where = 'd.reviewed AND d.created_date > (SELECT start_date FROM season WHERE number = {current_season_num})'.format( current_season_num=rotation.current_season_num()) having = '(d.competition_id NOT IN ({active_competition_id_query}) OR SUM(cache.wins + cache.draws + cache.losses) >= 5)'.format( active_competition_id_query=active_competition_id_query()) try: return deck.load_decks(where=where, having=having, order_by='RAND()', limit='LIMIT 1')[0] except IndexError: # For a short while at the start of a season there are no decks that match the WHERE/HAVING clauses. return None
def seasonized_url(season_id: Union[int, str]) -> str: args = request.view_args.copy() if season_id == rotation.current_season_num(): args.pop('season_id', None) endpoint = request.endpoint.replace('seasons.', '') else: args['season_id'] = season_id prefix = '' if request.endpoint.startswith('seasons.') else 'seasons.' endpoint = '{prefix}{endpoint}'.format(prefix=prefix, endpoint=request.endpoint) try: return url_for(endpoint, **args) except BuildError: return url_for(request.endpoint)
def pd_rotation_changes(season_id): # Bit of a hack to make 'all' not explode until we cope with selective season dropdowns. if season_id == 'all': season_id = rotation.current_season_num() try: from_format_id = multiverse.get_format_id_from_season_id( int(season_id) - 1) except InvalidArgumentException: from_format_id = -1 try: to_format_id = multiverse.get_format_id_from_season_id(season_id) except InvalidArgumentException: to_format_id = -1 return changes_between_formats(from_format_id, to_format_id)
def __init__(self, cards: List[Card], tournament_only: bool = False, query: str = '') -> None: super().__init__() self.show_seasons = True self.show_tournament_toggle = True self.tournament_only = self.hide_source = tournament_only self.query = query # if it's the current season, allow the scryfall filter to add "f:pd" to speed up results if self.season_id() == current_season_num(): self.filter_current_season = True self.toggle_results_url = url_for( '.cards', deck_type=None if tournament_only else DeckType.TOURNAMENT.value) self.cards = cards self.show_filters_toggle = True
def test_seasonized_url_for_app() -> None: with APP.test_request_context('/decks/'): assert view.seasonized_url(1) == '/seasons/1/decks/' assert view.seasonized_url(rotation.current_season_num()) == '/decks/'
def test_seasonized_url_simple() -> None: with APP.test_request_context('/tournaments/'): assert view.seasonized_url(1) == '/tournaments/' assert view.seasonized_url( rotation.current_season_num()) == '/tournaments/'
def get_season_id() -> int: return g.get('season_id', rotation.current_season_num())
def get_season_id() -> int: season_id = g.get('season_id', rotation.current_season_num()) if season_id == 'all': return 0 return season_id