From f60ff3164cdf155e51b3018132710f72eee0da86 Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Mon, 21 Mar 2022 22:03:55 +0300 Subject: [PATCH] new_chat_member + ban + refactoring warns --- README.md | 16 ++++---- src/SqlModels.py | 23 ++++++++++-- src/config.py | 6 +++ src/main.py | 95 ++++++++++++++++++++++++++++++++++++++++++------ src/sl3.sql | 28 ++++++++++---- src/tools.py | 93 ++++++++++++++++++++++++++++------------------- 6 files changed, 192 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 3943c56..485d62d 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,13 @@ $ python3 main.py { "bot_token": "BOT_TOKEN", "remote_chat": -1000, + "new_member_message": "Привет, @%(username)-s!\nДобро пожаловать в наше IT - сообщество.\nЧтобы люди могли в будущем найти тебя, напиши вступительное сообщение о себе с хештегом %(<)-s#знакомство%( 1: + message = await tools.ban_user(msg) + + else: + message = "Укажи причину бана: `/ban [причина]`" + + else: + message = "Сначала надо выбрать пользователя." + + if message: + await msg.reply(message, parse_mode=ParseMode.MARKDOWN) + + +@dp.message_handler(content_types=['new_chat_members'], chat_type=ChatType.SUPERGROUP) +async def new_chat_member(msg: types.Message): + for user in msg.new_chat_members: + user_id = user['id'] + log.info(f"New member: {user['id']}(@{user['username']})") + banned, ban_msg, ban_by = tools.is_banned(user_id) + if banned: + await bot.send_message(msg.chat.id, + f"@{user['username']}, вы забанены [Администратором](tg://user?id={ban_by})\n", + parse_mode=ParseMode.MARKDOWN) + await bot.kick_chat_member(msg.chat.id, user_id) + else: + message = config.new_member_message % { + "username": user['username'], + "<": "", # Start codeblock + "" # Close codeblock + } + await bot.send_message(msg.chat.id, message, parse_mode=ParseMode.HTML) + + +@dp.message_handler(content_types=['text', 'photo', 'document', 'audio', 'sticker', 'animation', 'voice', 'video_note']) +async def all_messages(msg: types.Message): + text = msg.text + user_id = msg.from_user.id + log.info(f"New message from {user_id}(@{msg.from_user.username}) in {msg.chat.id}: '{text}'; " + f"Type: {msg.content_type}") + + if msg.chat.type in [ChatType.SUPERGROUP, ChatType.GROUP]: # Если сообщение пришло из группы + pass + + for k, v in config.static_message.items(): + if k == text[1:len(k) + 1]: + await msg.reply(config.static_message[k], parse_mode=ParseMode.MARKDOWN) + return + if __name__ == '__main__': executor.start_polling(dp) diff --git a/src/sl3.sql b/src/sl3.sql index 96c4303..e200d76 100644 --- a/src/sl3.sql +++ b/src/sl3.sql @@ -1,11 +1,23 @@ DROP TABLE IF EXISTS `users`; +DROP TABLE IF EXISTS `mailing`; CREATE TABLE users ( - id INTEGER PRIMARY KEY AUTOINCREMENT - UNIQUE, - user_id INTEGER UNIQUE - NOT NULL, - warns INTEGER DEFAULT (0), - muted_until DOUBLE DEFAULT (0.0), - banned_until DOUBLE DEFAULT (0.0) -); \ No newline at end of file + id INTEGER PRIMARY KEY AUTOINCREMENT + UNIQUE, + user_id INTEGER UNIQUE + NOT NULL, + warns INTEGER DEFAULT (0), + muted_until DOUBLE DEFAULT (0.0), + banned BOOLEAN DEFAULT (0), + ban_by INTEGER, + ban_msg TEXT +); + + +CREATE TABLE mailing ( + id INTEGER PRIMARY KEY AUTOINCREMENT + UNIQUE, + user_id INTEGER UNIQUE + NOT NULL, + enable BOOLEAN DEFAULT (1) +); diff --git a/src/tools.py b/src/tools.py index e29e5ef..ab6fd70 100644 --- a/src/tools.py +++ b/src/tools.py @@ -2,13 +2,12 @@ import logging import time import aiogram +from aiogram.types import ParseMode from peewee import DoesNotExist -from SqlModels import Users +from SqlModels import Users, Mailing from config import Config -static_log = logging.getLogger('static messages') - class Tools: @@ -18,35 +17,13 @@ class Tools: self.dispatcher = dispatcher self.__admins: dict = {} - @staticmethod - async def __message_handler(msg: aiogram.types.Message, **kwargs): - text = msg.text - static_log.info(f"New message from {msg.from_user.id}({msg.from_user.username}) in {msg.chat.id}: '{text}'") - for k, v in kwargs['__messages__'].items(): - if k.startswith(text[1:len(k)]): - allow = v['allow'] - send = False - if (allow == "all") or \ - (allow == "private" and msg.chat.id > 0) or \ - (allow == "chat" and msg.chat.id < 0): - send = True - if send: - await msg.reply(v['msg']) - break - - def bind_static_messages(self): - __messages__: dict = self.config.raw_config['static_message'] - __messages_keys__ = list(__messages__.keys()) - l = lambda *x: self.__message_handler(*x, __messages__=__messages__) - self.dispatcher.register_message_handler(l, commands=__messages_keys__) - async def _update_admins_list(self): admins = await self.dispatcher.bot.get_chat_administrators(self.config.remote_chat) ids = list() for admin in admins: ids.append(admin['user']['id']) self.__admins = { - "time": time.time()+60.0, + "time": time.time() + 60.0, "object": {"list": admins, "ids": ids} } @@ -59,31 +36,46 @@ class Tools: return self.__admins['object'] - async def add_warn(self, user_id, user_username, chat_id): + @staticmethod + def get_user(user_id): try: user = Users.get(Users.user_id == user_id) except DoesNotExist: user = Users(user_id=user_id) + return user + + async def kick_chat_member(self, chat_id, user_id): + try: + await self.dispatcher.bot.kick_chat_member(chat_id, user_id) + return True + except Exception as e: + await self.dispatcher.bot.send_message(chat_id, + f"Ошибка при исключении [пользователя](tg://user?id={user_id}).\n" + f"Exception: `{e}`", + parse_mode=ParseMode.MARKDOWN) + return False + + async def add_warn(self, user_id, user_username, chat_id): + user = self.get_user(user_id) user.warns += 1 user.save() if user.warns > 3: - try: - await self.dispatcher.bot.kick_chat_member(chat_id, user_id) + + if await self.kick_chat_member(chat_id, user_id): message = f"@{user_username} вёл себя плохо, поэтому теперь он иключён!" - except Exception as e: - message = f"Ошибка при исключении @{user_username}.\nException: `{e}`" + else: + message = None + user.warns = 0 + user.save() + else: message = f"@{user_username}, вы получили {user.warns} из 3 предупреждений.\nВпредь ведите себя лучше!" return message @classmethod - async def reset_warn(cls, user_id, username): - try: - user = Users.get(Users.user_id == user_id) - except DoesNotExist: - user = Users(user_id=user_id) - + def reset_warn(cls, user_id, username): + user = cls.get_user(user_id) if user.warns == 0: message = f"У пользователя @{username} нет предупреждений!" else: @@ -92,3 +84,30 @@ class Tools: user.save() return message + + @classmethod + def is_banned(cls, user_id): + user = cls.get_user(user_id) + return user.banned, user.ban_msg, user.ban_by + + async def ban_user(self, msg: aiogram.types.Message): + user = self.get_user(msg.reply_to_message.from_user.id) + + if await self.kick_chat_member(msg.chat.id, user.user_id): + user.banned = True + user.ban_msg = " ".join(msg.text.split(" ")[1:]) + user.ban_by = msg.from_user.id + user.save() + return f"@{msg.reply_to_message.from_user.username} был забанен по причие `{user.ban_msg}`." + + @classmethod + def register_user(cls, user_id): + registered = False + cls.get_user(user_id).save() + try: + Mailing.get(Mailing.user_id == user_id) + registered = True + except DoesNotExist: + Mailing(user_id=user_id).save() + + return registered