diff options
author | John Smith <mrdoctorwho@gmail.com> | 2018-07-07 13:14:11 +0300 |
---|---|---|
committer | John Smith <mrdoctorwho@gmail.com> | 2018-07-07 13:14:11 +0300 |
commit | 8f2d2b2384e8d8d90f4ba2f3000d6ba2c86ce078 (patch) | |
tree | 668e971b3317465b8a5c72f6fed06c96550e9e98 | |
parent | cd68de33cbf6d7df9aeea9bca7cb1fb27d6c18d7 (diff) |
workaround for the broken messages.get method
-rw-r--r-- | extensions/groupchats.py | 34 | ||||
-rw-r--r-- | gateway.py | 40 | ||||
-rw-r--r-- | library/longpoll.py | 6 |
3 files changed, 52 insertions, 28 deletions
diff --git a/extensions/groupchats.py b/extensions/groupchats.py index 64950c2..2f03633 100644 --- a/extensions/groupchats.py +++ b/extensions/groupchats.py @@ -1,11 +1,9 @@ # coding: utf-8 # This file is a part of VK4XMPP transport -# © simpleApps, 2013 — 2015. -# File contains parts of code from -# BlackSmith mark.1 XMPP Bot, © simpleApps 2011 — 2014. +# © simpleApps, 2013 — 2018. # Installation: -# The extension requires up to 2 fields in the main config: +# This extension requires 2 fields in the main config: # 1. ConferenceServer - the address of your (or not yours?) conference server # Bear in mind that there can be limits on the jabber server for conference per jid. Read the wiki for more details. # 2. CHAT_LIFETIME_LIMIT - the limit of the time after that user considered inactive and will be removed. @@ -29,6 +27,8 @@ mod_groupchat_msg for message handling MAX_UPDATE_DELAY = 3600 # 1 hour CHAT_CLEANUP_DELAY = 86400 # 24 hours +MIN_CHAT_ID = 2000000000 + if not require("attachments") or not require("forwarded_messages"): raise AssertionError("extension 'groupchats' requires 'forwarded_messages' and 'attachments'") @@ -137,6 +137,7 @@ def handleOutgoingChatMessage(user, vkChat): """ Handles outging VK messages and sends them to XMPP """ + if "chat_id" in vkChat: # check if the groupchats support enabled in user's settings if not user.settings.groupchats: @@ -152,12 +153,23 @@ def handleOutgoingChatMessage(user, vkChat): utils.runThread(handleOutgoingChatMessage, (user, vkChat), delay=10) return None - owner = vkChat.get("admin_id", "1") chatID = vkChat["chat_id"] chatJID = "%s_chat#%s@%s" % (user.vk.userID, chatID, ConferenceServer) chat = createChat(user, chatJID) if not chat.initialized: - chat.init(owner, chatID, chatJID, vkChat["title"], vkChat["date"], vkChat["chat_active"].split(",")) + owner = 1 + conversation = user.vk.method("messages.getConversationsById", {"peer_ids": MIN_CHAT_ID + chatID})[1] + settings = conversation.get("chat_settings") + if settings: + members = user.vk.method("messages.getConversationMembers", {"peer_id": MIN_CHAT_ID + chatID}) + members = members.get("items") + chat_active = settings.get("active_ids") + for member in members: + if member["is_admin"]: + owner = member["member_id"] + break + + chat.init(owner, chatID, chatJID, settings["title"], time.time(), chat_active) if not chat.created: if chat.creation_failed: return None @@ -284,12 +296,8 @@ class Chat(object): Updates chat users and sends messages Uses two user lists to prevent losing of any of them """ - all_users = vkChat["chat_active"].split(",") - all_users = [int(user) for user in all_users if user] - if userObject.settings.show_all_chat_users: - users = self.getVKChat(userObject, self.id) - if users: - all_users = users.get("users", []) + vkChat = self.getVKChat(userObject, self.id) + all_users = vkChat.get("users", []) old_users = self.users.keys() buddies = all_users + old_users if TransportID in buddies: @@ -302,7 +310,7 @@ class Chat(object): if user not in old_users: logger.debug("groupchats: user %s has joined the chat %s (jid: %s)", user, self.jid, userObject.source) - # TODO: Transport MUST NOT request a name for each user it sees. + # TODO: Transport MUST NOT request the name for each user it sees. # It should be done with a list of users # E.g. requesting a list of users and get a list of names name = userObject.vk.getUserData(user)["name"] @@ -2,7 +2,7 @@ # coding: utf-8 # vk4xmpp gateway, v3.0 -# © simpleApps, 2013 — 2016. +# © simpleApps, 2013 — 2018. # Program published under the MIT license. __author__ = "mrDoctorWho <mrdoctorwho@gmail.com>" @@ -460,7 +460,7 @@ class VK(object): self.lists = self.method("friends.getLists") return self.lists - def getMessages(self, count=5, mid=0): + def getMessages(self, count=5, mid=0, uid=0): """ Gets the last messages list Args: @@ -469,12 +469,27 @@ class VK(object): Returns: The result of the messages.get method """ - values = {"out": 0, "filters": 1, "count": count} + if mid: - del values["count"] - del values["filters"] - values["last_message_id"] = mid - return self.method("messages.get", values) + mid -= 10 # preventing message loss; receiving last 10 messages before the current one + if uid == 0: + conversations = self.method("messages.getConversations", {"filters": "unread", "start_message_id": mid, "count": count}) + else: + conversations = {"unread_count": 1, "1": {"conversation": {"peer": {"id": uid}}}} + messages = [] + unreadCount = conversations.pop("unread_count") + if unreadCount > 0: + for conversationId in conversations: + conversation = conversations[conversationId] + if isinstance(conversation, dict): + innerConversation = conversation.get("conversation") + if innerConversation: + peer = innerConversation["peer"]["id"] + peerMessageHistory = self.method("messages.getHistory", {"user_id": peer, "start_message_id": mid}) + if len(peerMessageHistory) > 1: + # skipping count-only reponses + messages.append(peerMessageHistory) + return messages # TODO: put this in the DB def getUserID(self): @@ -711,7 +726,7 @@ class User(object): if dist: self.markRosterSet() - def sendMessages(self, init=False, messages=None): + def sendMessages(self, init=False, messages=None, mid=0, uid=0): """ Sends messages from vk to xmpp and call message01 handlers Args: @@ -725,13 +740,14 @@ class User(object): with self.sync: date = 0 if not messages: - messages = self.vk.getMessages(MAX_MESSAGES_PER_REQUEST, self.lastMsgID) + messages = self.vk.getMessages(MAX_MESSAGES_PER_REQUEST, mid or self.lastMsgID, uid) if not messages: # or not messages[0]: return None - messages = sorted(messages[1:], sortMsg) + messages = sorted([message[1] for message in messages], sortMsg) for message in messages: - # If message wasn't sent by our user - if not message["out"]: + # If message wasn'tsent by our user + # and not message["read_state"] + if not message["out"] : Stats["msgin"] += 1 frm = message["uid"] if frm in self.typing: diff --git a/library/longpoll.py b/library/longpoll.py index 99790e8..e20b4f1 100644 --- a/library/longpoll.py +++ b/library/longpoll.py @@ -110,9 +110,9 @@ def processPollResult(user, data): chat = (uid > MIN_CHAT_UID) # a groupchat always has uid > 2000000000 if not out: if not attachments and not chat: - message = [1, - {"out": 0, "uid": uid, "mid": mid, "date": date, "body": body}] - utils.runThread(user.sendMessages, (None, message), "sendMessages-%s" % user.source) + message = [[1, + {"out": 0, "uid": uid, "mid": mid, "date": date, "body": body}]] + utils.runThread(user.sendMessages, (False, message, mid, uid), "sendMessages-%s" % user.source) else: logger.warning( "longpoll: incorrect events number while trying to " |