From 9434b1db6f5a3f2fdc9e8ee3737dba27625685ce Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 14 Dec 2015 20:14:20 +0200 Subject: [PATCH] Request contacts' statuses when user logs in --- buddy.py | 36 ++++++++++++++++++++++++++++-------- session.py | 18 ++++++------------ yowsupwrapper.py | 22 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 20 deletions(-) diff --git a/buddy.py b/buddy.py index 0823163..6c581bf 100644 --- a/buddy.py +++ b/buddy.py @@ -24,6 +24,7 @@ __email__ = "post@steffenvogel.de" from Spectrum2 import protocol_pb2 import logging +import time class Buddy(): @@ -74,6 +75,7 @@ class BuddyList(dict): # new = self.buddies.keys() # contacts = new contacts = self.keys() + contacts.remove('bot') if self.synced == False: self.session.sendSync(contacts, delta = False, interactive = True) @@ -93,11 +95,19 @@ class BuddyList(dict): # for number in contacts: buddy = self[number] - if number != 'bot': - self.backend.handleBuddyChanged(self.user, number, buddy.nick, - buddy.groups, protocol_pb2.STATUS_NONE, - iconHash = buddy.image_hash if buddy.image_hash is not None else "") - self.session.subscribePresence(number) + self.backend.handleBuddyChanged(self.user, number, buddy.nick, + buddy.groups, protocol_pb2.STATUS_NONE, + iconHash = buddy.image_hash if buddy.image_hash is not None else "") + self.session.subscribePresence(number) + self.logger.debug("%s is requesting statuses of: %s", self.user, contacts) + self.session.requestStatuses(contacts, success = self.onStatus) + + def onStatus(self, contacts): + self.logger.debug("%s received statuses of: %s", self.user, contacts) + for number, (status, time) in contacts.iteritems(): + buddy = self[number] + buddy.statusMsg = status + self.updateSpectrum(buddy) def load(self, buddies): @@ -113,21 +123,31 @@ class BuddyList(dict): else: self.session.sendSync([number], delta = True, interactive = True) self.session.subscribePresence(number) + self.session.requestStatuses(contacts, success = self.onStatus) buddy = Buddy(self.owner, number, nick, "", groups, image_hash) self[number] = buddy self.logger.debug("Roster add: %s", buddy) + self.updateSpectrum(buddy) + return buddy + + def updateSpectrum(self, buddy): if buddy.presence == 0: status = protocol_pb2.STATUS_NONE elif buddy.presence == 'unavailable': status = protocol_pb2.STATUS_AWAY else: status = protocol_pb2.STATUS_ONLINE - self.backend.handleBuddyChanged(self.user, number, buddy.nick, - buddy.groups, status, + + statusmsg = buddy.statusMsg + if buddy.lastseen != 0: + timestamp = time.localtime(buddy.lastseen) + statusmsg += time.strftime("\n Last seen: %a, %d %b %Y %H:%M:%S", timestamp) + + self.backend.handleBuddyChanged(self.user, buddy.number, buddy.nick, + buddy.groups, status, statusMessage = statusmsg, iconHash = buddy.image_hash if buddy.image_hash is not None else "") - return buddy def remove(self, number): try: diff --git a/session.py b/session.py index 6dfed66..d481bfe 100644 --- a/session.py +++ b/session.py @@ -30,7 +30,6 @@ from PIL import Image import sys import os -from yowsup.common.tools import TimeTools from yowsup.layers.protocol_media.mediauploader import MediaUploader from yowsup.layers.protocol_media.mediadownloader import MediaDownloader @@ -497,25 +496,20 @@ class Session(YowsupApp): buddy.presence = _type - timestamp = time.localtime(buddy.lastseen) - statusmsg = buddy.statusMsg + time.strftime("\n Last seen: %a, %d %b %Y %H:%M:%S", timestamp) - if _type == "unavailable": - self.onPresenceUnavailable(buddy, statusmsg) + self.onPresenceUnavailable(buddy) else: - self.onPresenceAvailable(buddy, statusmsg) + self.onPresenceAvailable(buddy) - def onPresenceAvailable(self, buddy, statusmsg): + def onPresenceAvailable(self, buddy): self.logger.info("Is available: %s", buddy) - self.backend.handleBuddyChanged(self.user, buddy.number, - buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE, statusmsg, buddy.image_hash) + self.buddies.updateSpectrum(buddy) - def onPresenceUnavailable(self, buddy, statusmsg): + def onPresenceUnavailable(self, buddy): self.logger.info("Is unavailable: %s", buddy) - self.backend.handleBuddyChanged(self.user, buddy.number, - buddy.nick, buddy.groups, protocol_pb2.STATUS_AWAY, statusmsg, buddy.image_hash) + self.buddies.updateSpectrum(buddy) # spectrum RequestMethods def sendTypingStarted(self, buddy): diff --git a/yowsupwrapper.py b/yowsupwrapper.py index d7c3a79..9fdb84c 100644 --- a/yowsupwrapper.py +++ b/yowsupwrapper.py @@ -65,6 +65,7 @@ class YowsupApp(object): YowProfilesProtocolLayer, YowGroupsProtocolLayer, YowPresenceProtocolLayer)), + YowLoggerLayer, YowAxolotlLayer, YowCoderLayer, YowCryptLayer, @@ -291,6 +292,27 @@ class YowsupApp(object): context = GetSyncIqProtocolEntity.CONTEXT_INTERACTIVE if interactive else GetSyncIqProtocolEntity.CONTEXT_REGISTRATION iq = GetSyncIqProtocolEntity(contacts, mode, context) self.sendIq(iq) + + def requestStatuses(self, contacts, success = None, failure = None): + """ + Request the statuses of a number of users. + + Args: + - contacts: ([str]) the phone numbers of users whose statuses you + wish to request + - success: (func) called when request is successful + - failure: (func) called when request has failed + """ + iq = GetStatusesIqProtocolEntity([c + '@s.whatsapp.net' for c in contacts]) + def onSuccess(response, request): + self.logger.debug("Received Statuses %s", response) + s = {} + for k, v in response.statuses.iteritems(): + s[k.split('@')[0]] = v + success(s) + + self.sendIq(iq, onSuccess = onSuccess, onError = failure) + def requestLastSeen(self, phoneNumber, success = None, failure = None): """