Exemple #1
0
def load_card(name):
    c = guarantee.exactly_one(oracle.load_cards([name]))
    c.decks = deck.load_decks(
        'd.id IN (SELECT deck_id FROM deck_card WHERE card = {name})'.format(
            name=sqlescape(name)))
    c.season = Container()
    c.all = Container()
    c.all.wins = sum(filter(None, [d.wins for d in c.decks]))
    c.all.losses = sum(filter(None, [d.losses for d in c.decks]))
    c.all.draws = sum(filter(None, [d.draws for d in c.decks]))
    if c.all.wins or c.all.losses or c.all.draws:
        c.all.win_percent = round(
            (c.all.wins / (c.all.wins + c.all.losses)) * 100, 1)
    else:
        c.all.win_percent = ''
    c.all.num_decks = len(c.decks)
    season_decks = [
        d for d in c.decks if d.created_date > rotation.last_rotation()
    ]
    c.season.wins = sum(filter(None, [d.wins for d in season_decks]))
    c.season.losses = sum(filter(None, [d.losses for d in season_decks]))
    c.season.draws = sum(filter(None, [d.draws for d in season_decks]))
    if c.season.wins or c.season.losses or c.season.draws:
        c.season.win_percent = round(
            (c.season.wins / (c.season.wins + c.season.losses)) * 100, 1)
    else:
        c.season.win_percent = ''
    c.season.num_decks = len(season_decks)
    c.played_competitively = c.all.wins or c.all.losses or c.all.draws
    return c
Exemple #2
0
def only_played_by(person_id: int,
                   season_id: Optional[int] = None) -> List[Card]:
    sql = """
        SELECT
            card AS name
        FROM
            deck_card AS dc
        INNER JOIN
            deck AS d ON dc.deck_id = d.id
        {season_join}
        WHERE
            deck_id
        IN
            (
                SELECT
                    DISTINCT deck_id
                FROM
                    deck_match
            ) -- Only include cards that actually got played competitively rather than just posted to Goldfish as "new cards this season" or similar.
        AND
            ({season_query})
        GROUP BY
            card
        HAVING
            COUNT(DISTINCT d.person_id) = 1
        AND
            MAX(d.person_id) = {person_id} -- In MySQL 5.7+ this could/should be ANY_VALUE not MAX but this works with any version. The COUNT(DISTINCT  p.id) ensures this only has one possible value but MySQL can't work that out.-- In MySQL 5.7+ this could/should be ANY_VALUE not MAX but this works with any version. The COUNT(DISTINCT  p.id) ensures this only has one possible value but MySQL can't work that out.
    """.format(season_join=query.season_join(),
               season_query=query.season_query(season_id),
               person_id=sqlescape(person_id))
    cards = {c.name: c for c in oracle.load_cards()}
    return [cards[r['name']] for r in db().execute(sql)]
Exemple #3
0
def test_split_cards() -> None:
    cards = oracle.load_cards(['Armed // Dangerous'])
    assert len(cards) == 1
    assert image_fetcher.download_image(cards) is not None
    names = command.parse_queries('[Toil // Trouble]', False)
    assert len(names) == 1
    results = command.results_from_queries(names)
    assert len(results) == 1
Exemple #4
0
def test_split_cards():
    cards = oracle.load_cards(['Armed // Dangerous'])
    assert len(cards) == 1
    assert image_fetcher.download_image(cards) is not None
    names = command.parse_queries('[Toil // Trouble]')
    assert len(names) == 1
    results = command.results_from_queries(names,
                                           whoosh_search.WhooshSearcher())[0]
    assert len(results) == 1
def test_deck_sort_x_last():
    cards = oracle.load_cards(
        ['Ghitu Fire', 'Flash of Insight', 'Frantic Search'])
    assert len(cards) == 3
    cards = {c.name: c for c in cards}
    assert oracle.deck_sort(cards.get('Ghitu Fire')) < oracle.deck_sort(
        cards.get('Flash of Insight'))
    assert oracle.deck_sort(cards.get('Ghitu Fire')) > oracle.deck_sort(
        cards.get('Frantic Search'))
Exemple #6
0
def test_deck_sort_x_last() -> None:
    cards = oracle.load_cards(
        ['Ghitu Fire', 'Flash of Insight', 'Frantic Search'])
    assert len(cards) == 3
    cards_by_name = {c.name: c for c in cards}
    assert oracle.deck_sort(cards_by_name['Ghitu Fire']) < oracle.deck_sort(
        cards_by_name['Flash of Insight'])
    assert oracle.deck_sort(cards_by_name['Ghitu Fire']) > oracle.deck_sort(
        cards_by_name['Frantic Search'])
Exemple #7
0
def only_played_by(person_id):
    sql = """
        SELECT card AS name, p.id
        FROM deck_card AS dc
        INNER JOIN deck AS d ON d.id = dc.deck_id
        INNER JOIN person AS p ON p.id = d.person_id
        GROUP BY card
        HAVING COUNT(DISTINCT p.id) = 1 AND p.id = {person_id} AND SUM(d.wins + d.draws + d.losses) > 0
    """.format(person_id=sqlescape(person_id))
    cs = [Container(r) for r in db().execute(sql)]
    cards = {c.name: c for c in oracle.load_cards()}
    for c in cs:
        c.update(cards[c.name])
    return cs
Exemple #8
0
def load_card(name: str, season_id: Optional[int] = None) -> Card:
    c = guarantee.exactly_one(oracle.load_cards([name]))
    c.decks = deck.load_decks('d.id IN (SELECT deck_id FROM deck_card WHERE card = {name})'.format(name=sqlescape(name)), season_id=season_id)
    c.all = Container()
    c.all_wins = sum(filter(None, [d.wins for d in c.decks]))
    c.all_losses = sum(filter(None, [d.losses for d in c.decks]))
    c.all_draws = sum(filter(None, [d.draws for d in c.decks]))
    if c.all_wins or c.all_losses:
        c.all_win_percent = round((c.all_wins / (c.all_wins + c.all_losses)) * 100, 1)
    else:
        c.all_win_percent = ''
    c.all_num_decks = len(c.decks)
    c.played_competitively = c.all_wins or c.all_losses or c.all_draws
    return c
Exemple #9
0
def fancy_cards():
    return legality.cards_legal_in_format(
        oracle.load_cards([
            'Mother of Runes', 'Treasure Cruise', 'Hymn to Tourach',
            'Hermit Druid', 'Frantic Search', 'Necropotence',
            'Tendrils of Agony', 'Hypergenesis', "Mind's Desire",
            'Recurring Nightmare', 'Worldgorger Dragon', 'Astral Slide',
            'Dark Ritual', 'Fact or Fiction', 'High Tide', "Nevinyrral's Disk",
            'Lake of the Dead', 'Braids, Cabal Minion', 'Channel',
            'Chain Lightning', 'Brain Freeze', 'Dragonstorm',
            'Day of Judgment', 'Cruel Ultimatum', 'Mana Leak',
            'Burning of Xinye', 'Psychatog', 'Smokestack', 'Llanowar Elves',
            'Animate Dead', 'Demonic Consultation'
        ]), 'Penny Dreadful')
Exemple #10
0
def image(c: str = '') -> Response:
    names = c.split('|')
    try:
        requested_cards = oracle.load_cards(names)
        path = image_fetcher.download_image(requested_cards)
        if path is None:
            raise InternalServerError(
                f'Failed to get image for {c}')  # type: ignore
        return send_file(
            os.path.abspath(path)
        )  # Send abspath to work around monolith root versus web root.
    except TooFewItemsException as e:
        print(e)
        return '', 400
def promo_explanation() -> Tuple[str, Dict[str, str]]:
    explanation = 'Some cards have promos that are much cheaper than all other versions. The bot reports the cheapest version in stock.\nOther bot chains will have copies.'
    have_cheap_promos = [
        'Barbarian Ring',
        'Buried Alive',
        'Crystal Vein',
        'Eureka',
        'Figure of Destiny',
        'Lake of the Dead',
    ]
    legal_cheap_promos = [c for c in oracle.load_cards(have_cheap_promos) if c.pd_legal]
    if len(legal_cheap_promos) > 0:
        explanation += ' Affected cards include: ' + ', '.join(c.name for c in legal_cheap_promos)
    return(explanation, {})
Exemple #12
0
def image(c: str = '') -> wrappers.Response:
    names = c.split('|')
    try:
        requested_cards = oracle.load_cards(names)
        path = image_fetcher.download_image(requested_cards)
        if path is None:
            raise InternalServerError(f'Failed to get image for {c}')
        return send_file(
            os.path.abspath(path)
        )  # Send abspath to work around monolith root versus web root.
    except TooFewItemsException as e:
        logger.info(f'Did not find an image for {c}: {e}')
        if len(names) == 1:
            return redirect(
                f'https://api.scryfall.com/cards/named?exact={c}&format=image',
                code=303)
        return make_response('', 400)
def vivify(decklist):
    validated, invalid_names = {'maindeck': {}, 'sideboard': {}}, set()
    for section in ['maindeck', 'sideboard']:
        for name, n in decklist[section].items():
            try:
                validated[section][oracle.valid_name(name)] = n
            except InvalidDataException:
                invalid_names.add(name)
    if invalid_names:
        raise InvalidDataException('Invalid cards: {invalid_names}'.format(invalid_names='; '.join(invalid_names)))
    validated_names = list(validated['maindeck'].keys()) + list(validated['sideboard'].keys())
    cards = {c.name: c for c in oracle.load_cards(validated_names)}
    d = Deck({'maindeck': [], 'sideboard': []})
    for section in ['maindeck', 'sideboard']:
        for name, n in validated[section].items():
            d[section].append({'n': n, 'name': name, 'card': cards[name]})
    return d
Exemple #14
0
def image(c: str = '') -> Union[Tuple[str, int], wrappers.Response]:
    names = c.split('|')
    try:
        requested_cards = oracle.load_cards(names)
        path = image_fetcher.download_image(requested_cards)
        if path is None:
            raise InternalServerError(
                f'Failed to get image for {c}')  # type: ignore
        return send_file(
            os.path.abspath(path)
        )  # Send abspath to work around monolith root versus web root.
    except TooFewItemsException as e:
        print(e)
        if len(names) == 1:
            return redirect(
                f'https://api.scryfall.com/cards/named?exact={c}&format=image',
                code=303)
        return '', 400
def load_card(name: str, season_id: Optional[int] = None) -> Card:
    c = guarantee.exactly_one(oracle.load_cards([name]))
    c.decks = deck.load_decks(query.card_where(name), season_id=season_id)
    c.wins, c.losses, c.draws, c.tournament_wins, c.tournament_top8s, c.perfect_runs = 0, 0, 0, 0, 0, 0
    for d in c.decks:
        c.wins += d.get('wins', 0)
        c.losses += d.get('losses', 0)
        c.draws += d.get('draws', 0)
        c.tournament_wins += 1 if d.get('finish') == 1 else 0
        c.tournament_top8s += 1 if (d.get('finish') or sys.maxsize) <= 8 else 0
        c.perfect_runs += 1 if d.get('source_name') == 'League' and d.get('wins', 0) >= 5 and d.get('losses', 0) == 0 else 0
    if c.wins or c.losses:
        c.win_percent = round((c.wins / (c.wins + c.losses)) * 100, 1)
    else:
        c.win_percent = ''
    c.num_decks = len(c.decks)
    c.played_competitively = c.wins or c.losses or c.draws
    return c
Exemple #16
0
def load_card(name: str, season_id: Optional[int] = None) -> Card:
    c = guarantee.exactly_one(oracle.load_cards([name]))
    c.decks = deck.load_decks(
        'd.id IN (SELECT deck_id FROM deck_card WHERE card = {name})'.format(
            name=sqlescape(name)),
        season_id=season_id)
    c.all_wins, c.all_losses, c.all_draws, c.all_tournament_wins, c.all_tournament_top8s, c.all_perfect_runs = 0, 0, 0, 0, 0, 0
    for d in c.decks:
        c.all_wins += d.get('wins', 0)
        c.all_losses += d.get('losses', 0)
        c.all_draws += d.get('draws', 0)
        c.all_tournament_wins += 1 if d.get('finish') == 1 else 0
        c.all_tournament_top8s += 1 if (d.get('finish')
                                        or sys.maxsize) <= 8 else 0
        c.all_perfect_runs += 1 if d.get('source_name') == 'League' and d.get(
            'wins', 0) >= 5 and d.get('losses', 0) == 0 else 0
    if c.all_wins or c.all_losses:
        c.all_win_percent = round(
            (c.all_wins / (c.all_wins + c.all_losses)) * 100, 1)
    else:
        c.all_win_percent = ''
    c.all_num_decks = len(c.decks)
    c.played_competitively = c.all_wins or c.all_losses or c.all_draws
    return c
 def __init__(self, exception):
     self.exception = str(exception)
     self.card = random.choice(oracle.load_cards(where="c.name LIKE '%%Lost%%'"))
     self.cards = [self.card]
 def __init__(self, person: ps.Person, cards: List[Card],
              archetypes: List[Archetype], all_archetypes: List[Archetype],
              your_cards: Dict[str,
                               List[str]], seasons_active: Sequence[int],
              season_id: Optional[int]) -> None:
     super().__init__()
     self.all_archetypes = all_archetypes
     self.person = person
     self.people = [person]
     self.decks = person.decks
     self.has_decks = len(person.decks) > 0
     self.archetypes = archetypes
     self.hide_person = True
     self.cards = cards
     self.show_seasons = True
     self.displayed_achievements = [{
         'title':
         a.title,
         'detail':
         titlecase.titlecase(a.display(self.person))
     } for a in Achievement.all_achievements if a.display(self.person)]
     self.achievements_url = url_for('.achievements')
     self.person_achievements_url = url_for('.person_achievements',
                                            person_id=person.id)
     colors: Dict[str, int] = {}
     for d in self.decks:
         for c in d.colors:
             colors[c] = colors.get(c, 0) + 1
     self.charts = [
         {
             'title':
             'Colors Played',
             'type':
             'horizontalBar',
             'labels':
             json.dumps(
                 ['White', 'Blue', 'Black', 'Red', 'Green', 'Colorless']),
             'series':
             json.dumps([
                 colors.get('W'),
                 colors.get('U'),
                 colors.get('B'),
                 colors.get('R'),
                 colors.get('G'),
                 colors.get('C')
             ]),
             'options':
             json.dumps({
                 'responsive': True,
                 'scales': {
                     'xAxes': [{
                         'ticks': {
                             'precision': 0
                         }
                     }]
                 }
             }),  # Only display whole numbers on x axis.
         },
     ]
     self.add_note_url = url_for('post_player_note')
     self.matches_url = url_for(
         '.person_matches',
         person_id=person.id,
         season_id=None
         if season_id == seasons.current_season_num() else season_id)
     self.is_person_page = True
     self.trailblazer_cards = oracle.load_cards(your_cards['trailblazer'])
     self.has_trailblazer_cards = len(self.trailblazer_cards) > 0
     self.unique_cards = oracle.load_cards(your_cards['unique'])
     self.has_unique_cards = len(self.unique_cards) > 0
     self.cards += self.trailblazer_cards + self.unique_cards
     self.setup_active_seasons(seasons_active)
 def __init__(self, exception):
     self.exception = str(exception)
     self.card = random.choice(
         oracle.load_cards(
             ['Erratic Explosion', 'Curse of Chaos', 'Anarchy']))
     self.cards = [self.card]
Exemple #20
0
def test_load_cards() -> None:
    cards = oracle.load_cards(['Think Twice', 'Swamp'])
    assert len(cards) == 2
    assert 'Think Twice' in [c.name for c in cards]
    assert 'Swamp' in [c.name for c in cards]