示例#1
0
文件: forms.py 项目: lamiru/reactor
class SignupForm(UserCreationForm):
    username = forms.RegexField(
        label=_('username'),
        max_length=20,
        regex=r'^[\w_]+$',
        help_text=
        "Required. 20 characters or fewer. Letters, digits and _ only.",
        error_messages={
            'invalid':
            "This value may contain only letters, numbers and _ characters."
        })
    email = forms.EmailField(label=_('email'), )

    def clean_email(self):
        email = self.cleaned_data.get('email').strip()
        if email:
            if User.objects.filter(email=email).exists() == True:
                raise forms.ValidationError('This email is already used.')
        return email

    def save(self, commit=True):
        user = super(SignupForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        if commit:
            user.save()
        return user
示例#2
0
文件: models.py 项目: lamiru/reactor
class Reaction(models.Model):
    actor = models.ForeignKey(settings.AUTH_USER_MODEL, db_index=True)
    topic = models.ForeignKey('self',
                              null=True,
                              blank=True,
                              db_index=True,
                              related_name='topic_reactions')
    target = models.ForeignKey('self',
                               null=True,
                               blank=True,
                               db_index=True,
                               related_name='target_reactions')
    title = models.CharField(max_length=100,
                             db_index=True,
                             verbose_name=_('title'))
    contents = models.TextField(max_length=65535, verbose_name=_('contents'))
    url = models.CharField(max_length=100, blank=True, default='')
    url_title = models.CharField(max_length=100, null=True, blank=True)
    url_description = models.CharField(max_length=255, null=True, blank=True)
    url_image = models.CharField(max_length=100, null=True, blank=True)
    score = models.PositiveIntegerField(default=0,
                                        db_index=True,
                                        verbose_name=_('score'))
    topic_score = models.PositiveIntegerField(default=0, db_index=True)
    deleted = models.BooleanField(default=False, db_index=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return str(self.id)

    def get_tree(self):
        reaction_tree = []
        reaction_tree.append(self)
        for reaction in reaction_tree:
            if reaction.target is not None:
                reaction = reaction.target
                reaction_tree.append(reaction)
        return reaction_tree

    def get_current_generation(self):
        if self.target is not None:
            return self.target.target_reactions.all().order_by('-score')
        else:
            return Reaction.objects.filter(pk=self.pk).order_by('-score')

    def get_previous_generation(self):
        if self.target is not None:
            return self.target.get_current_generation()
        else:
            return None

    def get_next_generation(self):
        return self.target_reactions.all().order_by('-score')

    def get_family(self):
        return Reaction.objects.filter(topic=self.topic)
示例#3
0
    async def check_explicit(self, message: types.Message):
        from explicit import find_explicit

        text = message.text
        chat = message.chat
        user = message.from_user

        # message without text skip
        if not text:
            return

        # is explicit found?
        result = await find_explicit(text)
        if not result:
            await self.cb.register_message(user_id=user.id,
                                           intent='normal message')
            return
        logger.info(f'Found explicit in message: {text}')
        await self.cb.register_message(user_id=user.id,
                                       intent='explicit message')

        # let's delete bad message
        await self.delete_message(message)

        # notify user
        try:
            jail[user.id] += 1
        except KeyError:
            jail[user.id] = 1

        user_link = md.hlink(user.full_name, f'tg://user?id={user.id}')

        if jail.get(user.id) <= 2:
            text = _('Ай-ай-ай, {user_link}!', user_link=user_link)
            await self.say(chat.id, text)
            return

        if 2 < jail.get(user.id) < 5:
            text = _('{user_link}, я же тебя предупреждал... Иди молчать.',
                     user_link=user_link)
            await self.say(chat.id, text)
            await aio.sleep(1)
            await self.restrict_user(chat.id, user.id,
                                     5 * 60 * jail.get(user.id))
            return

        if jail.get(user.id) >= 5:
            text = _('{user_link}, я же тебя предупреждал... Иди в бан.',
                     user_link=user_link)
            await self.say(chat.id, text)
            await aio.sleep(1)
            await self.kick(chat.id, user.id, 24 * 60 * 60)
            jail[user.id] = 3
            return
示例#4
0
async def welcome(message: types.Message):
    """
    Welcomes self and say HELP
    Said welcome message if enabled

    """
    chat = message.chat
    new_users = message.new_chat_members

    # a little delay before welcome
    await types.ChatActions.typing(sleep=2)

    # say help when bot added to new chat
    if await moder.me in new_users:
        logger.info(f'TrueModer added to chat {chat.full_name} ({chat.id})')
        markup = types.InlineKeyboardMarkup()
        markup.add(
            types.InlineKeyboardButton(text=f'ℹ️ Описание',
                                       url=config.FAQ_LINK))
        text = _(
            f"<b>Привет! Я бот-модератор!</b> \n\n"
            f"Чтобы я смог следить за этой группой, мне нужно дать следующие права администратора: \n"
            f"- удалять сообщения; \n"
            f"- блокировать пользователей; \n"
            f"- закреплять сообщения. \n\n"
            f"Подробности в описании:")
        await moder.say(chat.id, text, reply_markup=markup)
示例#5
0
文件: forms.py 项目: lamiru/reactor
class UserForm(forms.ModelForm):
    email = forms.EmailField(label=_('email'), )

    class Meta:
        model = User
        fields = (
            'email',
            'last_name',
            'first_name',
        )
示例#6
0
async def start_private(message: types.Message):
    """
    Handle start and help commands in private chat

    :param message:
    :return:
    """
    text = _('<b>Привет, я бот-модератор!</b> \n'
             'Добавь меня в чат, чтобы навести там порядок')

    markup = types.InlineKeyboardMarkup()
    add_group = f'https://telegram.me/{config.BOT_NAME[1:]}?startgroup=true'
    markup.add(types.InlineKeyboardButton(text=f'Добавить модератора в чат', url=add_group))
    await message.reply(text, reply_markup=markup, reply=False)
示例#7
0
    async def kick(self, chat_id, user_id, seconds):
        until = int((datetime.now() + timedelta(seconds=seconds)).timestamp())

        try:
            await self._bot.kick_chat_member(chat_id, user_id, until)

        except BadRequest as error:

            if 'not enough rights' in str(error):
                logger.debug('Не хватает прав на совершение действия')
                text = _(
                    'Я бы с удовольствием произвёл блокировку, но мне не хватает администраторских прав'
                )
                await self.say(chat_id, text)

            elif 'an administrator of the chat' in str(error):
                logger.debug(f'Зачем-то пытается ограничить админа :)')
                text = _('Я не могу заблокировать админа')
                await self.say(chat_id, text)

            else:
                logger.exception(f'BadRequest: {error}', exc_info=True)
                text = _('Не шмогла :(')
                await self.say(chat_id, text)
示例#8
0
async def group_migrates_to_supergroup(message: types.Message):
    chat = message.chat

    logger.info(
        f'Group {message.migrate_from_chat_id} migrated to supergroup {chat.id}'
    )

    markup = types.InlineKeyboardMarkup()
    markup.add(
        types.InlineKeyboardButton(text=f'ℹ️ Инструкция', url=config.FAQ_LINK))
    text = _(
        f"<b>Отлично!</b> \n\n"
        f"Теперь для начала работы требуется дать мне следующие права администратора: \n"
        f"- удалять сообщения; \n"
        f"- блокировать пользователей \n"
        f"- закреплять сообщения. \n\n"
        f"Подробности в разделе Установка:")
    await moder.say(chat.id, text, reply_markup=markup)
示例#9
0
import asyncio

from aiogram import types
from aiogram.dispatcher import CancelHandler, DEFAULT_RATE_LIMIT, ctx
from aiogram.dispatcher.middlewares import BaseMiddleware
from aiogram.utils import context
from aiogram.utils.exceptions import Throttled
from languages import underscore as _

FLOOD_LOCK_MESSAGE = _('<b>Не надо флудить!</b>')
FLOOD_MUTE_TIME = 120  # seconds


def rate_limit(limit: float, key=None):
    """
    Decorator for configuring rate limit and key in different functions.

    :param limit:
    :param key:
    :return:
    """
    def decorator(func):
        setattr(func, 'throttling_rate_limit', limit)
        if key:
            setattr(func, 'throttling_key', key)
        return func

    return decorator


class ThrottlingMiddleware(BaseMiddleware):
示例#10
0
    },
    {
        'NAME':
        'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/1.9/topics/i18n/

LANGUAGE_CODE = 'ja'

from languages import trans as _

LANGUAGES = [
    ('en', _('english')),
    ('ja', _('japanese')),
]

LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'), )

TIME_ZONE = 'Asia/Tokyo'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Authentication
示例#11
0
    async def restrict_user(self, chat_id, user_id, seconds=61):
        """
        Restriction method with try

        :param chat_id:
        :param user_id:
        :type user_id: int
        :param seconds: int
        :return:
        """
        until = int((datetime.now() + timedelta(seconds=seconds)).timestamp())

        try:
            await self._bot.restrict_chat_member(
                chat_id,
                user_id,
                can_send_messages=False,
                can_send_other_messages=False,
                can_add_web_page_previews=False,
                can_send_media_messages=False,
                until_date=until)

        except BadRequest as e:
            if "Can't demote chat creator" in str(
                    e) or "can't demote chat creator" in str(e):
                logger.debug(
                    f"Restriction: can't demote chat creator at {chat_id}")
                text = _('Не могу я создателя блочить!')
                await self.say(chat_id, text)

            elif "is an administrator of the chat" in str(e):
                logger.debug(
                    f"Restriction: can't demote chat admin at {chat_id}")
                text = _('Не могу я админа блочить!')
                await self.say(chat_id, text)

            elif "Not enough rights to restrict/unrestrict chat member" in str(
                    e):
                logger.warning(
                    f"Not enough rights to restrict/unrestrict chat member at {chat_id}"
                )
                text = _(
                    'Я бы с удовольствием произвёл блокировку, но мне не хватает администраторских прав'
                )
                await self.say(chat_id, text)

            else:
                logger.exception(f'Error: \n{e}', exc_info=True)
                text = _('Не шмогла :(')
                await self.say(chat_id, text)

        except RetryAfter:
            logging.error(f'Message limit reached! {RetryAfter}')

        except Unauthorized as e:
            logger.exception(f'Error: \n{e}', exc_info=True)

        except TelegramAPIError as e:
            logger.error(f'Error: \n{e}')

        else:
            return True
示例#12
0
    async def ban(self, message):
        """
        Executing ban

        :param message:
        :type message: types.Message
        :return: None
        """
        if not isinstance(message, types.Message):
            logger.error("There's no Message with ban request ")
            return

        admin = message.from_user
        chat = message.chat

        logger.info(
            f'moderator.ban received from {log_repr(admin)} in {log_repr(chat)}'
        )

        # check admin rights
        if not await self.check_admin(admin, chat):
            await message.delete()
            await self.restrict_user(chat_id=chat.id,
                                     user_id=admin.id,
                                     seconds=30 * 60)
            return

        # check reply to forward
        if not message.reply_to_message:
            await message.reply(
                f'Эту команду нужно использовать в ответ на чьё-то сообщение')
            return

        abuser = message.reply_to_message.from_user
        if chat and abuser:
            how_long = await self.get_time(message)
            ban_before = int((datetime.now() + how_long.get(TIME)).timestamp())
            need_delete = await self.check_delete(message)

            try:
                await self._bot.kick_chat_member(chat.id, abuser.id,
                                                 ban_before)

            except BadRequest as error:

                if 'not enough rights' in str(error):
                    logger.debug('Не хватает прав на совершение действия')
                    text = _(
                        'Я бы с удовольствием произвёл блокировку, но мне не хватает администраторских прав'
                    )
                    await self.say(chat.id, text)

                elif 'an administrator of the chat' in str(error):
                    logger.debug(f'Зачем-то пытается ограничить админа :)')
                    text = _('Я не могу заблокировать админа')
                    await self.say(chat.id, text)

                else:
                    logger.exception(f'BadRequest: {error}', exc_info=True)
                    text = _('Я не могу заблокировать админа')
                    await self.say(chat.id, text)

            else:
                await self._bot.send_message(chat.id, 'Готово! :)')
                logger.info(
                    f"{admin.full_name} ({admin.id}) "
                    f"ban {abuser.full_name} ({abuser.id}) "
                    f"in {chat.full_name} ({chat.id}) for {how_long.get(TEXT)}"
                )

            if need_delete:
                await self._bot.delete_message(
                    chat.id, message.reply_to_message.message_id)

        else:
            logger.info(f"{admin.first_name} ({admin.id}) "
                        f"хотел кого-то забанить, но не получилось :(")