add.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. """Add player conversation"""
  2. import random
  3. import string
  4. from telegram import ParseMode
  5. from telegram.ext import MessageHandler, CommandHandler, Filters, ConversationHandler
  6. from app import api, functions, database, commands, HEADERS, BASE_URL, LOGGER
  7. PLAYER_ID, CHOOSE, CONFIRM, VERIFICATION = range(4)
  8. def conv_start(update, context):
  9. """Start conversation"""
  10. LOGGER.info('"@%s" start add account conversation', update.message.from_user.username)
  11. update.message.reply_text('Starting add account conversation, use /cancel to stop.')
  12. return conv_ask_player_id(update, context)
  13. def conv_ask_player_id(update, context):
  14. """Ask player id"""
  15. update.message.reply_text('Send me your Rival Regions account name or ID.')
  16. return PLAYER_ID
  17. def conv_player_choose(update, context):
  18. """Ask max resource"""
  19. player_name = update.message.text
  20. LOGGER.info(
  21. '"@%s" searching for player name "%s"',
  22. update.message.from_user.username,
  23. player_name
  24. )
  25. update.message.reply_text(
  26. 'Searching for \'{}\', this might take a couple seconds.'.format(player_name)
  27. )
  28. players = api.get_players_by_name(player_name)
  29. if len(players) == 0:
  30. update.message.reply_text('No accounts found witht that name, try again.')
  31. return PLAYER_ID
  32. if len(players) == 1:
  33. player = players[0]
  34. player_id = player['id']
  35. if database.is_connected(update.message.from_user.id, player_id):
  36. update.message.reply_text('Account already connected, ending conversation.')
  37. context.user_data.clear()
  38. return ConversationHandler.END
  39. context.user_data['player_id'] = player_id
  40. player = get_player(player_id)
  41. if not player:
  42. LOGGER.warn(
  43. '"@%s" Can\'t find RR player ID "%s"',
  44. update.message.from_user.username, player_id
  45. )
  46. update.message.reply_text('Couldn\'t find an account by that ID, try again.')
  47. return PLAYER_ID
  48. ask_confirmation(update, player)
  49. return CONFIRM
  50. context.user_data['player_list'] = players
  51. message = 'Choose from list:\n'
  52. for num, player in enumerate(players, start=1):
  53. message += '{}) {} ({})\n'.format(num, player['name'], player['level'])
  54. update.message.reply_text(message)
  55. return CHOOSE
  56. def conv_player_id_confirm(update, context):
  57. """Confirm player ID"""
  58. player_id = int(update.message.text)
  59. if player_id <= 25:
  60. player_index = player_id-1
  61. if 'player_list' not in context.user_data:
  62. return conv_ask_player_id(update, context)
  63. if player_index >= len(context.user_data['player_list']):
  64. update.message.reply_text('{} is not an option, try again.'.format(player_id),)
  65. return CHOOSE
  66. player = context.user_data['player_list'][player_index]
  67. player_id = player['id']
  68. if database.is_connected(update.message.from_user.id, player_id):
  69. update.message.reply_text('Account already connected.')
  70. context.user_data.clear()
  71. return ConversationHandler.END
  72. context.user_data['player_id'] = player_id
  73. update.message.reply_text(
  74. 'Retreiving account from Rival Regions, this might take a couple seconds.'
  75. )
  76. player = get_player(player_id)
  77. if not player:
  78. LOGGER.warn(
  79. '"@%s" Can\'t find RR player ID "%s"',
  80. update.message.from_user.username, player_id
  81. )
  82. update.message.reply_text('Couldn\'t find an account by that ID, try again.')
  83. return CHOOSE
  84. ask_confirmation(update, player)
  85. return CONFIRM
  86. def get_player(player_id):
  87. """Get player by ID"""
  88. try:
  89. return api.get_rr_player(player_id)
  90. except api.PlayerNotFoundException:
  91. return False
  92. def ask_confirmation(update, player):
  93. """Get account and ask for confirmation"""
  94. LOGGER.info(
  95. '"@%s" Ask for confirmation on RR player ID "%s"',
  96. update.message.from_user.username, player['id']
  97. )
  98. message_list = [
  99. '*Player details*',
  100. '*ID*: {}'.format(player['id']),
  101. '*Name*: {}'.format(functions.escape_text(player['name'])),
  102. '*Region*: {}'.format(player['region']),
  103. '*Residency*: {}'.format(player['residency']),
  104. '*Registration date*: {}'.format(player['registation_date']),
  105. ]
  106. update.message.reply_text(
  107. '\n'.join(message_list),
  108. parse_mode=ParseMode.MARKDOWN
  109. )
  110. update.message.reply_text('Please confirm this is your account by typing \'confirm\'.')
  111. def conv_verification(update, context):
  112. """Sending announcement"""
  113. update.message.reply_text(
  114. 'Verification code will be send to your Rival Region player in a couple of secconds. ' + \
  115. 'Check your personal messages for a verification code and send it here.',
  116. parse_mode=ParseMode.MARKDOWN
  117. )
  118. letters = string.ascii_lowercase
  119. verification_code = ''.join(random.choice(letters) for i in range(5))
  120. LOGGER.info(
  121. '"@%s" verification code "%s"',
  122. update.message.from_user.username,
  123. verification_code
  124. )
  125. message = 'Your verification code:\n{}\n\n'.format(verification_code) + \
  126. 'Telegram user @{} tried to add this account. '.format(
  127. update.message.from_user.username
  128. ) + \
  129. 'Don\'t share this code with anyone except @rr_verification_bot on Telegram.'
  130. api.send_personal_message(context.user_data['player_id'], message)
  131. context.user_data['verification_code'] = verification_code
  132. return VERIFICATION
  133. def conv_finish(update, context):
  134. """Sending announcement"""
  135. verification_code = update.message.text
  136. if verification_code != context.user_data['verification_code']:
  137. LOGGER.info(
  138. '"@%s" wrong verification code try "%s"',
  139. update.message.from_user.username,
  140. verification_code,
  141. )
  142. if 'tries' not in context.user_data:
  143. context.user_data['tries'] = 0
  144. context.user_data['tries'] += 1
  145. if context.user_data['tries'] >= 3:
  146. LOGGER.info(
  147. '"@%s" too many wrong verification tries',
  148. update.message.from_user.username
  149. )
  150. update.message.reply_text(
  151. 'Failed verification to many times, canceled action.',
  152. parse_mode=ParseMode.MARKDOWN
  153. )
  154. context.user_data.clear()
  155. return ConversationHandler.END
  156. update.message.reply_text(
  157. 'Verificated code doesn\'t match, try again.',
  158. parse_mode=ParseMode.MARKDOWN
  159. )
  160. return VERIFICATION
  161. player_id = context.user_data['player_id']
  162. LOGGER.info(
  163. '"@%s" succesfully verified RR account "%s"',
  164. update.message.from_user.username,
  165. player_id,
  166. )
  167. database.verify_rr_player(update.message.from_user.id, player_id)
  168. update.message.reply_text('Verificated your Rival Region player to Telegram')
  169. commands.cmd_accounts(update, context)
  170. context.user_data.clear()
  171. return ConversationHandler.END
  172. def conv_error_finish(update, context):
  173. """Wrong verification code"""
  174. incorrect_input = update.message.text
  175. update.message.reply_text(
  176. '"{}" not recognized. Send me the verification code.\n/cancel to cancel'.format(
  177. incorrect_input
  178. ),
  179. )
  180. return VERIFICATION
  181. def conv_cancel(update, context):
  182. """Cancel announcement"""
  183. update.message.reply_text('Canceled action.')
  184. context.user_data.clear()
  185. return ConversationHandler.END
  186. # announcement conversation
  187. ADD_CONV = ConversationHandler(
  188. entry_points=[CommandHandler('add', conv_start)],
  189. states={
  190. PLAYER_ID: [
  191. MessageHandler(Filters.regex(r'^\d*$'), conv_player_id_confirm),
  192. MessageHandler(Filters.text, conv_player_choose),
  193. ],
  194. CHOOSE: [
  195. MessageHandler(Filters.regex(r'^\d*$'), conv_player_id_confirm),
  196. MessageHandler(Filters.text, conv_player_choose),
  197. ],
  198. CONFIRM: [
  199. MessageHandler(Filters.regex('(?i)confirm'), conv_verification),
  200. MessageHandler(Filters.text, conv_cancel),
  201. ],
  202. VERIFICATION: [
  203. MessageHandler(Filters.regex(r'^([a-z]|\d)+$'), conv_finish),
  204. MessageHandler(Filters.text, conv_error_finish),
  205. ],
  206. },
  207. fallbacks=[CommandHandler('cancel', conv_cancel)]
  208. )