Queer European MD passionate about IT

helper.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. """Make a self-consistent bot help section."""
  2. # Third party modules
  3. from davtelepot.utilities import (
  4. get_cleaned_text, make_inline_keyboard,
  5. make_lines_of_buttons, make_button
  6. )
  7. # Project modules
  8. from .messages import default_help_messages
  9. def get_command_description(bot, update, user_record):
  10. """Get a string description of `bot` commands.
  11. Show only commands available for `update` sender.
  12. """
  13. user_role = bot.Role.get_user_role(
  14. user_record=user_record
  15. )
  16. return "\n".join(
  17. [
  18. "/{}: {}".format(
  19. command,
  20. bot.get_message(
  21. 'commands', command, 'description',
  22. user_record=user_record, update=update,
  23. default_message=(
  24. details['description']
  25. if type(details['description']) is str
  26. else ''
  27. )
  28. )
  29. )
  30. for command, details in sorted(
  31. bot.commands.items(),
  32. key=lambda x:x[0]
  33. )
  34. if details['description']
  35. and user_role.code <= bot.Role.get_user_role(
  36. user_role_id=details['authorization_level']
  37. ).code
  38. ]
  39. )
  40. def _make_button(text=None, callback_data='',
  41. prefix='help:///', delimiter='|', data=[]):
  42. return make_button(text=text, callback_data=callback_data,
  43. prefix=prefix, delimiter=delimiter, data=data)
  44. def get_back_to_help_menu_keyboard(bot, update, user_record):
  45. """Return a keyboard to let user come back to help menu."""
  46. return make_inline_keyboard(
  47. [
  48. _make_button(
  49. text=bot.get_message(
  50. 'help', 'help_command', 'back_to_help_menu',
  51. update=update, user_record=user_record
  52. ),
  53. data=['menu']
  54. )
  55. ],
  56. 1
  57. )
  58. def get_help_buttons(bot, update, user_record):
  59. """Get `bot` help menu inline keyboard.
  60. Show only buttons available for `update` sender.
  61. """
  62. user_role = bot.Role.get_user_role(
  63. user_record=user_record
  64. )
  65. buttons_list = [
  66. _make_button(
  67. text=bot.get_message(
  68. 'help_sections', section['name'], 'label',
  69. update=update, user_record=user_record,
  70. ),
  71. data=['section', name]
  72. )
  73. for name, section in bot.messages['help_sections'].items()
  74. if 'authorization_level' in section
  75. and user_role.code <= bot.Role.get_user_role(
  76. user_role_id=section['authorization_level']
  77. ).code
  78. ]
  79. return dict(
  80. inline_keyboard=(
  81. make_lines_of_buttons(buttons_list, 3)
  82. + make_lines_of_buttons(
  83. [
  84. _make_button(
  85. text=bot.get_message(
  86. 'help', 'commands_button_label',
  87. update=update, user_record=user_record,
  88. ),
  89. data=['commands']
  90. )
  91. ],
  92. 1
  93. )
  94. )
  95. )
  96. async def _help_command(bot, update, user_record):
  97. if not bot.authorization_function(update=update,
  98. authorization_level='everybody'):
  99. return bot.get_message(
  100. 'help', 'help_command', 'access_denied_message',
  101. update=update, user_record=user_record
  102. )
  103. reply_markup = get_help_buttons(bot, update, user_record)
  104. return dict(
  105. text=bot.get_message(
  106. 'help', 'help_command', 'text',
  107. update=update, user_record=user_record,
  108. bot=bot
  109. ),
  110. parse_mode='HTML',
  111. reply_markup=reply_markup,
  112. disable_web_page_preview=True
  113. )
  114. async def _help_button(bot, update, user_record, data):
  115. result, text, reply_markup = '', '', None
  116. if data[0] == 'commands':
  117. text = bot.get_message(
  118. 'help', 'help_command', 'header',
  119. update=update, user_record=user_record,
  120. bot=bot,
  121. commands=get_command_description(bot, update, user_record)
  122. )
  123. reply_markup = get_back_to_help_menu_keyboard(
  124. bot=bot, update=update, user_record=user_record
  125. )
  126. elif data[0] == 'menu':
  127. text = bot.get_message(
  128. 'help', 'help_command', 'text',
  129. update=update, user_record=user_record,
  130. bot=bot
  131. )
  132. reply_markup = get_help_buttons(bot, update, user_record)
  133. elif (
  134. data[0] == 'section'
  135. and len(data) > 1
  136. and data[1] in bot.messages['help_sections']
  137. ):
  138. section = bot.messages['help_sections'][data[1]]
  139. if bot.authorization_function(
  140. update=update,
  141. authorization_level=section['authorization_level']
  142. ):
  143. text = (
  144. "<b>{label}</b>\n\n"
  145. "{description}"
  146. ).format(
  147. label=bot.get_message(
  148. 'help_sections', section['name'], 'label',
  149. update=update, user_record=user_record,
  150. ),
  151. description=bot.get_message(
  152. 'help_sections', section['name'], 'description',
  153. update=update, user_record=user_record,
  154. bot=bot
  155. ),
  156. )
  157. else:
  158. text = bot.authorization_denied_message
  159. reply_markup = get_back_to_help_menu_keyboard(
  160. bot=bot, update=update, user_record=user_record
  161. )
  162. if text or reply_markup:
  163. return dict(
  164. text=result,
  165. edit=dict(
  166. text=text,
  167. parse_mode='HTML',
  168. reply_markup=reply_markup,
  169. disable_web_page_preview=True
  170. )
  171. )
  172. return result
  173. async def _start_command(bot, update, user_record):
  174. text = get_cleaned_text(update=update, bot=bot, replace=['start'])
  175. if not text:
  176. return await _help_command(bot, update, user_record)
  177. update['text'] = text
  178. await bot.text_message_handler(
  179. update=update,
  180. user_record=None
  181. )
  182. return
  183. def init(bot, help_messages=None):
  184. """Assign parsers, commands, buttons and queries to given `bot`."""
  185. if help_messages is None:
  186. help_messages = default_help_messages
  187. bot.messages['help'] = help_messages
  188. @bot.command("/start", authorization_level='everybody')
  189. async def start_command(bot, update, user_record):
  190. return await _start_command(bot, update, user_record)
  191. @bot.command(command='/help', aliases=['00help'],
  192. reply_keyboard_button=help_messages['help_command'][
  193. 'reply_keyboard_button'],
  194. show_in_keyboard=True,
  195. description=help_messages['help_command']['description'],
  196. authorization_level='everybody')
  197. async def help_command(bot, update, user_record):
  198. result = await _help_command(bot, update, user_record)
  199. return result
  200. @bot.button(prefix='help:///', separator='|',
  201. authorization_level='everybody')
  202. async def help_button(bot, update, user_record, data):
  203. return await _help_button(bot, update, user_record, data)