openkriemy.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. from sys import executable
  2. from asyncio import run, create_subprocess_shell
  3. from asyncio.subprocess import PIPE
  4. from ujson import dumps
  5. from telethon import TelegramClient
  6. from telethon.events import NewMessage
  7. from telethon.utils import resolve_bot_file_id, get_display_name
  8. from tortoise.exceptions import IntegrityError
  9. from aiofiles.os import remove
  10. from emoji import is_emoji
  11. from utils import parse_command, get_link_to_user, make_temporary_filename
  12. from config import config
  13. from db import init_db
  14. from actions import create_action, find_action, delete_action, add_gif, get_random_gif, assign_color, add_sticker
  15. bot = TelegramClient(
  16. 'openkriemy',
  17. config.API_ID,
  18. config.API_HASH
  19. ).start(bot_token=config.API_TOKEN)
  20. # Very, very, VERY evil code...
  21. async def make_message_shot(message):
  22. proc = await create_subprocess_shell(
  23. f'{executable} makeshot.py',
  24. stdin=PIPE
  25. )
  26. output_path = make_temporary_filename('png')
  27. avatar_path = make_temporary_filename('png')
  28. await bot.download_profile_photo(message.sender, file=avatar_path)
  29. full_name = get_display_name(message.sender)
  30. data = dumps({
  31. 'output_path': output_path,
  32. 'avatar_path': avatar_path,
  33. 'username': full_name if full_name else message.sender.username,
  34. 'username_color': await assign_color(message.sender.username),
  35. 'text': message.text
  36. }).encode('UTF-8')
  37. await proc.communicate(input=data)
  38. await remove(avatar_path)
  39. return output_path
  40. async def handle_command(event, command, argc, args, args_string):
  41. if command == 'newaction':
  42. if argc < 2:
  43. await event.reply('Пожалуйста, укажите имя и шаблон действия!')
  44. return
  45. try:
  46. await create_action(args[0], ' '.join(args[1:]))
  47. except SyntaxError:
  48. await event.reply('Недопустимое имя действия!!!')
  49. return
  50. except IntegrityError:
  51. await event.reply('Действие с таким названием уже существует!')
  52. return
  53. await event.reply('Действие создано!')
  54. elif command == 'delaction':
  55. if argc < 1:
  56. await event.reply('Пожалуйста, укажите имя действия!')
  57. return
  58. try:
  59. await delete_action(args[0])
  60. except SyntaxError:
  61. await event.reply('Недопустимое имя действия!!!')
  62. return
  63. except NameError:
  64. await event.reply('Действия с таким названием не существует!')
  65. return
  66. await event.reply('Действие удалено!')
  67. elif command == 'addgif':
  68. if argc < 1:
  69. await event.reply('Пожалуйста, укажите имя действия!')
  70. return
  71. gif = await event.get_reply_message()
  72. if not gif or not gif.gif:
  73. await event.reply('Пожалуйста, добавьте GIF!')
  74. return
  75. try:
  76. action = await find_action(args[0])
  77. await add_gif(action, gif.file.id)
  78. except SyntaxError:
  79. await event.reply('Недопустимое имя действия!!!')
  80. return
  81. except NameError:
  82. await event.reply('Нет такого действия!')
  83. return
  84. await event.reply('Готово!~~')
  85. elif command == 'save':
  86. message = await event.get_reply_message()
  87. if not message:
  88. await event.reply('Пожалуйста, укажите сообщение для сохранения!')
  89. return
  90. emoji = '⚡'
  91. if argc >= 1:
  92. emoji = args[0]
  93. if not is_emoji(emoji):
  94. await event.reply('Указан некорректный эмодзи!!!')
  95. return
  96. path = await make_message_shot(message)
  97. try:
  98. file = await add_sticker(bot, path, emoji)
  99. await bot.send_file(
  100. message.peer_id,
  101. file=file,
  102. reply_to=message
  103. )
  104. finally:
  105. await remove(path)
  106. @bot.on(NewMessage)
  107. async def on_message(event):
  108. try:
  109. command, argc, args, args_string = parse_command(event.text)
  110. except ValueError:
  111. return
  112. if command in (
  113. 'newaction',
  114. 'delaction',
  115. 'addgif',
  116. 'save'
  117. ):
  118. await handle_command(event, command, argc, args, args_string)
  119. return
  120. try:
  121. action = await find_action(command)
  122. except SyntaxError:
  123. return
  124. if not action:
  125. return
  126. reply_to = None
  127. target = await event.get_reply_message()
  128. if not target:
  129. try:
  130. target = await bot.get_entity(args[0])
  131. except (ValueError, IndexError):
  132. await event.reply('Это действие нужно применить на кого-то!')
  133. return
  134. else:
  135. reply_to = target
  136. target = target.sender
  137. await event.delete()
  138. text = action.template.format(**{
  139. 'initiator': get_link_to_user(event.sender),
  140. 'target': get_link_to_user(target)
  141. })
  142. gif = await get_random_gif(action)
  143. if gif:
  144. gif = resolve_bot_file_id(gif.file_id)
  145. await bot.send_message(
  146. event.peer_id,
  147. message=text,
  148. file=gif,
  149. reply_to=reply_to
  150. )
  151. with bot:
  152. bot.loop.run_until_complete(init_db())
  153. bot.start()
  154. bot.run_until_disconnected()