You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

magic-judge-telegram-bot.py 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import logging
  2. import json
  3. from telegram.ext import Updater, CommandHandler, InlineQueryHandler, CallbackQueryHandler
  4. from telegram import InlineQueryResultArticle, InputTextMessageContent, InlineKeyboardButton, InlineKeyboardMarkup
  5. #logging.basicConfig(level=logging.DEBUG,
  6. # format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
  7. names = {}
  8. with open('data/names.json') as file:
  9. names = json.load(file)
  10. namesToSearch = names.keys()
  11. oracleData = {}
  12. with open('data/oracle.json') as file:
  13. oracleData = json.load(file)
  14. print('Registered {} card names and {} oracle entries'.format(len(names), len(oracleData)))
  15. def format_card(card):
  16. mana = ''
  17. if 'manaCost' in card:
  18. mana = '\t' + card['manaCost']
  19. text = ''
  20. if 'text' in card:
  21. text = '\n' + card['text']
  22. footer = ''
  23. if "Creature" in card['type']:
  24. footer = '\n{}/{}'.format(card['power'], card['toughness'])
  25. if "Planeswalker" in card['type'] and 'loyalty' in card:
  26. footer = '\n{}'.format(card['loyalty'])
  27. return '{}{}\n{}{}{}'.format(
  28. card['name'],
  29. mana,
  30. card['type'],
  31. text,
  32. footer)
  33. def preview_card(card):
  34. mana = ''
  35. if 'manaCost' in card:
  36. mana = '\t' + card['manaCost']
  37. return '{}{}\n{}'.format(
  38. card['name'],
  39. mana,
  40. card['type'])
  41. def start(bot, update):
  42. commands = [
  43. '/o <card name or search strings> - oracle text for a card',
  44. '/q <question> - oracle text for cards mentioned in the question',
  45. '/cr <section> (coming soon)',
  46. '/ipg <section> (coming soon)',
  47. '/mtr <section> (coming soon)',
  48. ]
  49. update.message.reply_text('How can I help?\n{}'.format('\n'.join(commands)))
  50. def search_names(words):
  51. nameCandidates = [name for name in namesToSearch if all(word in name.casefold() for word in words)]
  52. term = ' '.join(words)
  53. if len(words) > 1:
  54. goodCandidates = [name for name in nameCandidates if term in name.casefold()]
  55. if goodCandidates:
  56. nameCandidates = goodCandidates
  57. bestCandidates = [name for name in nameCandidates if term == name.casefold()]
  58. if bestCandidates:
  59. return bestCandidates
  60. return nameCandidates
  61. def oracle(bot, update, args):
  62. if not args:
  63. update.message.reply_text('I need some clues to search for, my master!')
  64. return
  65. words = [word.casefold() for word in args]
  66. nameCandidates = search_names(words)
  67. if not nameCandidates:
  68. update.message.reply_text('I searched very thoroughly, but returned empty-handed, my master!')
  69. return
  70. if len(nameCandidates) > 20:
  71. update.message.reply_text('I need more specific clues, my master! This would return {} names'.format(len(nameCandidates)))
  72. return
  73. if len(nameCandidates) > 1:
  74. reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton(name, callback_data=name)] for name in nameCandidates])
  75. update.message.reply_text('Which one?', reply_markup=reply_markup)
  76. return
  77. reply = []
  78. for name in nameCandidates:
  79. for uniqueName in names[name]:
  80. reply.append(format_card(oracleData[uniqueName]))
  81. update.message.reply_text('\n'.join(reply))
  82. def question(bot, update, args):
  83. words = args
  84. text = ' '.join(words).casefold()
  85. reply = []
  86. for name in namesToSearch:
  87. if name.casefold() in text:
  88. reply.append('"' + name + '":')
  89. for uniqueName in names[name]:
  90. reply.append(format_card(oracleData[uniqueName]))
  91. if reply:
  92. update.message.reply_text('\n'.join(reply))
  93. def inline_oracle(bot, update):
  94. query = update.inline_query.query.casefold()
  95. if not query:
  96. return
  97. if len(query) < 3:
  98. return
  99. words = query.split()
  100. nameCandidates = search_names(words)
  101. if not nameCandidates:
  102. return
  103. results = list()
  104. for word in nameCandidates[:3]:
  105. for uniqueName in names[word]:
  106. results.append(
  107. InlineQueryResultArticle(
  108. id=oracleData[uniqueName]['name'],
  109. title=word,
  110. description=preview_card(oracleData[uniqueName]),
  111. input_message_content=InputTextMessageContent(format_card(oracleData[uniqueName]))
  112. )
  113. )
  114. bot.answerInlineQuery(update.inline_query.id, results)
  115. def callback_name(bot, update):
  116. message_id = update.callback_query.message.message_id
  117. chat_id = update.callback_query.message.chat.id
  118. name = update.callback_query.data
  119. if not name in oracleData:
  120. return
  121. bot.editMessageText(
  122. chat_id = chat_id,
  123. message_id = message_id,
  124. text = '\n'.join([format_card(oracleData[uniqueName]) for uniqueName in names[name]])
  125. )
  126. bot.answerCallbackQuery(update.callback_query.id)
  127. def dispatcher_setup(dispatcher):
  128. dispatcher.add_handler(CommandHandler('start', start))
  129. dispatcher.add_handler(CommandHandler('help', start))
  130. dispatcher.add_handler(CommandHandler('o', oracle, pass_args=True))
  131. dispatcher.add_handler(CommandHandler('q', question, pass_args=True))
  132. dispatcher.add_handler(InlineQueryHandler(inline_oracle))
  133. dispatcher.add_handler(CallbackQueryHandler(callback_name))
  134. with open('token') as file:
  135. token = file.read().strip()
  136. updater = Updater(token)
  137. dispatcher_setup(updater.dispatcher)
  138. updater.start_polling()
  139. updater.idle()