Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mrDoctorWho/vk4xmpp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Smith <mrdoctorwho@helldev.net>2018-07-26 20:17:37 +0300
committerJohn Smith <mrdoctorwho@helldev.net>2018-07-26 20:17:37 +0300
commit368915900b27ae9eeac372bdda42184b0a9b5207 (patch)
treec93c766a2a1f7c49511e3767927b1ae8989424cd
parent55826a3503bf6ad5f70574a3125a34999ef0bb2d (diff)
Completely rewrite the message reception algorithms (use execute.getMessagesBulk)
-rw-r--r--extensions/groupchats.py12
-rw-r--r--gateway.py86
-rw-r--r--js/getMessagesBulk.js4
-rw-r--r--library/longpoll.py3
4 files changed, 70 insertions, 35 deletions
diff --git a/extensions/groupchats.py b/extensions/groupchats.py
index 2f03633..37e9ea5 100644
--- a/extensions/groupchats.py
+++ b/extensions/groupchats.py
@@ -164,10 +164,14 @@ def handleOutgoingChatMessage(user, vkChat):
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
+ if members:
+ for member in members:
+ if member["is_admin"]:
+ owner = member["member_id"]
+ break
+ else:
+ logger.warning("groupchats: unable to get members for groupchat: %s (%s)", chatID)
+ return None
chat.init(owner, chatID, chatJID, settings["title"], time.time(), chat_active)
if not chat.created:
diff --git a/gateway.py b/gateway.py
index ece54f4..0023f21 100644
--- a/gateway.py
+++ b/gateway.py
@@ -460,43 +460,74 @@ class VK(object):
self.lists = self.method("friends.getLists")
return self.lists
- def getInnerConversation(self, conversation, messages, mid):
- 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})
+ @staticmethod
+ def getPeerIds(conversations):
+ """
+ Returns a list of peer ids that exist in the given conversations
+ Args:
+ conversations: list of Conversations objects
+ Returns:
+ A list of peer id strings
+ """
+ peers = []
+ for conversation in conversations:
+ if isinstance(conversation, dict):
+ innerConversation = conversation.get("conversation")
+ if innerConversation:
+ peers.append(str(innerConversation["peer"]["id"]))
+ return peers
+
+ def getMessagesBulk(self, peers, messages=None, count=20, mid=0):
+ """
+ Recursively receives messages for all the conversations' peers
+ 25 is the maximum number of conversations we can receive in a single request
+ The sky is the limit!
+ Args:
+ peers: a list of peer ids (strings)
+ messages: a list of messages (used internally)
+ count: the number of messages to receive
+ uid: the last message id
+ Returns:
+ A list of VK Message objects
+ """
+ messages = messages or []
+ if peers:
+ parts = (peers[:25], peers[25:])
+ users = ",".join(parts[0])
+ response = self.method("execute.getMessagesBulk", {"users": users, "start_message_id": mid, "count": count}) or []
+ for message in response:
# skipping count-only reponses
- if peerMessageHistory and len(peerMessageHistory) > 1:
- messages.append(peerMessageHistory)
+ if len(message) > 1:
+ if isinstance(message, list):
+ first = message[0]
+ # removing the unread count
+ if isinstance(first, (int, long)):
+ message.remove(first)
+ messages.extend(message)
+ else:
+ # not sure if that's okay
+ # VK is totally unpredictable now
+ logger.warning("no response for execute.getMessagesBulk! Users: %s, mid: %s", users, mid)
+ return self.getMessagesBulk(parts[1], messages, count, mid)
+ return messages
- def getMessages(self, count=5, mid=0, uid=0):
+ def getMessages(self, count=20, mid=0, uid=0):
"""
Gets the last messages list
Args:
count: the number of messages to receive
mid: the last message id
Returns:
- The result of the messages.get method
+ A list of VK Message objects
"""
- if mid:
- mid -= 20 # preventing message loss; receiving last 20 messages before the current one
if uid == 0:
- conversations = self.method("messages.getConversations", {"filters": "unread", "count": count})
+ conversations = self.method("messages.getConversations", {"count": count})
else:
conversations = {"unread_count": 1, "1": {"conversation": {"peer": {"id": uid}}}}
- messages = []
- # what a horrible decision to have two different data types in the response?
if isinstance(conversations, dict):
- unreadCount = conversations.get("unread_count", 0)
- if unreadCount > 0:
- for conversationId in conversations:
- conversation = conversations[conversationId]
- self.getInnerConversation(conversation, messages, mid)
- elif isinstance(conversations, list):
- for conversation in conversations:
- self.getInnerConversation(conversation, messages, mid)
- return messages
+ conversations = conversations.values()
+ peers = VK.getPeerIds(conversations)
+ return self.getMessagesBulk(peers, count=count, mid=mid)
# TODO: put this in the DB
def getUserID(self):
@@ -748,12 +779,11 @@ class User(object):
date = 0
if not messages:
messages = self.vk.getMessages(MAX_MESSAGES_PER_REQUEST, mid or self.lastMsgID, uid)
- if not messages: # or not messages[0]:
+ if not messages:
return None
- messages = sorted([message[1] for message in messages], sortMsg)
+ messages = sorted(messages, sortMsg)
for message in messages:
- # If message wasn't sent by our user
- # and not message["read_state"]
+ # check if message wasn't sent by our user
if not message["out"]:
Stats["msgin"] += 1
frm = message["uid"]
diff --git a/js/getMessagesBulk.js b/js/getMessagesBulk.js
index b1aaac1..765c978 100644
--- a/js/getMessagesBulk.js
+++ b/js/getMessagesBulk.js
@@ -1,13 +1,15 @@
+// Allows to receive conversations' logs for up to 25 users
var users = Args.users.split(",");
var startMessageId = Args.start_message_id;
if (startMessageId == null) {
startMessageId = 0;
}
var history = [];
+var user;
var length = users.length;
while (length > 0) {
var uid = users[length - 1];
- var userHistory = API.messages.getHistory({"user_id": uid, "start_message_id": startMessageId});
+ var userHistory = API.messages.getHistory({"user_id":uid, "start_message_id": startMessageId, "count": Args.count});
history.push(userHistory);
length = length - 1;
}
diff --git a/library/longpoll.py b/library/longpoll.py
index e20b4f1..d75c822 100644
--- a/library/longpoll.py
+++ b/library/longpoll.py
@@ -110,8 +110,7 @@ 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}]]
+ message = [{"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(