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

View file

@ -31,6 +31,7 @@ import sys, os
import MySQLdb
import e4u
import threading
import Queue
sys.path.insert(0, os.getcwd())
@ -39,6 +40,7 @@ from Spectrum2.iochannel import IOChannel
from whatsappbackend import WhatsAppBackend
from constants import *
from yowsup.common import YowConstants
from yowsup.stacks import YowStack
# Arguments
parser = argparse.ArgumentParser()
@ -71,4 +73,10 @@ io = IOChannel(args.host, args.port, handleTransportData)
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_chatstate.protocolentities import *
from yowsup.layers.protocol_acks.protocolentities import *
from yowsup.layers.protocol_receipts.protocolentities import *
class YowsupApp(object):
def __init__(self):
@ -92,10 +93,10 @@ class YowsupApp(object):
YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
except TypeError as e: # Occurs when password is not correctly formated
self.onAuthFailure('password not base64 encoded')
try:
self.stack.loop(timeout=0.5, discrete=0.5)
except AuthError as e: # For some reason Yowsup throws an exception
self.onAuthFailure("%s" % e)
# try:
# self.stack.loop(timeout=0.5, discrete=0.5)
# except AuthError as e: # For some reason Yowsup throws an exception
# self.onAuthFailure("%s" % e)
def logout(self):
"""
@ -114,7 +115,7 @@ class YowsupApp(object):
- participant
"""
receipt = OutgoingReceiptProtocolEntity(_id, _from, read, participant)
self.stack.toLower(receipt)
self.sendEntity(receipt)
def sendTextMessage(self, to, message):
"""
@ -127,6 +128,28 @@ class YowsupApp(object):
messageEntity = TextMessageProtocolEntity(message, to = to)
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):
"""
Called when login is successful.
@ -165,7 +188,7 @@ class YowsupApp(object):
- offline: (True, False or None)
- items
"""
pass
pass
def onAck(self, _id,_class, _from, timestamp):
"""