Ejemplo n.º 1
0
    def get_all_love_outbound(cls,
                              chat_id: int,
                              date=None,
                              header='Вся исходящая страсть',
                              no_love_show_only_count=False) -> str:
        all_chat_users = ChatUser.get_all(chat_id)
        all_users = (User.get(chatuser.uid) for chatuser in all_chat_users)
        all_users = sorted(all_users, key=lambda x: x.fullname)
        all_love = [(user,
                     ReplyTop.get_user_top_strast(chat_id, user.uid, date)[2])
                    for user in all_users if user]

        in_love = [(a, b, ReplyTop.get_user_top_strast(chat_id, b.uid,
                                                       date)[2])
                   for a, b in all_love if b]
        no_love = [a for a, b in all_love if not b]

        in_love_str = '\n'.join(
            cls.__format_pair(a, b, b_pair) for a, b, b_pair in in_love)
        if no_love_show_only_count is False:
            no_love_str = '' if len(
                no_love) == 0 else '\n\nБеcстрастные:\n' + '\n'.join(
                    (cls.__format_pair(a) for a in no_love))
        else:
            no_love_str = '' if len(
                no_love
            ) == 0 else f'\n\nИ еще {pytils.numeral.get_plural(len(no_love), "беcстрастный, беcстрастных, беcстрастных")}'

        return f'{header}:\n\n{in_love_str}{no_love_str}'
Ejemplo n.º 2
0
def command_8(bot: telegram.Bot, update: telegram.Update) -> None:
    message: telegram.Message = update.message
    chat_id = message.chat_id
    from_uid = message.from_user.id

    if not can_use(chat_id, from_uid):
        send_limit(bot, chat_id)
        return

    if not is_day_active():
        return

    all_uids = [chat_user.uid for chat_user in ChatUser.get_all(chat_id)]
    all_users = [User.get(uid) for uid in all_uids]
    males = [user.uid for user in all_users if not user.female]
    females = [user.uid for user in all_users if user.female]

    gifts = get_gifts()
    gift = random_uniq_for_chat(chat_id, gifts)
    result = random_gift_text(from_uid, males, females, gift, random.choice)

    from_user = User.get(result.from_uid)
    to_user = User.get(result.to_uid)
    text = result.text \
        .replace('{from}', from_user.get_username_or_link()) \
        .replace('{to}', to_user.get_username_or_link())
    # reply_markup=get_reply_markup(answer.get_message_buttons()),
    bot.send_message(chat_id, text, parse_mode=telegram.ParseMode.HTML)
Ejemplo n.º 3
0
    def __get_team(cls, chat_id: int) -> str:
        """
        Возвращает строку с "коллективом" чата.

        Пример: "30 👨, 10 👩, 2 👘, 1 🍍, 2 🦆, 1 🐽, 3 🏳️‍🌈, 3 🐈, 4 🐕, 5 🐀"
        """

        # Итоговая строка должна состоять из двух частей:
        # 1. количество мужчин/женщин (берется из настоящих данных)
        # 2. жестко зафиксированная "специальная часть"

        # нам нужно подсчитать количество людей, задействованных в спец части
        # и вычесть это количество из общего списка
        special = '2 👘, 1 🍍, 2 🦆, 1 🐽, 3 🏳️‍🌈, 3 🐈, 2 🐕, 5 🐀'
        special_count = 2 + 1 + 2 + 1 + 3 + 3 + 2 + 5
        chat_users = ChatUser.get_all(chat_id)
        uids = [chat_user.uid for chat_user in chat_users
                ][:-special_count or None]  # вычитаем

        # теперь нужно подсчитать сколько мужчин и женщин осталось
        users = (User.get(uid) for uid in uids)
        genders = ('👩' if user.female else '👨' for user in users if user)
        # noinspection PyArgumentList
        gender_counter = collections.Counter(genders)
        gender_text = ', '.join(
            (f'{count} {gender}'
             for gender, count in gender_counter.most_common()))

        # собираем итоговую строку
        return f'{gender_text}, {special}'.strip(',').strip()
Ejemplo n.º 4
0
 def decorator(_cls, bot: telegram.Bot, update: telegram.Update):
     message = update.edited_message if update.edited_message else update.message
     uid = message.from_user.id
     if not DateChecker.is_day_active():
         return
     if not ChatUser.get(uid, CONFIG['anon_chat_id']):
         return
     return f(_cls, bot, update)
Ejemplo n.º 5
0
 def decorator(_cls, bot: telegram.Bot, update: telegram.Update):
     message = update.edited_message if update.edited_message else update.message
     uid = message.from_user.id
     if not FSBDayModel.is_day_active():
         return
     if not ChatUser.get(uid, CONFIG['anon_chat_id']):
         return
     if cls.is_dinner_time():
         cls.__send_dinner(bot, uid)
         return
     return f(_cls, bot, update)
Ejemplo n.º 6
0
 def find_user(username: Optional[str], chat_id: int) -> Optional[User]:
     if not username:
         return None
     uid = User.get_id_by_name(username)
     if not uid:
         return None
     chat_user = ChatUser.get(uid, chat_id)
     if not chat_user:
         return None
     if chat_user.left:
         return None
     return User.get(uid)
Ejemplo n.º 7
0
 def update_ktolivnul(cls, chat_id: int) -> None:
     logger.debug(f'update_ktolivnul_lock {chat_id}')
     # лок, чтобы работа прошла за раз
     # иначе можно кого-то отметить дважды ливнувшим
     with cls.update_ktolivnul_lock:
         chat_uids_ktolivnul = set([
             int(x)
             for x in pure_cache.get(f'ktolivnul:{chat_id}', '').split(',')
             if x != ''
         ])
         if len(chat_uids_ktolivnul) == 0:
             return
         chat_uids_db = set([x.uid for x in ChatUser.get_all(chat_id)])
         leaved_uids = chat_uids_db - chat_uids_ktolivnul
         if len(leaved_uids) == 0:
             return
         ktolivnul_uid = CONFIG.get('ktolivnul', 0)
         now = datetime.now()
         for uid in leaved_uids:
             ChatUser.add(uid, chat_id, left=True)
             LeaveCollector.add_kick(uid, chat_id, now, ktolivnul_uid)
             logger.info(f'[update_ktolivnul] kick {chat_id}:{uid}')
Ejemplo n.º 8
0
def format_chat_users(chat_id: int, uids: Iterable[int]) -> List[str]:
    """
    Возвращает юзернеймы (с тегами) тех uids, что есть в чате.
    """
    users = []
    chat_uids: Set[int] = {chat_user.uid for chat_user in ChatUser.get_all(chat_id)}
    for uid in uids:
        user = User.get(uid)
        if user is None:
            continue
        if uid not in chat_uids:
            continue
        users.append(user.get_username_or_link())
    return users
Ejemplo n.º 9
0
    def get_leaves(cls, cid, days=3, return_id=False):
        days_ago = (datetime.today() - timedelta(days=days)).replace(
            hour=0, minute=0, second=0, microsecond=0)
        uids: typing.Set[int] = set(
            LeaveCollectorDB.get_leaves(cid, days_ago.strftime('%Y%m%d')))

        # некоторые ливают, а потом возвращаются без сообщений о входе.
        # из-за отсутствия сообщения о входе, LeaveCollector думает, что они не в чате
        # (при этом сам бот в курсе, что они в чате).
        # можно было бы в `leave_check` определять невидимые входы и отмечать их,
        # но проще просто в этом методе получить тех, кто в чате, и исключить их из выдачи.
        chat_uids_db: typing.Set[int] = set(
            [x.uid for x in ChatUser.get_all(cid)])
        true_leaves = uids - chat_uids_db

        if return_id:
            return list(true_leaves)
        return [cls.__format_uid(uid) for uid in true_leaves]
Ejemplo n.º 10
0
    def get_all_love(cls,
                     chat_id: int,
                     date=None,
                     header='Вся страсть') -> str:
        def get_no_love_str(no_love_: List) -> str:
            length = len(no_love_)
            if length == 0:
                return ''
            if length <= 10:
                return '\n\nБеcстрастные:\n' + '\n'.join(
                    (cls.__format_pair(a) for a in no_love_))
            return f'\n\nИ еще {pytils.numeral.get_plural(length, "беcстрастный, беcстрастных, беcстрастных")}'

        def get_narcissist(narcissist_: List[User]) -> str:
            if len(narcissist_) == 0:
                return ''
            return f'\n\nНарциссы:\n' + '\n'.join(
                (cls.__format_pair(a) for a in narcissist_))

        all_chat_users = ChatUser.get_all(chat_id)
        all_users = (User.get(chatuser.uid) for chatuser in all_chat_users)
        all_users = sorted(all_users, key=lambda x: x.fullname)
        all_love = [(user,
                     ReplyTop.get_user_top_strast(chat_id, user.uid, date)[0])
                    for user in all_users if user]

        in_love = [(a, b, ReplyTop.get_user_top_strast(chat_id, b.uid,
                                                       date)[0])
                   for a, b in all_love if b]
        narcissist = [
            a for a, _ in all_love
            if a.uid in CONFIG.get('replylove__narcissist', [])
        ]
        no_love = [
            a for a, b in all_love
            if not b and a.uid not in CONFIG.get('replylove__narcissist', [])
        ]

        in_love_str = '\n'.join(
            cls.__format_pair(a, b, b_pair) for a, b, b_pair in in_love)
        no_love_str = get_no_love_str(no_love)
        narcissist_str = get_narcissist(narcissist)

        return f'{header}:\n\n{in_love_str}{narcissist_str}{no_love_str}'
Ejemplo n.º 11
0
    def get_chat_text(self):
        case_num = FSBDayCaseNumber()
        if case_num.title:
            header = f'<b>Дело № {case_num.num}.</b> <i>"{case_num.title}"</i>'
        else:
            header = f'<b>Дело № {case_num.num}</b>'
        random_user = User.get(ChatUser.get_random(CONFIG['anon_chat_id']))
        user = User.get(self.uid)
        masked_sign = self.__mask_signature(
            random_user if random.randint(0, 100) < 70 else user)
        signature = f'Подписано  {masked_sign}' if random_user else ''
        msg = lstrip_every_line(
            textwrap.dedent(f"""
            {header}

            {self.text}

            {signature}
            """)).strip()
        self.num = case_num.num
        return msg
Ejemplo n.º 12
0
def format_users(chat_id: int, uids: Iterable[int]) -> List[str]:
    """
    Возвращает подготовленный список юзернеймов для указанных uids. Там особые условия.
    """
    users = []
    chat_uids: Set[int] = {chat_user.uid for chat_user in ChatUser.get_all(chat_id)}
    for uid in uids:
        user = User.get(uid)
        # если юзера нет в базе, то добавляем его uid, чтобы хотя бы так можно было удалить
        if user is None:
            users.append(str(uid))
            continue
        # если юзера нет в чате, то добавляем его с тегом
        if uid not in chat_uids:
            users.append(user.get_username_or_link())
            continue
        # если нет юзернейма, указыаем uid
        if user.username is None:
            users.append(f'{user.fullname} ({user.uid})')
            continue
        # для остальных добавляем юзернейм без тега
        users.append(user.username.lstrip('@'))
    return users
Ejemplo n.º 13
0
def leave_check(bot: telegram.Bot, update: telegram.Update):
    message = update.message
    chat_id = message.chat_id
    from_user: telegram.User = message.from_user
    from_uid = from_user.id

    if not from_user.is_bot:
        ChatUser.add(from_uid, chat_id)

    # убыло
    left_user = message.left_chat_member
    if left_user is not None and not left_user.is_bot:
        User.add_user(left_user)
        ChatUser.add(left_user.id, chat_id, left=True)
        if from_uid == left_user.id:  # сам ливнул
            LeaveCollector.add_left(left_user.id, chat_id, message.date,
                                    from_uid)
        else:
            LeaveCollector.add_kick(left_user.id, chat_id, message.date,
                                    from_uid)

    # прибыло
    new_users = message.new_chat_members
    if new_users is not None and len(new_users) > 0:
        for new_user in new_users:
            if new_user.is_bot:
                continue
            User.add_user(new_user)
            ChatUser.add(new_user.id, chat_id)
            if from_uid == new_user.id:  # вошел по инвайт-ссылке
                LeaveCollector.add_invite(new_user.id, chat_id, message.date,
                                          from_uid)
            else:
                LeaveCollector.add_join(new_user.id, chat_id, message.date,
                                        from_uid)
            send_welcome(bot, chat_id, new_user.id)

    # если ктоливнулыч что-то пишет, то запускаем сверку списков
    if 'ktolivnul' in CONFIG and from_uid == CONFIG['ktolivnul']:
        LeaveCollector.update_ktolivnul(chat_id)
Ejemplo n.º 14
0
 def get_user_chats(cls, uid: int) -> List[int]:
     return ChatUser.get_user_chats(uid, cids=[CONFIG['anon_chat_id']])
Ejemplo n.º 15
0
def get_user_chats(uid: int) -> List[int]:
    return ChatUser.get_user_chats(uid)
Ejemplo n.º 16
0
 def decorator(bot: telegram.Bot, update: telegram.Update):
     message = update.edited_message if update.edited_message else update.message
     uid = message.from_user.id
     if not ChatUser.get(uid, CONFIG['anon_chat_id']):
         return
     return func(bot, update)