def get_users_chats_with_bot(self, user_id): # type: (int) -> dict chats_available = {} user, created = TtbUser.update_or_create_by_tt_user(None, user_id) if user: if not TtbDjChatAvailable.objects.filter( user=user, subscriber__enabled=True).exists(): self.recreate_cache(user_id) for chat_available in TtbDjChatAvailable.objects.filter( user=user, subscriber__enabled=True): if isinstance(chat_available, TtbDjChatAvailable): chat = self.deserialize_open_api_object( bytes(chat_available.chat, encoding='utf-8'), 'Chat') if isinstance(chat, Chat): chat_ext = ChatExt( chat, self.get_dialog_name(self.title, chat=chat, user_id=user.user_id), json.loads(chat_available.permissions)) chats_available[chat.chat_id] = chat_ext self.lgz.debug( 'chat => chat_id=%(id)s added into list available chats from cache' % {'id': chat.chat_id}) else: self.lgz.debug( f"it can't be, but it happened... user_id={user_id}") return chats_available
def change_subscriber(self, update, enabled, chat_ext=None, api_user=None, recreate_cache=True): # type: (UpdateCmn or None, bool or None, ChatExt, User, bool) -> TtbDjSubscriber subscriber = None defaults = {'updated': now()} if enabled is not None: defaults['enabled'] = enabled if update: if not api_user: api_user = update.user if api_user and not hasattr(api_user, 'disable'): api_user.disable = True try: chat_ext = chat_ext or ChatExt( self.chats.get_chat(update.chat_id), self.get_dialog_name(self.title, user=api_user)) except ApiException: chat_ext = None if chat_ext: defaults['chat_name'] = chat_ext.chat_name defaults['chat_type'] = chat_ext.chat.type defaults['participants_count'] = chat_ext.chat.participants_count subscriber, created = TtbDjSubscriber.objects.update_or_create( chat_id=chat_ext.chat_id, defaults=defaults) db_user = None if api_user: if api_user.is_bot: api_user.disable = True db_user, created = TtbUser.update_or_create_by_tt_user(api_user) api_user.disable = not db_user.enabled if db_user: if subscriber: db_user.subscriber.add(subscriber) else: subscriber, created = TtbDjSubscriber.objects.update_or_create( chat_id=update.chat_id, defaults=defaults) db_user.subscriber.remove(subscriber) if isinstance(subscriber, TtbDjSubscriber) and chat_ext: if subscriber.language is None: if chat_ext.lang: subscriber.language = chat_ext.lang subscriber.save() elif isinstance(db_user, TtbUser) and db_user.language: subscriber.language = db_user.language subscriber.save() if api_user: if recreate_cache and api_user.user_id: self.recreate_cache(api_user.user_id) return subscriber
def recreate_cache(self, user_id=None): # type: (int) -> timedelta or str tb = now() all_bot_relation = self.get_all_chats_with_bot_admin(True) all_chats_members = all_bot_relation['ChatsMembers'] all_members = all_bot_relation['Members'] all_chats = all_bot_relation['Chats'] proc_user_list = list(all_members.keys()) proc_chat_list = list(all_chats.keys()) if user_id: if user_id not in proc_user_list: return _('Current user (%s) not found.') % user_id api_user = all_members[user_id] TtbUser.update_or_create_by_tt_user(api_user) qs_db_user = TtbUser.objects.filter(user_id=user_id) else: # Синхронизация пользователей proc_user_list = [] c_u = 0 for api_user in all_members.values(): if isinstance(api_user, ChatMember): pass c_u += 1 if api_user.is_bot: api_user.disable = True db_user, created = TtbUser.update_or_create_by_tt_user( api_user) u_i = f'{"bot " if api_user.is_bot else ""}name={api_user.name}; user_id={api_user.user_id}; enabled={db_user.enabled}' if api_user.username: u_i += f'; username={api_user.username}' # if api_user.description: # u_i += f' ({api_user.description[:50]})' self.lgz.debug( f'User synchronization +++++++++++++++> ({c_u} of {len(all_members)}) - {u_i}' ) proc_user_list.append(api_user.user_id) duc = TtbUser.objects.filter(enabled=True).exclude( user_id__in=proc_user_list).update(enabled=False, updated=now()) self.lgz.debug(f'Other users disabled: {duc}') qs_db_user = TtbUser.objects.filter(enabled=True) cnt_u = len(qs_db_user) c_u = 0 for db_user in qs_db_user: c_u += 1 self.lgz.debug( f'+++++++++++++++> ({c_u} of {len(qs_db_user)}) - {db_user}') chat_ext_dict = all_chats_members.get(db_user.user_id) api_user = all_members.get(db_user.user_id) if chat_ext_dict and api_user: cnt_c = len(chat_ext_dict) c_c = 0 for chat_ext in chat_ext_dict.values(): c_c += 1 self.lgz.debug( 'Executing %.4f%% (user %d of %d) -> %.4f%% (chat %d of %d)' % (c_u / cnt_u * 100, c_u, cnt_u, c_c / cnt_c * 100, c_c, cnt_c)) self.change_chat_available(chat_ext, db_user, api_user) if not self.chat_is_allowed( chat_ext, db_user.user_id ) and chat_ext.chat_id in proc_chat_list: proc_chat_list.remove(chat_ext.chat_id) elif not chat_ext_dict: self.lgz.debug( f"do not available chats for user_id={db_user.user_id}") TtbDjChatAvailable.objects.filter(user=db_user).delete() TtbUser.objects.filter(enabled=True, user_id=db_user.user_id).update( enabled=False, updated=now()) # Удаление строк кэша по неактивным подписчикам и пользователям if user_id: TtbDjChatAvailable.objects.filter(user__user_id=user_id).exclude( subscriber__chat_id__in=proc_chat_list).delete() TtbDjChatAvailable.objects.filter( user__user_id=user_id, subscriber__enabled=False).delete() else: dcc = TtbDjSubscriber.objects.filter(enabled=True).exclude( chat_id__in=proc_chat_list).update(enabled=False, updated=now()) self.lgz.debug(f'Other chats disabled: {dcc}') TtbDjChatAvailable.objects.filter( subscriber__enabled=False).delete() TtbDjChatAvailable.objects.filter(user__enabled=False).delete() e_t = now() - tb self.lgz.debug(f'100% executed in {e_t}') return e_t