actions.py 8.2 KB

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