diff --git a/app_version.py b/app_version.py index 0638b41..fb2c0ac 100644 --- a/app_version.py +++ b/app_version.py @@ -1 +1 @@ -APP_VERSION = "2.2.4" +APP_VERSION = "2.2.5" diff --git a/main.py b/main.py index c247ef7..7e4dc5e 100644 --- a/main.py +++ b/main.py @@ -1330,7 +1330,7 @@ class VkChatManager(QMainWindow): try: self._set_busy(True, "Статус: загрузка чатов...") self._log_event("load_chats", "start") - conversations = load_chat_conversations(self._vk_call_with_retry, self.vk) + conversations = load_chat_conversations(self._vk_call_with_retry, self.vk, log_func=self._log_event) type_counts = {} non_chat_samples = [] missing_title_count = 0 diff --git a/services/chat_actions.py b/services/chat_actions.py index 0b22475..b2a0a42 100644 --- a/services/chat_actions.py +++ b/services/chat_actions.py @@ -1,6 +1,15 @@ from urllib.parse import urlparse +def _safe_log(log_func, context, message): + if not log_func: + return + try: + log_func(context, message) + except TypeError: + log_func(f"{context}: {message}") + + def resolve_user_ids(vk_call_with_retry, vk_api, links): resolved_ids = [] failed_links = [] @@ -23,24 +32,74 @@ def resolve_user_ids(vk_call_with_retry, vk_api, links): return resolved_ids, failed_links -def load_chat_conversations(vk_call_with_retry, vk_api): +def load_chat_conversations(vk_call_with_retry, vk_api, log_func=None): conversations = [] start_from = None seen_start_tokens = set() + total_count = None + page_num = 0 while True: params = {"count": 200, "filter": "all"} if start_from: if start_from in seen_start_tokens: + _safe_log(log_func, "load_chats_page", f"stop duplicate next_from={start_from}") break params["start_from"] = start_from seen_start_tokens.add(start_from) response = vk_call_with_retry(vk_api.messages.getConversations, **params) + page_num += 1 + if total_count is None: + total_count = response.get("count") page_items = response.get("items", []) + _safe_log( + log_func, + "load_chats_page", + f"page={page_num} items={len(page_items)} next_from={response.get('next_from')} total={total_count}", + ) if not page_items: break conversations.extend(page_items) start_from = response.get("next_from") if not start_from: break + + if total_count is not None and total_count > len(conversations): + _safe_log( + log_func, + "load_chats_fallback", + f"start offset pagination total={total_count} current={len(conversations)}", + ) + seen_keys = set() + for conv in conversations: + peer = (conv.get("conversation") or {}).get("peer", {}) + key = (peer.get("type"), peer.get("id") or peer.get("local_id")) + seen_keys.add(key) + + offset = len(conversations) + safety_pages = 0 + while offset < total_count: + params = {"count": 200, "filter": "all", "offset": offset} + response = vk_call_with_retry(vk_api.messages.getConversations, **params) + page_items = response.get("items", []) + _safe_log( + log_func, + "load_chats_fallback", + f"offset={offset} items={len(page_items)} total={response.get('count')}", + ) + if not page_items: + break + for item in page_items: + peer = (item.get("conversation") or {}).get("peer", {}) + key = (peer.get("type"), peer.get("id") or peer.get("local_id")) + if key in seen_keys: + continue + seen_keys.add(key) + conversations.append(item) + offset += len(page_items) + safety_pages += 1 + if safety_pages > 50: + _safe_log(log_func, "load_chats_fallback", "stop safety_pages>50") + break + return conversations