actions.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. import re
  2. from random import uniform
  3. from asyncio import sleep
  4. from aiohttp import ClientSession
  5. from tortoise.contrib.postgres.functions import Random
  6. from telethon.utils import get_input_document
  7. from telethon.tl.functions.stickers import (
  8. CreateStickerSetRequest,
  9. AddStickerToSetRequest,
  10. )
  11. from telethon.tl.functions.messages import UploadMediaRequest, GetStickerSetRequest
  12. from telethon.tl.types import (
  13. InputStickerSetID,
  14. InputStickerSetShortName,
  15. InputStickerSetItem,
  16. InputMediaUploadedDocument,
  17. InputPeerSelf,
  18. )
  19. from telethon.errors import MessageEmptyError
  20. from tortoise.expressions import F
  21. from models import (
  22. Action,
  23. Gif,
  24. StickerPack,
  25. Admin,
  26. BirthDay,
  27. VPNServer,
  28. AllowedChat,
  29. MarkovChat,
  30. )
  31. from utils import is_valid_name, is_valid_ip, remove_ansi_escapes
  32. from config import config
  33. async def is_admin(bot, user):
  34. admin = await bot.get_entity(config.ADMIN)
  35. if user.id == admin.id:
  36. return True
  37. admin = await Admin.filter(user_id=user.id)
  38. if admin:
  39. return True
  40. return False
  41. async def add_admin(user):
  42. await Admin(user_id=user.id).save()
  43. async def delete_admin(user):
  44. admin = await Admin.filter(user_id=user.id).first()
  45. if not admin:
  46. raise IndexError
  47. await admin.delete()
  48. async def create_action(name, template, kind):
  49. if not is_valid_name(name):
  50. raise SyntaxError
  51. await Action(name=name, template=template, kind=kind).save()
  52. async def find_action(name):
  53. if not is_valid_name(name):
  54. raise SyntaxError
  55. return await Action.filter(name=name).first()
  56. async def delete_action(name):
  57. action = await find_action(name)
  58. if not action:
  59. raise NameError
  60. gifs = await action.gifs.all()
  61. for gif in gifs:
  62. await gif.delete()
  63. await action.delete()
  64. async def add_gif(action, file_id):
  65. await Gif(action=action, file_id=file_id).save()
  66. async def get_random_gif(action):
  67. return await action.gifs.all().annotate(order=Random()).order_by("order").first()
  68. async def create_new_pack(bot, sticker):
  69. last_pack = await StickerPack.all().order_by("-id").first()
  70. set_id = last_pack.id + 1 if last_pack else 1
  71. user = await bot.get_entity(config.USER)
  72. me = await bot.get_me()
  73. bot_username = me.username
  74. pack = await bot(
  75. CreateStickerSetRequest(
  76. user_id=user.id,
  77. title=f"Messages #{set_id}.",
  78. short_name=f"messages{set_id}_by_{bot_username}",
  79. stickers=[sticker],
  80. )
  81. )
  82. sid = pack.set.id
  83. hash = pack.set.access_hash
  84. await StickerPack(short_name=pack.set.short_name, sid=sid, hash=hash).save()
  85. return pack
  86. async def get_current_pack(bot):
  87. pack = await StickerPack.all().order_by("-id").first()
  88. if not pack or pack.stickers_count >= 119:
  89. return None
  90. return pack
  91. async def add_sticker(bot, file, emoji):
  92. file = await bot.upload_file(file)
  93. file = InputMediaUploadedDocument(file, "image/png", [])
  94. file = await bot(UploadMediaRequest(InputPeerSelf(), file))
  95. file = get_input_document(file)
  96. sticker = InputStickerSetItem(document=file, emoji=emoji)
  97. pack = await get_current_pack(bot)
  98. if not pack:
  99. pack = await create_new_pack(bot, sticker)
  100. else:
  101. await StickerPack.filter(id=pack.id).update(
  102. stickers_count=F("stickers_count") + 1
  103. )
  104. pack = await bot(
  105. AddStickerToSetRequest(
  106. stickerset=InputStickerSetID(id=pack.sid, access_hash=pack.hash),
  107. sticker=sticker,
  108. )
  109. )
  110. return get_input_document(pack.documents[-1])
  111. async def get_birthdays(peer_id):
  112. return await BirthDay.filter(peer_id=peer_id).all()
  113. async def add_or_update_birthday(peer_id, user, date):
  114. birthday = await BirthDay.filter(peer_id=peer_id, user_id=user.id).first()
  115. if birthday:
  116. await BirthDay.filter(id=birthday.id).update(date=date)
  117. return False
  118. await BirthDay(peer_id=peer_id, user_id=user.id, date=date).save()
  119. return True
  120. async def get_all_birthdays():
  121. return await BirthDay.all()
  122. async def add_server(name, ip):
  123. if not is_valid_ip(ip):
  124. raise ValueError
  125. await VPNServer(name=name, ip=ip).save()
  126. async def add_server(name, ip):
  127. if not is_valid_name(name):
  128. raise SyntaxError
  129. if not is_valid_ip(ip):
  130. raise ValueError
  131. await VPNServer(name=name, ip=ip).save()
  132. async def delete_server(name):
  133. if not is_valid_name(name):
  134. raise SyntaxError
  135. server = await VPNServer.filter(name=name).first()
  136. if not server:
  137. raise IndexError
  138. await server.delete()
  139. async def list_servers():
  140. servers = await VPNServer.all()
  141. if not servers:
  142. return "*пусто*"
  143. return ", ".join(map(lambda server: server.name, servers))
  144. async def get_server_ip(name):
  145. if not is_valid_name(name):
  146. raise SyntaxError
  147. server = await VPNServer.filter(name=name).first()
  148. if not server:
  149. raise IndexError
  150. return server.ip
  151. async def add_allowed(peer_id):
  152. await AllowedChat(peer_id=peer_id).save()
  153. async def delete_allowed(peer_id):
  154. chat = await AllowedChat.filter(peer_id=peer_id).first()
  155. if not chat:
  156. raise IndexError
  157. await chat.delete()
  158. async def is_allowed(peer_id):
  159. return await AllowedChat.filter(peer_id=peer_id).exists()
  160. async def is_markov_enabled(peer_id):
  161. return await MarkovChat.filter(peer_id=peer_id).exists()
  162. async def enable_markov(peer_id):
  163. await MarkovChat(peer_id=peer_id).save()
  164. async def set_markov_options(peer_id, **options):
  165. chat = await MarkovChat.filter(peer_id=peer_id).first()
  166. if not chat:
  167. raise IndexError
  168. await MarkovChat.filter(id=chat.id).update(**options)
  169. async def get_markov_option(peer_id, option):
  170. chat = await MarkovChat.filter(peer_id=peer_id).first()
  171. if not chat:
  172. raise IndexError
  173. return getattr(chat, option)
  174. async def disable_markov(peer_id):
  175. chat = await MarkovChat.filter(peer_id=peer_id).first()
  176. if not chat:
  177. raise IndexError
  178. await chat.delete()
  179. async def list_markov_chats():
  180. return await MarkovChat.all()
  181. async def markov_say(bot, peer_id, reply_to=None, init_state=None):
  182. if not bot.markov.is_ready:
  183. return
  184. text = bot.markov.generate(init_state)
  185. async with bot.action(peer_id, "typing"):
  186. amount = 0
  187. for _ in range(len(text)):
  188. amount += round(uniform(0.05, 0.2), 2)
  189. await sleep(min(amount, 8))
  190. await bot.send_message(peer_id, message=text, reply_to=reply_to)
  191. async def run(text):
  192. match = re.match(r"^(\w+)(?:\s|\n)((?:\n|.)*)$", text)
  193. if not match:
  194. return "Пожалуйста, не оставляйте ввод пустым!"
  195. language_name, text = match.groups()
  196. if text.startswith("```") and text.endswith("```"):
  197. text = text[3:-3]
  198. text = text.replace("\xa0", " ") # i hate telegram
  199. async with ClientSession() as session:
  200. try:
  201. async with session.post(
  202. f"https://farlands.txlyre.website/run/{language_name}", data=text
  203. ) as resp:
  204. if resp.status in (404, 500):
  205. info = await resp.json()
  206. return f"Произошла ошибка при попытке обращения к API… :(\nОтвет API: {info['detail']}"
  207. elif resp.status != 200:
  208. return "Сервер API временно недоступен. Пожалуйста, попробуйте ещё раз чуть позже."
  209. text = await resp.read()
  210. text = text.decode("UTF-8")[:4096]
  211. except:
  212. return "Произошла ошибка при попытке обращения к API… :("
  213. text = remove_ansi_escapes(text).strip()
  214. text = filter(
  215. lambda c: (c in " \t\n" or ord(c) >= 32) and ord(c) not in range(128, 159), text
  216. )
  217. text = "".join(text)
  218. text = text.replace("`", "")
  219. if not text:
  220. return "<пусто>"
  221. try:
  222. return f"```\n{text}```"
  223. except (ValueError, MessageEmptyError):
  224. return "<Telegram не смог декодировать текст сообщения>"