openkriemy.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. import time
  2. from random import random, randint
  3. from asyncio import sleep
  4. from datetime import datetime, timedelta, date, time
  5. from telethon import TelegramClient
  6. from telethon.events import NewMessage, InlineQuery
  7. from telethon.utils import resolve_bot_file_id, get_peer_id
  8. from actions import get_all_birthdays
  9. from utils import parse_command, get_link_to_user, calculate_age, Kind
  10. from config import config
  11. from db import init_db
  12. from actions import (
  13. find_action,
  14. get_random_gif,
  15. is_admin,
  16. is_allowed,
  17. is_markov_enabled,
  18. get_markov_option,
  19. list_markov_chats,
  20. markov_say,
  21. run,
  22. )
  23. from commands import COMMANDS
  24. from markov import Markov
  25. from chess0 import ChessManager
  26. bot = TelegramClient("openkriemy", config.API_ID, config.API_HASH).start(
  27. bot_token=config.API_TOKEN
  28. )
  29. markov = Markov()
  30. if config.CHESS_UCI_ENGINE:
  31. chess = ChessManager(config.CHESS_UCI_ENGINE)
  32. else:
  33. chess = None
  34. # Wait isn't that illegal??
  35. bot.markov = markov
  36. bot.chess = chess
  37. @bot.on(InlineQuery)
  38. async def on_inline_query(event):
  39. text = event.text.strip()
  40. if not text:
  41. return
  42. lang, input_text, result = await run(text)
  43. if not lang:
  44. await event.answer(
  45. [
  46. event.builder.article(result, text=result),
  47. ]
  48. )
  49. return
  50. await event.answer(
  51. [
  52. event.builder.article(
  53. "Результат.",
  54. text=f"Язык: {lang}\nКод:```\n{input_text.replace('`', '')}```Результат: {result}",
  55. ),
  56. ]
  57. )
  58. @bot.on(NewMessage)
  59. async def on_message(event):
  60. peer_id = get_peer_id(event.peer_id)
  61. text = event.text
  62. try:
  63. command = parse_command(text)
  64. except ValueError:
  65. if await is_markov_enabled(peer_id):
  66. markov.extend_corpus(text)
  67. for word in config.MARKOV_TRIGGER_WORDS:
  68. if word.lower() in text.lower() and random() > 0.5:
  69. await markov_say(bot, peer_id, reply_to=event)
  70. return
  71. reply_prob = await get_markov_option(peer_id, "opt_reply_prob")
  72. reply = await event.get_reply_message()
  73. if (
  74. reply
  75. and get_peer_id(reply.from_id) == await bot.get_peer_id("me")
  76. and random() > 0.5
  77. ) or random() > reply_prob:
  78. await markov_say(bot, peer_id, reply_to=event)
  79. return
  80. handler = COMMANDS.get(command.name, None)
  81. if handler and handler.is_public:
  82. await handler.handler(bot, event, command)
  83. return
  84. action = None
  85. try:
  86. action = await find_action(command.name)
  87. except SyntaxError:
  88. pass
  89. if not await is_allowed(peer_id):
  90. if not action and (not handler or not handler.is_restricted):
  91. return
  92. if handler:
  93. if handler.is_restricted and not await is_admin(bot, event.sender):
  94. await event.reply("К сожалению, данная команда Вам недоступна.")
  95. else:
  96. await handler.handler(bot, event, command)
  97. return
  98. if not action:
  99. return
  100. reply_to = None
  101. target = None
  102. if action.kind != Kind.NO_TARGET:
  103. target = await event.get_reply_message()
  104. if not target:
  105. try:
  106. target = await bot.get_entity(command.args[0])
  107. except (ValueError, IndexError):
  108. if action.kind != Kind.NO_TARGET_MAYBE:
  109. await event.reply("Это действие нужно применить на кого-то!")
  110. return
  111. else:
  112. reply_to = target
  113. target = target.sender
  114. if target is None:
  115. target = await bot.get_entity(event.peer_id.channel_id)
  116. if action.kind == Kind.CANNOT_APPLY_TO_SELF and target.id == event.sender.id:
  117. await event.reply("Данное действие нельзя применять к самому себе...")
  118. return
  119. try:
  120. await event.delete()
  121. except Exception:
  122. pass
  123. if event.sender is None:
  124. initiator = await bot.get_entity(event.peer_id.channel_id)
  125. initiator = initiator.title
  126. else:
  127. initiator = get_link_to_user(event.sender)
  128. text = action.template.format(
  129. **{"initiator": initiator, "target": get_link_to_user(target) if target else ""}
  130. )
  131. gif = await get_random_gif(action)
  132. if gif:
  133. gif = resolve_bot_file_id(gif.file_id)
  134. await bot.send_message(event.peer_id, message=text, file=gif, reply_to=reply_to)
  135. async def notify_birthdays():
  136. birthdays = await get_all_birthdays()
  137. for birthday in birthdays:
  138. age = calculate_age(birthday.date)
  139. if age.days_until < 1:
  140. try:
  141. try:
  142. entity = await bot.get_entity(birthday.user_id)
  143. except ValueError:
  144. await bot.get_participants(birthday.peer_id)
  145. entity = await bot.get_entity(birthday.user_id)
  146. await bot.send_message(
  147. birthday.peer_id,
  148. f"{get_link_to_user(entity)}, поздравляю с днём рождения!!~~",
  149. )
  150. except:
  151. pass
  152. async def notify_birthdays_loop():
  153. interval = datetime.combine(date.today(), time(hour=0, minute=0))
  154. while True:
  155. await sleep(((interval - datetime.now()) % timedelta(days=1)).total_seconds())
  156. await notify_birthdays()
  157. async def markov_say_loop():
  158. while True:
  159. await sleep(randint(30, 60 * 5))
  160. for chat in await list_markov_chats():
  161. if random() > chat.opt_message_prob:
  162. await markov_say(bot, chat.peer_id)
  163. async def chess_cleanup():
  164. while True:
  165. await sleep(60 * 60)
  166. await chess.cleanup()
  167. with bot:
  168. bot.loop.run_until_complete(init_db())
  169. bot.loop.create_task(notify_birthdays_loop())
  170. bot.loop.create_task(markov_say_loop())
  171. if chess:
  172. bot.loop.create_task(chess_cleanup())
  173. bot.start()
  174. bot.run_until_disconnected()