Add presence updates and looping asyncore.loop()

Add functions to update presence and status

Make asyncore.loop() timeout after some time and call the functions in
the YowStack.__detachedQueue.
This commit is contained in:
moyamo 2015-09-02 17:04:49 +02:00
parent 48313c5475
commit 67c5a7c951
3 changed files with 61 additions and 29 deletions

View file

@ -149,13 +149,13 @@ class Session(YowsupApp):
for number in remove: for number in remove:
self.backend.handleBuddyChanged(self.user, number, "", [], protocol_pb2.STATUS_NONE) self.backend.handleBuddyChanged(self.user, number, "", [], protocol_pb2.STATUS_NONE)
self.backend.handleBuddyRemoved(self.user, number) self.backend.handleBuddyRemoved(self.user, number)
entity = UnsubscribePresenceProtocolEntity(number + "@s.whatsapp.net") # entity = UnsubscribePresenceProtocolEntity(number + "@s.whatsapp.net")
self.toLower(entity) # self.toLower(entity)
for number in add: for number in add:
buddy = self.buddies[number] buddy = self.buddies[number]
entity = SubscribePresenceProtocolEntity(number + "@s.whatsapp.net") # entity = SubscribePresenceProtocolEntity(number + "@s.whatsapp.net")
self.toLower(entity) # self.toLower(entity)
# Called by superclass # Called by superclass
def onAuthSuccess(self, status, kind, creation, def onAuthSuccess(self, status, kind, creation,
@ -176,6 +176,7 @@ class Session(YowsupApp):
# Called by superclass # Called by superclass
def onDisconnect(self): def onDisconnect(self):
self.logger.debug('Disconnected')
self.backend.handleDisconnected(self.user, 0, 'Disconnected for unknown reasons') self.backend.handleDisconnected(self.user, 0, 'Disconnected for unknown reasons')
self.loggedin = False self.loggedin = False
@ -199,7 +200,7 @@ class Session(YowsupApp):
messageContent = utils.softToUni(messageEntity.getBody()) messageContent = utils.softToUni(messageEntity.getBody())
timestamp = messageEntity.getTimestamp() timestamp = messageEntity.getTimestamp()
self.sendReceipt(messageEntity.getId(), messageEntity.getFrom(), 'read', self.sendReceipt(messageEntity.getId(), messageEntity.getFrom(), None,
messageEntity.getParticipant()) messageEntity.getParticipant())
if messageEntity.isBroadcast(): if messageEntity.isBroadcast():
@ -209,7 +210,7 @@ class Session(YowsupApp):
else: else:
self.logger.info("Message received from %s to %s: %s (at ts=%s)", self.logger.info("Message received from %s to %s: %s (at ts=%s)",
buddy, self.legacyName, messageContent, timestamp) buddy, self.legacyName, messageContent, timestamp)
self.session.sendMessageToXMPP(buddy, messageContent, timestamp) self.sendMessageToXMPP(buddy, messageContent, timestamp)
# if receiptRequested: self.call("message_ack", (jid, messageId)) # if receiptRequested: self.call("message_ack", (jid, messageId))
@ -284,14 +285,14 @@ class Session(YowsupApp):
self.status = status self.status = status
if status == protocol_pb2.STATUS_ONLINE or status == protocol_pb2.STATUS_FFC: if status == protocol_pb2.STATUS_ONLINE or status == protocol_pb2.STATUS_FFC:
self.call("presence_sendAvailable") self.sendPresence(True)
else: else:
self.call("presence_sendUnavailable") self.sendPresence(False)
def changeStatusMessage(self, statusMessage): def changeStatusMessage(self, statusMessage):
if (statusMessage != self.statusMessage) or (self.initialized == False): if (statusMessage != self.statusMessage) or (self.initialized == False):
self.statusMessage = statusMessage self.statusMessage = statusMessage
self.call("profile_setStatus", message = statusMessage.encode("utf-8")) self.setStatus(statusMessage.encode('utf-8'))
self.logger.info("Status message changed: %s", statusMessage) self.logger.info("Status message changed: %s", statusMessage)
if self.initialized == False: if self.initialized == False:
@ -465,19 +466,19 @@ class SpectrumLayer(YowInterfaceLayer):
reason = layerEvent.getArg("reason") reason = layerEvent.getArg("reason")
self.logger.info("Disconnected: %s (%s)", self.user, reason) self.logger.info("Disconnected: %s (%s)", self.user, reason)
self.backend.handleDisconnected(self.user, 0, reason) self.backend.handleDisconnected(self.user, 0, reason)
elif layerEvent.getName() == 'presence_sendAvailable': # elif layerEvent.getName() == 'presence_sendAvailable':
entity = AvailablePresenceProtocolEntity() # entity = AvailablePresenceProtocolEntity()
self.toLower(entity) # self.toLower(entity)
retval = True # retval = True
elif layerEvent.getName() == 'presence_sendUnavailable': # elif layerEvent.getName() == 'presence_sendUnavailable':
entity = UnavailablePresenceProtocolEntity() # entity = UnavailablePresenceProtocolEntity()
self.toLower(entity) # self.toLower(entity)
retval = True # retval = True
elif layerEvent.getName() == 'profile_setStatus': # elif layerEvent.getName() == 'profile_setStatus':
# entity = PresenceProtocolEntity(name = layerEvent.getArg('message')) # # entity = PresenceProtocolEntity(name = layerEvent.getArg('message'))
entity = PresenceProtocolEntity(name = 'This status is non-empty') # entity = PresenceProtocolEntity(name = 'This status is non-empty')
self.toLower(entity) # self.toLower(entity)
retval = True # retval = True
# elif layerEvent.getName() == 'message_send': # elif layerEvent.getName() == 'message_send':
# to = layerEvent.getArg('to') # to = layerEvent.getArg('to')
# message = layerEvent.getArg('message') # message = layerEvent.getArg('message')

View file

@ -31,6 +31,7 @@ import sys, os
import MySQLdb import MySQLdb
import e4u import e4u
import threading import threading
import Queue
sys.path.insert(0, os.getcwd()) sys.path.insert(0, os.getcwd())
@ -39,6 +40,7 @@ from Spectrum2.iochannel import IOChannel
from whatsappbackend import WhatsAppBackend from whatsappbackend import WhatsAppBackend
from constants import * from constants import *
from yowsup.common import YowConstants from yowsup.common import YowConstants
from yowsup.stacks import YowStack
# Arguments # Arguments
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
@ -71,4 +73,10 @@ io = IOChannel(args.host, args.port, handleTransportData)
plugin = WhatsAppBackend(io, db) plugin = WhatsAppBackend(io, db)
asyncore.loop(1) while True:
asyncore.loop(timeout=1.0, count=10, use_poll = True)
try:
callback = YowStack._YowStack__detachedQueue.get(False) #doesn't block
callback()
except Queue.Empty:
pass

View file

@ -33,6 +33,7 @@ from yowsup.layers.protocol_presence.protocolentities import *
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
from yowsup.layers.protocol_chatstate.protocolentities import * from yowsup.layers.protocol_chatstate.protocolentities import *
from yowsup.layers.protocol_acks.protocolentities import * from yowsup.layers.protocol_acks.protocolentities import *
from yowsup.layers.protocol_receipts.protocolentities import *
class YowsupApp(object): class YowsupApp(object):
def __init__(self): def __init__(self):
@ -92,10 +93,10 @@ class YowsupApp(object):
YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
except TypeError as e: # Occurs when password is not correctly formated except TypeError as e: # Occurs when password is not correctly formated
self.onAuthFailure('password not base64 encoded') self.onAuthFailure('password not base64 encoded')
try: # try:
self.stack.loop(timeout=0.5, discrete=0.5) # self.stack.loop(timeout=0.5, discrete=0.5)
except AuthError as e: # For some reason Yowsup throws an exception # except AuthError as e: # For some reason Yowsup throws an exception
self.onAuthFailure("%s" % e) # self.onAuthFailure("%s" % e)
def logout(self): def logout(self):
""" """
@ -114,7 +115,7 @@ class YowsupApp(object):
- participant - participant
""" """
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant) receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant)
self.stack.toLower(receipt) self.sendEntity(receipt)
def sendTextMessage(self, to, message): def sendTextMessage(self, to, message):
""" """
@ -127,6 +128,28 @@ class YowsupApp(object):
messageEntity = TextMessageProtocolEntity(message, to = to) messageEntity = TextMessageProtocolEntity(message, to = to)
self.sendEntity(messageEntity) self.sendEntity(messageEntity)
def sendPresence(self, available):
"""
Send presence to whatsapp
Args:
- available: (boolean) True if available false otherwise
"""
if available:
self.sendEntity(AvailablePresenceProtocolEntity())
else:
self.sendEntity(UnavailablePresenceProtocolEntity())
def setStatus(self, statusText):
"""
Send status to whatsapp
Args:
- statusTest: (str) Your whatsapp status
"""
entity = PresenceProtocolEntity(name = statusText if len(statusText) == 0 else 'this')
self.sendEntity(entity)
def onAuthSuccess(self, status, kind, creation, expiration, props, nonce, t): def onAuthSuccess(self, status, kind, creation, expiration, props, nonce, t):
""" """
Called when login is successful. Called when login is successful.