Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

magic-judge-telegram-bot.py 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import logging
  2. import json
  3. from telegram.ext import Updater, CommandHandler, InlineQueryHandler, CallbackQueryHandler, MessageHandler, Filters
  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 '<b>{}</b>{}\n<i>{}</i>{}{}'.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)), quote = False)
  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!', quote=False)
  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!', quote=False)
  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)), quote=False)
  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, quote=False)
  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), parse_mode='HTML', quote = False)
  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 + '":\n' + '\n'.join([format_card(oracleData[uniqueName]) for uniqueName in names[name]]))
  89. if reply:
  90. update.message.reply_text('\n\n'.join(reply), parse_mode='HTML', quote = False)
  91. def inline_oracle(bot, update):
  92. query = update.inline_query.query.casefold()
  93. if not query:
  94. return
  95. if len(query) < 3:
  96. return
  97. words = query.split()
  98. nameCandidates = search_names(words)
  99. if not nameCandidates:
  100. return
  101. results = list()
  102. for word in nameCandidates[:3]:
  103. for uniqueName in names[word]:
  104. results.append(
  105. InlineQueryResultArticle(
  106. id=oracleData[uniqueName]['name'],
  107. title=word,
  108. description=preview_card(oracleData[uniqueName]),
  109. input_message_content=InputTextMessageContent(format_card(oracleData[uniqueName]), parse_mode='HTML')
  110. )
  111. )
  112. bot.answerInlineQuery(update.inline_query.id, results)
  113. def callback_name(bot, update):
  114. message_id = update.callback_query.message.message_id
  115. chat_id = update.callback_query.message.chat.id
  116. name = update.callback_query.data
  117. if not name in oracleData:
  118. return
  119. bot.editMessageText(
  120. chat_id = chat_id,
  121. message_id = message_id,
  122. parse_mode = 'HTML',
  123. text = '\n'.join([format_card(oracleData[uniqueName]) for uniqueName in names[name]])
  124. )
  125. bot.answerCallbackQuery(update.callback_query.id)
  126. def text(bot, update):
  127. if update.message.chat.type != 'private':
  128. return
  129. text = update.message.text
  130. if len(text) < 30:
  131. oracle(bot, update, text.split())
  132. else:
  133. question(bot, update, text)
  134. def dispatcher_setup(dispatcher):
  135. dispatcher.add_handler(CommandHandler('start', start))
  136. dispatcher.add_handler(CommandHandler('help', start))
  137. dispatcher.add_handler(CommandHandler('o', oracle, pass_args=True))
  138. dispatcher.add_handler(CommandHandler('q', question, pass_args=True))
  139. dispatcher.add_handler(InlineQueryHandler(inline_oracle))
  140. dispatcher.add_handler(CallbackQueryHandler(callback_name))
  141. dispatcher.add_handler(MessageHandler(Filters.text, text))
  142. with open('token') as file:
  143. token = file.read().strip()
  144. updater = Updater(token)
  145. dispatcher_setup(updater.dispatcher)
  146. updater.start_polling()
  147. updater.idle()