Example #1
0
def find_card(lrrbot, search, includehidden=False, game=CARD_GAME_MTG):
    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)
        if game is not None:
            query = query.where(cards.c.game == game)
        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)
        if game is not None:
            query = query.where(cards.c.game == game)
        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)
        if game is not None:
            query = query.where(cards.c.game == game)
        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)
        if game is not None:
            query = query.where(cards.c.game == game)
        return conn.execute(query).fetchall()
Example #2
0
def find_card(lrrbot, search, includehidden=False, game=CARD_GAME_MTG):
	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)
		if game is not None:
			query = query.where(cards.c.game == game)
		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)
		if game is not None:
			query = query.where(cards.c.game == game)
		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)
		if game is not None:
			query = query.where(cards.c.game == game)
		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)
		if game is not None:
			query = query.where(cards.c.game == game)
		return conn.execute(query).fetchall()
def process_card(card, expansion, houses, include_reminder=False):
    # sanitise card name
    filtered = clean_text(card.get('internalname', card["card_title"]))
    if not re_check.match(filtered):
        print("Still some junk left in name %s (%s)" % (card.get(
            'internalname', card["card_title"]), json.dumps(filtered)))
        print(json.dumps(card))
        sys.exit(1)

    def build_description():
        yield card['card_title']
        yield ' ['
        if card.get('is_anomaly'):
            yield "Anomaly"
        elif card['house'] in houses:
            yield houses[card['house']]['name']
        else:
            yield card['house']
        if card.get('amber'):
            yield '\u2014'
            yield str(card['amber'])
            yield '<A>'
        yield '] | '
        yield card['card_type']
        if card.get('traits'):
            yield ' \u2014 '
            yield card['traits']
        if card['card_type'] == "Creature":
            yield ' ['
            yield str(card['power'])
            if card.get('armor'):
                yield '/'
                yield str(card['armor'])
            yield ']'
        if card.get('card_text'):
            yield ' | '
            yield process_text(card['card_text'], include_reminder)

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

    numbers = card['card_number'] if card.get('card_number') else []
    if not isinstance(numbers, list):
        numbers = [numbers]
    numbers = [(expansion['code'].lower(), str(i)) for i in numbers]
    hidden = 'internalname' in card

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

	def build_description():
		yield card['card_title']
		yield ' ['
		if card['house'] in houses:
			yield houses[card['house']]['name']
		else:
			yield card['house']
		if card.get('amber'):
			yield '\u2014'
			yield str(card['amber'])
			yield '<A>'
		yield '] | '
		yield card['card_type']
		if card.get('traits'):
			yield ' \u2014 '
			yield card['traits']
		if card.get('power') or card.get('armor') or card['card_type'] == "Creature":
			yield ' ['
			yield str(card['power'])
			if card.get('armor'):
				yield '/'
				yield str(card['armor'])
			yield ']'
		if card.get('card_text'):
			yield ' | '
			yield process_text(card['card_text'], include_reminder)

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

	numbers = card['card_number'] if card.get('card_number') else []
	if not isinstance(numbers, list):
		numbers = [numbers]
	numbers = [(expansion['code'].lower(), str(i)) for i in numbers]
	hidden = 'internalname' in card

	return filtered, card['card_title'], desc, numbers, hidden
Example #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
Example #6
0
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']

    try:
        game = CARD_GAME_CODE_MAPPING[req.get('game', 'mtg')]
    except KeyError:
        return flask.jsonify(message="Unrecognised game code"), 400
    query = sqlalchemy.select([cards.c.id, cards.c.name,
                               cards.c.text]).where(cards.c.game == game)

    if 'multiverseid' in req:
        query = query.select_from(cards.join(card_multiverse)).where(
            card_multiverse.c.id == req['multiverseid'])
    elif 'name' in req:
        name = card.to_query(req['name'])
        exact = card.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 += card.to_query(req['augment']) + escape_like("_aug")
        if 'host' in req:
            name += ("_" if name != "" else "") + card.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,
    )
Example #7
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
Example #8
0
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']

	try:
		game = CARD_GAME_CODE_MAPPING[req.get('game', 'mtg')]
	except KeyError:
		return flask.jsonify(message="Unrecognised game code"), 400
	query = sqlalchemy.select([cards.c.id, cards.c.name, cards.c.text]).where(cards.c.game == game)

	if 'multiverseid' in req:
		query = query.select_from(cards.join(card_multiverse)).where(card_multiverse.c.id == req['multiverseid'])
	elif 'name' in req:
		name = card.to_query(req['name'])
		exact = card.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 += card.to_query(req['augment']) + escape_like("_aug")
		if 'host' in req:
			name += ("_" if name != "" else "") + card.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,
	)