Merge pull request #27 from moyamo/yowsup-2

Request contacts' statuses when user logs in
This commit is contained in:
Mohammed Yaseen Mowzer 2015-12-18 20:54:26 +02:00
commit 034a2adfd3
5 changed files with 74 additions and 23 deletions

View File

@ -222,9 +222,19 @@ class SpectrumBackend:
message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA); message = WRAP(d.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_FT_DATA);
self.send(message) self.send(message)
def handleBackendConfig(self, section, key, value): def handleBackendConfig(self, data):
"""
data is a dictionary, whose keys are sections and values are a list of
tuples of configuration key and configuration value.
"""
c = protocol_pb2.BackendConfig() c = protocol_pb2.BackendConfig()
c.config = "[%s]\n%s = %s\n" % (section, key, value) config = []
for section, rest in data.items():
config.append('[%s]' % section)
for key, value in rest:
config.append('%s = %s' % (key, value))
c.config = '\n'.join(config)
message = WRAP(c.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BACKEND_CONFIG); message = WRAP(c.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_BACKEND_CONFIG);
self.send(message) self.send(message)

View File

@ -24,6 +24,7 @@ __email__ = "post@steffenvogel.de"
from Spectrum2 import protocol_pb2 from Spectrum2 import protocol_pb2
import logging import logging
import time
class Buddy(): class Buddy():
@ -74,6 +75,7 @@ class BuddyList(dict):
# new = self.buddies.keys() # new = self.buddies.keys()
# contacts = new # contacts = new
contacts = self.keys() contacts = self.keys()
contacts.remove('bot')
if self.synced == False: if self.synced == False:
self.session.sendSync(contacts, delta = False, interactive = True) self.session.sendSync(contacts, delta = False, interactive = True)
@ -93,11 +95,19 @@ class BuddyList(dict):
# #
for number in contacts: for number in contacts:
buddy = self[number] buddy = self[number]
if number != 'bot': self.backend.handleBuddyChanged(self.user, number, buddy.nick,
self.backend.handleBuddyChanged(self.user, number, buddy.nick, buddy.groups, protocol_pb2.STATUS_NONE,
buddy.groups, protocol_pb2.STATUS_NONE, iconHash = buddy.image_hash if buddy.image_hash is not None else "")
iconHash = buddy.image_hash if buddy.image_hash is not None else "") self.session.subscribePresence(number)
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): def load(self, buddies):
@ -113,21 +123,31 @@ class BuddyList(dict):
else: else:
self.session.sendSync([number], delta = True, interactive = True) self.session.sendSync([number], delta = True, interactive = True)
self.session.subscribePresence(number) self.session.subscribePresence(number)
self.session.requestStatuses([number], success = self.onStatus)
buddy = Buddy(self.owner, number, nick, "", groups, image_hash) buddy = Buddy(self.owner, number, nick, "", groups, image_hash)
self[number] = buddy self[number] = buddy
self.logger.debug("Roster add: %s", buddy) self.logger.debug("Roster add: %s", buddy)
self.updateSpectrum(buddy)
return buddy
def updateSpectrum(self, buddy):
if buddy.presence == 0: if buddy.presence == 0:
status = protocol_pb2.STATUS_NONE status = protocol_pb2.STATUS_NONE
elif buddy.presence == 'unavailable': elif buddy.presence == 'unavailable':
status = protocol_pb2.STATUS_AWAY status = protocol_pb2.STATUS_AWAY
else: else:
status = protocol_pb2.STATUS_ONLINE 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 "") iconHash = buddy.image_hash if buddy.image_hash is not None else "")
return buddy
def remove(self, number): def remove(self, number):
try: try:

View File

@ -30,7 +30,6 @@ from PIL import Image
import sys import sys
import os import os
from yowsup.common.tools import TimeTools
from yowsup.layers.protocol_media.mediauploader import MediaUploader from yowsup.layers.protocol_media.mediauploader import MediaUploader
from yowsup.layers.protocol_media.mediadownloader import MediaDownloader from yowsup.layers.protocol_media.mediadownloader import MediaDownloader
@ -497,25 +496,20 @@ class Session(YowsupApp):
buddy.presence = _type 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": if _type == "unavailable":
self.onPresenceUnavailable(buddy, statusmsg) self.onPresenceUnavailable(buddy)
else: 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.logger.info("Is available: %s", buddy)
self.backend.handleBuddyChanged(self.user, buddy.number, self.buddies.updateSpectrum(buddy)
buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE, statusmsg, buddy.image_hash)
def onPresenceUnavailable(self, buddy, statusmsg): def onPresenceUnavailable(self, buddy):
self.logger.info("Is unavailable: %s", buddy) self.logger.info("Is unavailable: %s", buddy)
self.backend.handleBuddyChanged(self.user, buddy.number, self.buddies.updateSpectrum(buddy)
buddy.nick, buddy.groups, protocol_pb2.STATUS_AWAY, statusmsg, buddy.image_hash)
# spectrum RequestMethods # spectrum RequestMethods
def sendTypingStarted(self, buddy): def sendTypingStarted(self, buddy):

View File

@ -76,7 +76,12 @@ io = IOChannel(args.host, args.port, handleTransportData, connectionClosed)
plugin = WhatsAppBackend(io, args.j) plugin = WhatsAppBackend(io, args.j)
plugin.handleBackendConfig('features', 'send_buddies_on_login', 1) plugin.handleBackendConfig({
'features': [
('send_buddies_on_login', 1),
('muc', 'true'),
],
})
while True: while True:
try: try:

View File

@ -65,6 +65,7 @@ class YowsupApp(object):
YowProfilesProtocolLayer, YowProfilesProtocolLayer,
YowGroupsProtocolLayer, YowGroupsProtocolLayer,
YowPresenceProtocolLayer)), YowPresenceProtocolLayer)),
YowLoggerLayer,
YowAxolotlLayer, YowAxolotlLayer,
YowCoderLayer, YowCoderLayer,
YowCryptLayer, YowCryptLayer,
@ -291,6 +292,27 @@ class YowsupApp(object):
context = GetSyncIqProtocolEntity.CONTEXT_INTERACTIVE if interactive else GetSyncIqProtocolEntity.CONTEXT_REGISTRATION context = GetSyncIqProtocolEntity.CONTEXT_INTERACTIVE if interactive else GetSyncIqProtocolEntity.CONTEXT_REGISTRATION
iq = GetSyncIqProtocolEntity(contacts, mode, context) iq = GetSyncIqProtocolEntity(contacts, mode, context)
self.sendIq(iq) 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): def requestLastSeen(self, phoneNumber, success = None, failure = None):
""" """