def report(form: ReportForm) -> bool: try: db().get_lock('deck_id:{id}'.format(id=form.entry)) db().get_lock('deck_id:{id}'.format(id=form.opponent)) for m in match.get_matches(form): if int(form.opponent) == m.opponent_deck_id: form.errors[ 'result'] = 'This match was reported as You {game_wins}–{game_losses} {opponent} {date}'.format( game_wins=m.game_wins, game_losses=m.game_losses, opponent=m.opponent, date=dtutil.display_date(m.date)) return False counts = deck.count_matches(form.entry, form.opponent) if counts[int(form.entry)] >= 5: form.errors['entry'] = 'You already have 5 matches reported' return False if counts[int(form.opponent)] >= 5: form.errors[ 'opponent'] = 'Your opponent already has 5 matches reported' return False pdbot = form.get('api_token', None) == configuration.get('pdbot_api_token') if pdbot: mtgo_match_id = form.get('matchID', None) else: mtgo_match_id = None entry_name = deck.load_deck(int(form.entry)).person opp_name = deck.load_deck(int(form.opponent)).person fetcher.post_discord_webhook( configuration.get_str('league_webhook_id'), configuration.get_str('league_webhook_token'), '{entry} reported {f.entry_games}-{f.opponent_games} vs {opponent}' .format(f=form, entry=entry_name, opponent=opp_name)) db().begin() match.insert_match(dtutil.now(), form.entry, form.entry_games, form.opponent, form.opponent_games, None, None, mtgo_match_id) db().commit() return True except LockNotAcquiredException: form.errors[ 'entry'] = 'Cannot report right now, somebody else is reporting a match for you or your opponent. Try again a bit later' return False finally: db().release_lock('deck_id:{id}'.format(id=form.opponent)) db().release_lock('deck_id:{id}'.format(id=form.entry))
def tournament_deck(cells: ResultSet, competition_id: int, date: datetime.datetime, final: Dict[str, int]) -> Optional[deck.Deck]: d: deck.RawDeckDescription = { 'source': 'Gatherling', 'competition_id': competition_id, 'created_date': dtutil.dt2ts(date) } player = cells[2] username = aliased(player.a.contents[0].string) d['mtgo_username'] = username d['finish'] = final.get(username) link = cells[4].a d['url'] = gatherling_url(link['href']) d['name'] = link.string if cells[5].find('a'): d['archetype'] = cells[5].a.string else: d['archetype'] = cells[5].string gatherling_id = urllib.parse.parse_qs( urllib.parse.urlparse(str(d['url'])).query)['id'][0] d['identifier'] = gatherling_id existing = deck.get_deck_id(d['source'], d['identifier']) if existing is not None: return deck.load_deck(existing) dlist = decklist.parse( fetcher.internal.post(gatherling_url('deckdl.php'), {'id': gatherling_id})) d['cards'] = dlist if len(dlist['maindeck']) + len(dlist['sideboard']) == 0: logger.warning( 'Rejecting deck with id {id} because it has no cards.'.format( id=gatherling_id)) return None return deck.add_deck(d)
def export(deck_id): d = ds.load_deck(deck_id) if d.is_in_current_run(): if not auth.person_id() or auth.person_id() != d.person_id: abort(403) safe_name = deck_name.file_name(d) return (mc.to_mtgo_format(str(d)), 200, {'Content-type': 'text/plain; charset=utf-8', 'Content-Disposition': 'attachment; filename={name}.txt'.format(name=safe_name)})
def cmc(deck_id): name = str(deck_id) + '-cmc.png' if not os.path.exists(configuration.get('charts_dir')): raise DoesNotExistException( 'Cannot store graph images because {dir} does not exist.'.format( dir=configuration.get('charts_dir'))) path = os.path.join(configuration.get('charts_dir'), name) if os.path.exists(path): return path d = deck.load_deck(deck_id) costs = {} for ci in d.maindeck: c = ci.get('card') if c.is_land(): continue if c.mana_cost is None: cost = '0' elif next((s for s in c.mana_cost if '{X}' in s), None) is not None: cost = 'X' else: cost = int(float(c.cmc)) if cost >= 7: cost = '7+' cost = str(cost) costs[cost] = ci.get('n') + costs.get(cost, 0) return image(path, costs)
def do_admin_retire_deck() -> wrappers.Response: form = RetireForm(request.form) if form.validate(): d = ds.load_deck(form.entry) lg.retire_deck(d) return redirect(url_for('admin_retire_deck')) return make_response(admin_retire_deck(form))
def cmc(deck_id: int, attempts: int = 0) -> str: if attempts > 3: msg = 'Unable to generate cmc chart for {id} in 3 attempts.'.format( id=deck_id) logger.error(msg) raise OperationalException(msg) path = determine_path(str(deck_id) + '-cmc.png') if acceptable_file(path): return path d = deck.load_deck(deck_id) costs: Dict[str, int] = {} for ci in d.maindeck: c = ci.card if c.is_land(): continue if c.mana_cost is None: cost = '0' elif next((s for s in c.mana_cost if '{X}' in s), None) is not None: cost = 'X' else: converted = int(float(c.cmc)) cost = '7+' if converted >= 7 else str(converted) costs[cost] = ci.get('n') + costs.get(cost, 0) path = image(path, costs) if acceptable_file(path): return path return cmc(deck_id, attempts + 1)
def retire_deck() -> Union[str, Response]: form = RetireForm(request.form, discord_user=session.get('id')) if form.validate(): d = ds.load_deck(form.entry) ps.associate(d, session['id']) lg.retire_deck(d) return redirect(url_for('signup')) return retire(form)
def export(deck_id): d = deck.load_deck(deck_id) safe_name = deck_name.file_name(d) return (str(d), 200, { 'Content-type': 'text/plain; charset=utf-8', 'Content-Disposition': 'attachment; filename={name}.txt'.format(name=safe_name) })
def store_deck(d: deck.Deck) -> deck.Deck: d['source'] = d['source_name'] d['url'] = d['source_url'] existing = deck.get_deck_id(d['source'], d['identifier']) if existing is not None: return deck.load_deck(existing) d['mtgo_username'] = d['person'] d['cards'] = decklist.unvivify(d) return deck.add_deck(d)
def deck(deck_id): d = ds.load_deck(deck_id) if auth.discord_id() and auth.logged_person() is None and not d.is_person_associated(): ps.associate(d, auth.discord_id()) p = ps.load_person_by_discord_id(auth.discord_id()) auth.log_person(p) view = Deck(d, auth.logged_person()) return view.page()
def deck_embed(deck_id: int) -> Response: # Discord doesn't actually show this yet. I've reached out to them for better documentation about what they do/don't accept. d = deck.load_deck(deck_id) view = DeckEmbed(d, None, None) width = 1200 height = 500 embed = { 'type': 'rich', 'version': '1.0', 'title': view.page_title(), 'width': width, 'height': height, 'html': template.render(view) } return return_json(embed)
def deck_api(deck_id): blob = deck.load_deck(deck_id) return return_json(blob)
def deck(deck_id: int) -> str: d = ds.load_deck(deck_id) view = Deck(d, auth.person_id(), auth.discord_id()) return view.page()
def deck_api(deck_id: int) -> Response: blob = deck.load_deck(deck_id) return return_json(blob)
def decks(deck_id): view = Deck(deck.load_deck(deck_id)) return view.page()
def get(self, deck_id: int) -> Deck: return deck.load_deck(deck_id)