openkriemy.py 5.7 KB

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