def __init__(self, interestingness: Optional[str] = None, query: Optional[str] = '') -> None: super().__init__() until_rotation = seasons.next_rotation() - dtutil.now() in_rotation = configuration.get_bool('always_show_rotation') if until_rotation < datetime.timedelta(7): in_rotation = True self.rotation_msg = 'Rotation is in progress, ends ' + dtutil.display_date(seasons.next_rotation(), 2) else: self.rotation_msg = 'Rotation is ' + dtutil.display_date(seasons.next_rotation(), 2) if in_rotation: self.in_rotation = in_rotation self.show_interestingness_filter = True self.runs, self.runs_percent, self.cards = rotation.read_rotation_files() # Now add interestingness to the cards, which only decksite knows not magic.rotation. playability = card.playability() c: Card for c in self.cards: c.interestingness = rotation.interesting(playability, c) else: self.cards = [] self.show_interesting = True if interestingness: self.cards = [c for c in self.cards if c.get('interestingness') == interestingness] self.num_cards = len(self.cards) self.query = query self.show_filters_toggle = True self.cards = [c for c in self.cards if visible(c)]
def setup_rotation(self) -> None: self.season_start_display = dtutil.display_date(seasons.last_rotation()) self.season_end_display = dtutil.display_date(seasons.next_rotation()) self.scryfall_url = 'https://scryfall.com/search?q=f%3Apd' self.legal_cards_url = 'http://pdmtgo.com/legal_cards.txt' self.in_rotation = rotation.in_rotation() self.rotation_msg = 'Rotation is in progress.' self.rotation_url = url_for('rotation')
def __init__(self) -> None: super().__init__() until_rotation = seasons.next_rotation() - dtutil.now() in_rotation = configuration.get_bool('always_show_rotation') if until_rotation < datetime.timedelta(7): in_rotation = True self.rotation_msg = 'Rotation is in progress, ends ' + dtutil.display_date( seasons.next_rotation(), 2) else: self.rotation_msg = 'Rotation is ' + dtutil.display_date( seasons.next_rotation(), 2) if in_rotation: self.in_rotation = in_rotation self.runs, self.runs_percent, self.cards = rotation.read_rotation_files( ) else: self.cards = [] self.num_cards = len(self.cards)
def rotation_api() -> Response: now = dtutil.now() diff = seasons.next_rotation() - now result = { 'last': seasons.last_rotation_ex(), 'next': seasons.next_rotation_ex(), 'diff': diff.total_seconds(), 'friendly_diff': dtutil.display_time(int(diff.total_seconds())), } return return_json(result)
async def hype(ctx: MtgContext) -> None: """Display the latest rotation hype message.""" until_rotation = seasons.next_rotation() - dtutil.now() last_run_time = rotation.last_run_time() msg = None if until_rotation < datetime.timedelta(7) and last_run_time is not None: msg = await bot.rotation_hype_message() if msg: await ctx.send(msg) else: await ctx.send(f'{ctx.author.mention}: No rotation hype message.')
def active_league(should_load_decks: bool = False) -> competition.Competition: where = 'c.id = ({id_query})'.format(id_query=active_competition_id_query()) leagues = competition.load_competitions(where, should_load_decks=should_load_decks) if len(leagues) == 0: start_date = dtutil.now(tz=dtutil.WOTC_TZ) end_date = determine_end_of_league(start_date, seasons.next_rotation()) name = determine_league_name(start_date, end_date) comp_id = competition.get_or_insert_competition(start_date, end_date, name, 'League', None, competition.Top.EIGHT) if not comp_id: raise InvalidDataException(f'No competition id with {start_date}, {end_date}, {name}') leagues = [competition.load_competition(comp_id)] return guarantee.exactly_one(leagues)
async def background_task_rotation_hype(self) -> None: rotation_hype_channel_id = configuration.get_int('rotation_hype_channel_id') if not rotation_hype_channel_id: logging.warning('rotation hype channel is not configured') return channel = self.get_channel(rotation_hype_channel_id) if not isinstance(channel, discord.abc.Messageable): logging.warning('rotation hype channel is not a text channel') return while self.is_ready(): until_rotation = seasons.next_rotation() - dtutil.now() last_run_time = rotation.last_run_time() if until_rotation < datetime.timedelta(7) and last_run_time is not None: if dtutil.now() - last_run_time < datetime.timedelta(minutes=5): hype = await rotation_hype_message() if hype: await channel.send(hype) timer = 5 * 60 else: timer = int((until_rotation - datetime.timedelta(7)).total_seconds()) await asyncio.sleep(timer)
def build_menu() -> List[Dict[str, Union[str, Dict[str, str]]]]: current_template = (request.endpoint or '').replace('seasons.', '') archetypes_badge = { 'url': url_for('edit_archetypes'), 'text': '', 'badge_class': 'edit_archetypes' } resources_submenu: List[Dict[str, str]] = [] if (seasons.next_rotation() - dtutil.now()) < datetime.timedelta(7): resources_submenu.append({ 'name': gettext('Rotation Tracking'), 'endpoint': 'rotation' }) resources_submenu += [ { 'name': gettext('Rotation Changes'), 'endpoint': 'rotation_changes' }, { 'name': gettext('Deck Check'), 'endpoint': 'deck_check' }, { 'name': gettext('Discord Chat'), 'url': 'https://discord.gg/H6EHdHu' }, { 'name': gettext('External Links'), 'endpoint': 'resources' }, { 'name': gettext('Link Accounts'), 'endpoint': 'link' }, { 'name': gettext('Bugs'), 'endpoint': 'bugs' }, ] menu = [ { 'name': gettext('Metagame'), 'endpoint': 'home', 'badge': archetypes_badge, 'submenu': [ { 'name': gettext('Decks'), 'endpoint': '.decks' }, { 'name': gettext('Archetypes'), 'endpoint': 'archetypes', 'badge': archetypes_badge }, { 'name': gettext('People'), 'endpoint': 'people' }, { 'name': gettext('Cards'), 'endpoint': 'cards' }, { 'name': gettext('Past Seasons'), 'endpoint': 'seasons' }, { 'name': gettext('Matchups'), 'endpoint': 'matchups' }, ] }, { 'name': gettext('League'), 'endpoint': 'league', 'submenu': [ { 'name': gettext('League Info'), 'endpoint': 'league' }, { 'name': gettext('Sign Up'), 'endpoint': 'signup' }, { 'name': gettext('Report'), 'endpoint': 'report' }, { 'name': gettext('Records'), 'endpoint': 'current_league' }, { 'name': gettext('Retire'), 'endpoint': 'retire' }, ] }, { 'name': gettext('Competitions'), 'endpoint': 'competitions', 'submenu': [ { 'name': gettext('Competition Results'), 'endpoint': 'competitions' }, { 'name': gettext('Tournament Info'), 'endpoint': 'tournaments' }, { 'name': gettext('Leaderboards'), 'endpoint': 'tournament_leaderboards' }, { 'name': gettext('Gatherling'), 'url': 'https://gatherling.com/' }, { 'name': gettext('Achievements'), 'endpoint': 'achievements' }, { 'name': gettext('Hosting'), 'endpoint': 'hosting' }, ] }, { 'name': gettext('Resources'), 'endpoint': 'resources', 'submenu': resources_submenu }, { 'name': gettext('About'), 'endpoint': 'about', 'submenu': [ { 'name': gettext('What is Penny Dreadful?'), 'endpoint': 'about' }, { 'name': gettext('About pennydreadfulmagic.com'), 'endpoint': 'about_pdm' }, { 'name': gettext('FAQs'), 'endpoint': 'faqs' }, { 'name': gettext('Community Guidelines'), 'endpoint': 'community_guidelines' }, ] }, { 'name': gettext('Admin'), 'admin_only': True, 'endpoint': 'admin_home', 'submenu': admin.admin_menu() }, ] setup_links(menu) for item in menu: item['current'] = item.get('endpoint', '').replace( 'seasons', '').replace('.', '') == current_template or current_template in [ entry.get('endpoint', '') for entry in item.get('submenu', []) ] item['has_submenu'] = item.get('submenu') is not None return menu
def in_rotation() -> bool: if configuration.get_bool('always_show_rotation'): return True until_rotation = seasons.next_rotation() - dtutil.now() return until_rotation < datetime.timedelta(7)
def pd500_date() -> datetime.datetime: if seasons.next_rotation_ex().codename == '???': return datetime.datetime(1970, 1, 1) end_of_season = seasons.next_rotation() return end_of_season - datetime.timedelta(days=12, hours=13, minutes=30) # This effectively hardcodes a 10:30 PD Sat start time AND a Thu/Fri midnight rotation time.
import os import pathlib import shutil import subprocess from collections import Counter from typing import Dict, List, Set import ftfy from magic import card_price, fetcher, rotation, seasons from price_grabber.parser import PriceListType, parse_cardhoarder_prices, parse_mtgotraders_prices from shared import configuration, dtutil, fetch_tools from shared import redis_wrapper as redis from shared import repo, text TIME_UNTIL_ROTATION = seasons.next_rotation() - dtutil.now() BANNED_CARDS = ['Cleanse', 'Crusade'] # These cards are banned, even in Freeform def run() -> None: files = rotation.files() n = len(files) time_until = TIME_UNTIL_ROTATION - datetime.timedelta(weeks=1) if n >= rotation.TOTAL_RUNS: print( 'It is the moment of discovery, the triumph of the mind, and the end of this rotation.' ) return if n == 0 and TIME_UNTIL_ROTATION > datetime.timedelta(7):