예제 #1
0
파일: api_v2.py 프로젝트: Feriority/lrrbot
async def cardviewer_announce(session):
    if not flask.request.is_json:
        return flask.jsonify(message="Request not JSON"), 400

    req = flask.request.get_json()

    cards = server.db.metadata.tables['cards']
    card_multiverse = server.db.metadata.tables['card_multiverse']

    query = sqlalchemy.select([cards.c.id, cards.c.name, cards.c.text])

    if 'multiverseid' in req:
        query = query.select_from(cards.join(card_multiverse)).where(
            card_multiverse.c.id == req['multiverseid'])
    elif 'name' in req:
        name = cardname.to_query(req['name'])
        exact = cardname.clean_text(req['name'])
        hidden = False
        if 'variant' in req:
            name += escape_like("_" + req['variant'])
            exact += "_" + req['variant']
            hidden = True

        exact_query = sqlalchemy.exists().where(cards.c.filteredname == exact)
        if not hidden:
            exact_query = exact_query.where(~cards.c.hidden)

        query = query.where((exact_query & (cards.c.filteredname == exact))
                            | (~exact_query
                               & cards.c.filteredname.ilike(name)))
        if not hidden:
            query = query.where(~cards.c.hidden)
    elif 'host' in req or 'augment' in req:
        name = ""
        if 'augment' in req:
            name += cardname.to_query(req['augment']) + escape_like("_aug")
        if 'host' in req:
            name += ("_" if name != "" else "") + cardname.to_query(
                req['host']) + escape_like("_host")
        query = query.where(cards.c.filteredname.ilike(name))
    else:
        return flask.jsonify(message=""), 400

    with server.db.engine.begin() as conn:
        cards = conn.execute(query).fetchall()

    if len(cards) == 0:
        return flask.jsonify(message="No such card"), 400
    elif len(cards) > 1:
        return flask.jsonify(message="Matched multiple cards"), 400

    card_id, name, text = cards[0]

    await common.rpc.bot.cardviewer.announce(card_id)

    return flask.jsonify(
        name=name,
        text=text,
    )
예제 #2
0
파일: api_v2.py 프로젝트: andreasots/lrrbot
async def cardviewer_announce(session):
	if not flask.request.is_json:
		return flask.jsonify(message="Request not JSON"), 400
	
	req = flask.request.get_json()
	log.debug("Received cardviewer: %r", req)

	cards = server.db.metadata.tables['cards']
	card_multiverse = server.db.metadata.tables['card_multiverse']

	query = sqlalchemy.select([cards.c.id, cards.c.name, cards.c.text])

	if 'multiverseid' in req:
		query = query.select_from(cards.join(card_multiverse)).where(card_multiverse.c.id == req['multiverseid'])
	elif 'name' in req:
		name = cardname.to_query(req['name'])
		exact = cardname.clean_text(req['name'])
		hidden = False
		if 'variant' in req:
			name += escape_like("_" + req['variant'])
			exact += "_" + req['variant']
			hidden = True

		exact_query = sqlalchemy.exists().where(cards.c.filteredname == exact)
		if not hidden:
			exact_query = exact_query.where(~cards.c.hidden)

		query = query.where(
			(exact_query & (cards.c.filteredname == exact))
				| (~exact_query & cards.c.filteredname.ilike(name)))
		if not hidden:
			query = query.where(~cards.c.hidden)
	elif 'host' in req or 'augment' in req:
		name = ""
		if 'augment' in req:
			name += cardname.to_query(req['augment']) + escape_like("_aug")
		if 'host' in req:
			name += ("_" if name != "" else "") + cardname.to_query(req['host']) + escape_like("_host")
		query = query.where(cards.c.filteredname.ilike(name))
	else:
		return flask.jsonify(message=""), 400

	with server.db.engine.begin() as conn:
		cards = conn.execute(query).fetchall()

	if len(cards) == 0:
		return flask.jsonify(message="No such card"), 400
	elif len(cards) > 1:
		return flask.jsonify(message="Matched multiple cards"), 400

	card_id, name, text = cards[0]

	await common.rpc.bot.cardviewer.announce(card_id)

	return flask.jsonify(
		name=name,
		text=text,
	)
예제 #3
0
파일: card.py 프로젝트: Feriority/lrrbot
def find_card(lrrbot, search, includehidden=False):
	cards = lrrbot.metadata.tables["cards"]
	card_multiverse = lrrbot.metadata.tables["card_multiverse"]
	card_collector = lrrbot.metadata.tables["card_collector"]

	if isinstance(search, int):
		query = (sqlalchemy.select([cards.c.name, cards.c.text])
						.select_from(card_multiverse.join(cards, cards.c.id == card_multiverse.c.cardid))
						.where(card_multiverse.c.id == search))
		if not includehidden:
			query = query.where(cards.c.hidden == False)
		with lrrbot.engine.begin() as conn:
			return conn.execute(query).fetchall()

	if isinstance(search, tuple):
		query = (sqlalchemy.select([cards.c.name, cards.c.text])
						.select_from(card_collector.join(cards, cards.c.id == card_collector.c.cardid))
						.where((card_collector.c.setid == search[0].lower()) & (card_collector.c.collector == search[1])))
		if not includehidden:
			query = query.where(cards.c.hidden == False)
		with lrrbot.engine.begin() as conn:
			return conn.execute(query).fetchall()

	cleansearch = clean_text(search)
	with lrrbot.engine.begin() as conn:
		query = sqlalchemy.select([cards.c.name, cards.c.text]).where(cards.c.filteredname == cleansearch)
		if not includehidden:
			query = query.where(cards.c.hidden == False)
		rows = conn.execute(query).fetchall()
		if rows:
			return rows

		searchwords = search.split()
		searchwords = [clean_text(i) for i in searchwords]
		searchlike = "%" + "%".join(common.postgres.escape_like(i) for i in searchwords) + "%"
		query = sqlalchemy.select([cards.c.name, cards.c.text]).where(cards.c.filteredname.like(searchlike))
		if not includehidden:
			query = query.where(cards.c.hidden == False)
		return conn.execute(query).fetchall()
예제 #4
0
def process_card(card, expansion):
    if card.get('layout') == 'split':
        # Return split cards as a single card... for all the other pieces, return nothing
        if card['name'] != card['names'][0]:
            return None, None, None, None
        splits = []
        for splitname in card['names']:
            candidates = [
                i for i in expansion['cards'] if i['name'] == splitname
            ]
            if not candidates:
                print("Can't find split card piece: %s" % splitname)
                sys.exit(1)
            splits.append(candidates[0])
        card = {}
        card['name'] = ' // '.join(s['name'] for s in splits)
        card['manaCost'] = ' // '.join(s['manaCost'] for s in splits)
        card['type'] = splits[0]['type']  # should be the same for all splits
        card['text'] = ' // '.join(s['text'] for s in splits)
        multiverseids = [
            s['multiverseid'] for s in splits if s.get('multiverseid')
        ]
    elif card.get('layout') == 'flip':
        if card['name'] == card['names'][0] and card.get('multiverseid'):
            multiverseids = [card['multiverseid']]
        else:
            multiverseids = []
    else:
        if card.get('multiverseid'):
            multiverseids = [card['multiverseid']]
        else:
            multiverseids = []

    # sanitise card name
    name = clean_text(card["name"])
    if not re_check.match(name):
        print("Still some junk left in name %s (%s)" %
              (card['name'], json.dumps(name)))
        sys.exit(1)

    def build_description():
        yield card['name']
        if 'manaCost' in card:
            yield ' ['
            yield re_mana.sub(r"\1", card['manaCost'])
            yield ']'
        if card.get('layout') == 'flip':
            if card['name'] == card['names'][0]:
                yield ' (flip: '
                yield card['names'][1]
                yield ')'
            else:
                yield ' (unflip: '
                yield card['names'][0]
                yield ')'
        elif card.get('layout') == 'double-faced':
            if card['name'] == card['names'][0]:
                yield ' (back: '
                yield card['names'][1]
                yield ')'
            else:
                yield ' (front: '
                yield card['names'][0]
                yield ')'
        elif card.get('layout') == 'meld':
            # Only the melded card in MTGJSON has all three cards in the 'names' field
            # The front-face cards only have [me, back]
            melded_card = [
                i for i in expansion['cards'] if i['name'] == card['names'][-1]
            ]
            if not melded_card:
                print("Can't find melded card: %s" % card['names'][-1])
                sys.exit(1)
            melded_card = melded_card[0]
            # MTGJSON doesn't have this field in a consistent order...
            # some cards have [top, bottom, back] some have [bottom, top, back]
            part_cards = [
                i for i in expansion['cards']
                if i['name'] in melded_card['names'][:-1]
            ]
            if len(part_cards) != 2:
                print("Can't find part-cards for melded card: %s" %
                      melded_card['name'])
                sys.exit(1)
            if melded_card['number'][-1] != 'b':
                print("Melded card's number doesn't end in 'b': %s" %
                      melded_card['name'])
                sys.exit(1)
            if part_cards[0]['number'] == melded_card['number'][:-1] + 'a':
                bottom_card, top_card = part_cards
            elif part_cards[1]['number'] == melded_card['number'][:-1] + 'a':
                top_card, bottom_card = part_cards
            else:
                print(
                    "Couldn't figure out which card was top and bottom for: %s"
                    % melded_card['name'])
                sys.exit(1)
            if card['name'] == top_card['name']:
                # The names of what this melds with and into are in the card text
                pass
            elif card['name'] == bottom_card['name']:
                yield ' (melds with: '
                yield top_card['name']
                yield '; into: '
                yield melded_card['name']
                yield ')'
            elif card['name'] == melded_card['name']:
                yield ' (melds from: '
                yield top_card['name']
                yield '; '
                yield bottom_card['name']
                yield ')'
        yield ' | '
        yield card.get('type', '?Type missing?')
        if 'power' in card or 'toughness' in card:
            yield ' ['
            yield card.get('power', '?')
            yield '/'
            yield card.get('toughness', '?')
            yield ']'
        if 'loyalty' in card:
            yield ' ['
            yield str(card['loyalty'])
            yield ']'
        if 'hand' in card or 'life' in card:
            yield ' [hand:'
            yield str(card.get('hand', '?'))
            yield '/life:'
            yield str(card.get('life', '?'))
            yield ']'
        if 'text' in card:
            yield ' | '
            yield re_newlines.sub(
                ' / ',
                re_remindertext.sub(
                    lambda match: ' '
                    if match.group(1) and match.group(2) else '',
                    card['text']).strip())

    desc = ''.join(build_description())
    desc = re_multiplespaces.sub(' ', desc).strip()
    if len(desc) > MAXLEN:
        desc = desc[:MAXLEN - 1] + "\u2026"

    return name, desc, multiverseids, card.get('number')
예제 #5
0
def process_single_card(card, expansion, include_reminder=False):
	# sanitise card name
	filtered = clean_text(card.get('internalname', card["name"]))
	if not re_check.match(filtered):
		print("Still some junk left in name %s (%s)" % (card.get('internalname', card["name"]), json.dumps(filtered)))
		print(json.dumps(card))
		sys.exit(1)

	def build_description():
		yield card['name']
		if 'manaCost' in card:
			yield ' ['
			yield re_mana.sub(r"\1", card['manaCost'])
			yield ']'
		if card.get('layout') == 'flip':
			if card['name'] == card['names'][0]:
				yield ' (flip: '
				yield card['names'][1]
				yield ')'
			else:
				yield ' (unflip: '
				yield card['names'][0]
				yield ')'
		elif card.get('layout') == 'transform':
			if card['name'] == card['names'][0]:
				yield ' (back: '
				yield card['names'][1]
				yield ')'
			else:
				yield ' (front: '
				yield card['names'][0]
				yield ')'
		elif card.get('layout') == 'meld':
			card_a, melded_card, card_b = card['names']
			if card['name'] in (card_a, card_b):
				# mtgjson is inconsistent as to which of these is which
				# check if "melds with cardname" is in the card text
				if card['name'] == card_a:
					other_card = card_b
				else:
					other_card = card_a
				if '(Melds with %s.)' % other_card in card['text']:
					yield ' (melds with: '
					yield other_card
					yield '; into: '
					yield melded_card
					yield ')'
				else:
					# The names of what this melds with and into are in the rules text
					pass
			elif card['name'] == melded_card:
				yield ' (melds from: '
				yield card_a
				yield '; '
				yield card_b
				yield ')'
		yield ' | '
		yield card.get('type', '?Type missing?')
		if 'power' in card or 'toughness' in card:
			yield ' ['
			yield card.get('power', '?')
			yield '/'
			yield card.get('toughness', '?')
			yield ']'
		if 'loyalty' in card:
			yield ' ['
			yield str(card['loyalty'])
			yield ']'
		if 'hand' in card or 'life' in card:
			yield ' [hand: '
			if 'hand' in card:
				yield card['hand']
			else:
				yield "?"
			yield ', life: '
			if 'life' in card:
				yield card['life']
			else:
				yield "?"
			yield ']'
		if 'text' in card:
			yield ' | '
			yield process_text(card['text'], include_reminder)

	desc = ''.join(build_description())
	desc = re_multiplespaces.sub(' ', desc).strip()
	desc = utils.trim_length(desc)

	if card.get('layout') == 'flip' and card['name'] != card['names'][0]:
		multiverseids = numbers = []
	else:
		if card.get('layout') == 'transform':
			if card['name'] == card['names'][0]:
				if card.get('number') and 'a' not in card['number'] and 'b' not in card['number']:
					card['number'] = [card['number'], card['number'] + 'a']
			else:
				if card.get('number') and 'a' not in card['number'] and 'b' not in card['number']:
					card['number'] = card['number'] + 'b'
				card['foreignData'] = []  # mtgjson doesn't seem to have accurate foreign multiverse ids for back faces
		multiverseids = [card['multiverseId']] if card.get('multiverseId') else []
		# disabling adding foreign multiverse ids unless we decide we want them for some reason
		# they add a lot of time to the running of this script
		#for lang in card.get('foreignData', []):
		#	if lang.get('multiverseId'):
		#		multiverseids.append(lang['multiverseId'])
		numbers = card['number'] if card.get('number') else []
		if not isinstance(numbers, list):
			numbers = [numbers]
	hidden = 'internalname' in card

	# if a card has multiple variants, make "number" entries for the variants
	# to match what sort of thing we'd be seeing on scryfall
	if len(multiverseids) > 1 and len(numbers) == 1:
		orig_number = numbers[0]
		for i in range(len(multiverseids)):
			numbers.append(orig_number + chr(ord('a') + i))

	numbers = [(expansion['code'].lower(), i) for i in numbers]

	return filtered, card['name'], desc, multiverseids, numbers, hidden
예제 #6
0
def process_single_card(card, expansion, include_reminder=False):
    # sanitise card name
    filtered = clean_text(card.get('internalname', card["name"]))
    if not re_check.match(filtered):
        print("Still some junk left in name %s (%s)" %
              (card.get('internalname', card["name"]), json.dumps(filtered)))
        print(json.dumps(card))
        sys.exit(1)

    def build_description():
        yield card['name']
        if 'manaCost' in card:
            yield ' ['
            yield re_mana.sub(r"\1", card['manaCost'])
            yield ']'
        if card.get('layout') == 'flip':
            if card['name'] == card['names'][0]:
                yield ' (flip: '
                yield card['names'][1]
                yield ')'
            else:
                yield ' (unflip: '
                yield card['names'][0]
                yield ')'
        elif card.get('layout') == 'double-faced':
            if card['name'] == card['names'][0]:
                yield ' (back: '
                yield card['names'][1]
                yield ')'
            else:
                yield ' (front: '
                yield card['names'][0]
                yield ')'
        elif card.get('layout') == 'meld':
            top_card, bottom_card, melded_card = card['names']
            if card['name'] == top_card:
                # The names of what this melds with and into are in the card text
                pass
            elif card['name'] == bottom_card:
                yield ' (melds with: '
                yield top_card
                yield '; into: '
                yield melded_card
                yield ')'
            elif card['name'] == melded_card:
                yield ' (melds from: '
                yield top_card
                yield '; '
                yield bottom_card
                yield ')'
        yield ' | '
        yield card.get('type', '?Type missing?')
        if 'power' in card or 'toughness' in card:
            yield ' ['
            yield card.get('power', '?')
            yield '/'
            yield card.get('toughness', '?')
            yield ']'
        if 'loyalty' in card:
            yield ' ['
            yield str(card['loyalty'])
            yield ']'
        if 'hand' in card or 'life' in card:
            yield ' [hand: '
            if 'hand' in card:
                yield "%+d" % card['hand']
            else:
                yield "?"
            yield ', life: '
            if 'life' in card:
                yield "%+d" % card['life']
            else:
                yield "?"
            yield ']'
        if 'text' in card:
            yield ' | '
            text = card['text']
            # Let Un-set cards keep their reminder text, since there's joeks in there
            if not include_reminder:
                text = re_remindertext.sub(
                    lambda match: ' '
                    if match.group(1) and match.group(2) else '', text)
            yield re_newlines.sub(' / ', text.strip())

    desc = ''.join(build_description())
    desc = re_multiplespaces.sub(' ', desc).strip()
    desc = utils.trim_length(desc)

    if card.get('layout') == 'flip' and card['name'] != card['names'][0]:
        multiverseids = numbers = []
    else:
        multiverseids = [card['multiverseid']
                         ] if card.get('multiverseid') else []
        if card.get('variations'):
            multiverseids.extend(card['variations'])
        numbers = card['number'] if card.get('number') else []
        if not isinstance(numbers, list):
            numbers = [numbers]
    hidden = 'internalname' in card

    # if a card has multiple variants, make "number" entries for the variants
    # to match what sort of thing we'd be seeing on scryfall
    if len(multiverseids) > 1 and len(numbers) == 1:
        orig_number = numbers[0]
        for i in range(len(multiverseids)):
            numbers.append(orig_number + chr(ord('a') + i))

    numbers = [(expansion['code'].lower(), i) for i in numbers]

    return filtered, card['name'], desc, multiverseids, numbers, hidden
예제 #7
0
def process_card(card, expansion):
	if card.get('layout') == 'split':
		# Return split cards as a single card... for all the other pieces, return nothing
		if card['name'] != card['names'][0]:
			return None, None, None, None
		splits = []
		for splitname in card['names']:
			candidates = [i for i in expansion['cards'] if i['name'] == splitname]
			if not candidates:
				print("Can't find split card piece: %s" % splitname)
				sys.exit(1)
			splits.append(candidates[0])
		card = {}
		card['name'] = ' // '.join(s['name'] for s in splits)
		card['manaCost'] = ' // '.join(s['manaCost'] for s in splits)
		card['type'] = splits[0]['type'] # should be the same for all splits
		card['text'] = ' // '.join(s['text'] for s in splits)
		multiverseids = [s['multiverseid'] for s in splits if s.get('multiverseid')]
	elif card.get('layout') == 'flip':
		if card['name'] == card['names'][0] and card.get('multiverseid'):
			multiverseids = [card['multiverseid']]
		else:
			multiverseids = []
	else:
		if card.get('multiverseid'):
			multiverseids = [card['multiverseid']]
		else:
			multiverseids = []

	# sanitise card name
	name = clean_text(card["name"])
	if not re_check.match(name):
		print("Still some junk left in name %s (%s)" % (card['name'], json.dumps(name)))
		sys.exit(1)

	def build_description():
		yield card['name']
		if 'manaCost' in card:
			yield ' ['
			yield re_mana.sub(r"\1", card['manaCost'])
			yield ']'
		if card.get('layout') == 'flip':
			if card['name'] == card['names'][0]:
				yield ' (flip: '
				yield card['names'][1]
				yield ')'
			else:
				yield ' (unflip: '
				yield card['names'][0]
				yield ')'
		elif card.get('layout') == 'double-faced':
			if card['name'] == card['names'][0]:
				yield ' (back: '
				yield card['names'][1]
				yield ')'
			else:
				yield ' (front: '
				yield card['names'][0]
				yield ')'
		elif card.get('layout') == 'meld':
			if card['name'] == card['names'][0]:
				# The names of what this melds with and into are in the card text
				pass
			elif card['name'] == card['names'][1]:
				yield ' (melds with: '
				yield card['names'][0]
				yield '; into: '
				yield card['names'][2]
				yield ')'
			elif card['name'] == card['names'][2]:
				yield ' (melds from: '
				yield card['names'][0]
				yield '; '
				yield card['names'][1]
				yield ')'
		yield ' | '
		yield card.get('type', '?Type missing?')
		if 'power' in card or 'toughness' in card:
			yield ' ['
			yield card.get('power', '?')
			yield '/'
			yield card.get('toughness', '?')
			yield ']'
		if 'loyalty' in card:
			yield ' ['
			yield str(card['loyalty'])
			yield ']'
		if 'hand' in card or 'life' in card:
			yield ' [hand:'
			yield str(card.get('hand', '?'))
			yield '/life:'
			yield str(card.get('life', '?'))
			yield ']'
		if 'text' in card:
			yield ' | '
			yield re_newlines.sub(' / ', re_remindertext.sub('', card['text']).strip())

	desc = ''.join(build_description())
	desc = re_multiplespaces.sub(' ', desc).strip()
	if len(desc) > MAXLEN:
		desc = desc[:MAXLEN-1] + "\u2026"

	return name, desc, multiverseids, card.get('number')