Browse Source

switch oracle to mtgjson

master
Alexey Chernyshov 5 years ago
parent
commit
a4193665bb
3 changed files with 86 additions and 14 deletions
  1. 4
    2
      make_data.sh
  2. 12
    12
      src/magic-judge-telegram-bot.py
  3. 70
    0
      src/oracle_sql.py

+ 4
- 2
make_data.sh View File

#!/bin/sh #!/bin/sh
mkdir -p data mkdir -p data
python3 scripts/update_cards.py
curl https://media.wizards.com/2019/downloads/MagicCompRules%2020190503.txt --output cr.txt
#python3 scripts/update_cards.py
curl https://media.wizards.com/2020/downloads/MagicCompRules%2020200703.txt --output cr.txt
curl https://mtgjson.com/api/v5/AllPrintings.sqlite --output data/mtg.sqlite
python3 scripts/update_cr.py python3 scripts/update_cr.py


+ 12
- 12
src/magic-judge-telegram-bot.py View File

import logging import logging
import json import json
import oracle
import oracle_sql
import documents import documents
import gc import gc
from telegram.ext import (Updater, CommandHandler, InlineQueryHandler, from telegram.ext import (Updater, CommandHandler, InlineQueryHandler,
return return
words = [word.casefold() for word in args] words = [word.casefold() for word in args]


nameCandidates = oracle.get_matching_names(words)
nameCandidates = oracle_sql.get_matching_names(words)


if not nameCandidates: if not nameCandidates:
update.message.reply_text( update.message.reply_text(


reply = [] reply = []
for name in nameCandidates: for name in nameCandidates:
for oracleName in oracle.get_oracle_names(name):
reply.append(format_card(oracle.get_card(oracleName)))
for oracleName in oracle_sql.get_oracle_names(name):
reply.append(format_card(oracle_sql.get_card(oracleName)))
update.message.reply_text('\n'.join(reply), parse_mode='HTML', quote=False) update.message.reply_text('\n'.join(reply), parse_mode='HTML', quote=False)




def question_command(bot, update, args): def question_command(bot, update, args):
text = ' '.join(args).casefold() text = ' '.join(args).casefold()


names = oracle.get_names_in_text(text)
names = oracle_sql.get_names_in_text(text)


reply = [] reply = []
for name in names: for name in names:
reply.append( reply.append(
'"' + name + '":\n' + '\n'.join( '"' + name + '":\n' + '\n'.join(
[format_card(oracle.get_card(oracleName))
for oracleName in oracle.get_oracle_names(name)]))
[format_card(oracle_sql.get_card(oracleName))
for oracleName in oracle_sql.get_oracle_names(name)]))
if reply: if reply:
update.message.reply_text( update.message.reply_text(
'\n\n'.join(reply), '\n\n'.join(reply),
return return


words = query.split() words = query.split()
nameCandidates = oracle.get_matching_names(words)
nameCandidates = oracle_sql.get_matching_names(words)
if not nameCandidates: if not nameCandidates:
return return


results = list() results = list()
for word in nameCandidates[:3]: for word in nameCandidates[:3]:
for oracleName in oracle.get_oracle_names(word):
card = oracle.get_card(oracleName)
for oracleName in oracle_sql.get_oracle_names(word):
card = oracle_sql.get_card(oracleName)
results.append( results.append(
InlineQueryResultArticle( InlineQueryResultArticle(
id=card['name'], id=card['name'],
chat_id = update.callback_query.message.chat.id chat_id = update.callback_query.message.chat.id
name = update.callback_query.data name = update.callback_query.data


names = oracle.get_oracle_names(name)
names = oracle_sql.get_oracle_names(name)
if not names: if not names:
bot.answerCallbackQuery(update.callback_query.id) bot.answerCallbackQuery(update.callback_query.id)
return return


bot.editMessageText(chat_id=chat_id, message_id=message_id, bot.editMessageText(chat_id=chat_id, message_id=message_id,
parse_mode='HTML', text='\n'.join( parse_mode='HTML', text='\n'.join(
[format_card(oracle.get_card(oracleName))
[format_card(oracle_sql.get_card(oracleName))
for oracleName in names])) for oracleName in names]))
bot.answerCallbackQuery(update.callback_query.id) bot.answerCallbackQuery(update.callback_query.id)



+ 70
- 0
src/oracle_sql.py View File

import sqlite3
import codecs

def quote_identifier(s, errors="strict"):
encodable = s.encode("utf-8", errors).decode("utf-8")

nul_index = encodable.find("\x00")

if nul_index >= 0:
error = UnicodeEncodeError("NUL-terminated utf-8", encodable,
nul_index, nul_index + 1, "NUL not allowed")
error_handler = codecs.lookup_error(errors)
replacement, _ = error_handler(error)
encodable = encodable.replace("\x00", replacement)

return encodable.replace("\"", "\"\"")

conn = sqlite3.connect('data/mtg.sqlite', check_same_thread=False)

def get_card(name):
t = ( name,)
cursor = conn.cursor()
cursor.execute("SELECT DISTINCT(name), type, text, manacost, loyalty, power, toughness FROM cards WHERE name LIKE ?", t)
row = cursor.fetchone()
if not row:
return None

result = {
'name': row[0],
'type': row[1]
}

if row[2]:
result['text'] = row[2]

if row[3]:
result['manaCost'] = row[3]

if row[4]:
result['loyalty'] = row[4]

if row[5] and row[6]:
result['power'] = row[5]
result['toughness'] = row[6]

return result


def get_matching_names(words):
condition = ''

for word in words:
if condition:
condition = condition + ' AND '

condition = condition + "name LIKE '%" + quote_identifier(word) + "%'"

query = 'SELECT DISTINCT(name) FROM cards WHERE ' + condition
cursor = conn.cursor()
cursor.execute(query)
return [row[0] for row in cursor.fetchall()]


def get_oracle_names(name):
card = get_card(name)
if not card:
return None

return [card['name']]


Loading…
Cancel
Save