Example #1
0
 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)]
Example #2
0
 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')
Example #3
0
 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)
Example #4
0
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)
Example #5
0
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.')
Example #6
0
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)
Example #7
0
 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
Example #9
0
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.
Example #11
0
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):