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}'
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)
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()
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)
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)
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)
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}')
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
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]
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}'
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
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
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)
def get_user_chats(cls, uid: int) -> List[int]: return ChatUser.get_user_chats(uid, cids=[CONFIG['anon_chat_id']])
def get_user_chats(uid: int) -> List[int]: return ChatUser.get_user_chats(uid)
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)