Compare commits

..

No commits in common. "yowsup-2" and "v0.2.2" have entirely different histories.

12 changed files with 320 additions and 447 deletions

View file

@ -2,7 +2,7 @@ Installation and configuration guide
==================================== ====================================
I assume that you have a basic understanding of XMPP and the the concept I assume that you have a basic understanding of XMPP and the the concept
of a XMPP component/transport. If not, please get a book about Jabber of a XMPP component / transport. If not, please get a book about Jabber
or read the standards. or read the standards.
transWhat is a XMPP transport. By this means it extends the transWhat is a XMPP transport. By this means it extends the
@ -44,14 +44,14 @@ Spectrum 2
---------- ----------
Installation Installation
~~~~~~~~~~~~ ^^^^^^^^^^^^
Manual compile latest version from `Github`_. You can use the following Manual compile latest version from `Github`_. You can use the following
guide: guide:
http://spectrum.im/documentation/installation/from\_source\_code.html. http://spectrum.im/documentation/installation/from\_source\_code.html.
Configuration Configuration
~~~~~~~~~~~~~ ^^^^^^^^^^^^^
Create a new file ``/etc/spectrum2/transports/whatsapp.cfg`` with the Create a new file ``/etc/spectrum2/transports/whatsapp.cfg`` with the
following content: following content:
@ -69,7 +69,7 @@ following content:
port = 5221 port = 5221
backend_host = localhost backend_host = localhost
backend = /usr/bin/transwhat backend = /location/to/transwhat/transwhat.py
users_per_backend = 10 users_per_backend = 10
more_resources = 1 more_resources = 1
@ -106,12 +106,11 @@ Install required dependencies:
$ pip install --pre e4u protobuf python-dateutil yowsup2 $ pip install --pre e4u protobuf python-dateutil yowsup2
- e4u_: is a simple emoji4unicode python bindings - **e4u**: is a simple emoji4unicode python bindings
- yowsup_: is a python library that enables you build application - `**yowsup**`_: is a python library that enables you build application
which use WhatsApp service. which use WhatsApp service.
.. _Spectrum 2: http://www.spectrum.im .. _Spectrum 2: http://www.spectrum.im
.. _Yowsup 2: https://github.com/tgalal/yowsup .. _Yowsup 2: https://github.com/tgalal/yowsup
.. _Github: https://github.com/hanzz/libtransport .. _Github: https://github.com/hanzz/libtransport
.. _yowsup: https://github.com/tgalal/yowsup .. _**yowsup**: https://github.com/tgalal/yowsup
.. _e4u: https://pypi.python.org/pypi/e4u

View file

@ -3,10 +3,24 @@ transWhat
transWhat is a WhatsApp XMPP Gateway based on `Spectrum 2`_ and `Yowsup 2`_. transWhat is a WhatsApp XMPP Gateway based on `Spectrum 2`_ and `Yowsup 2`_.
Support Branches
------- ^^^^^^^^
For support and discussions please join the XMPP MUC: **transwhat@conference.0l.de**. - `yowsup-1`_ My original version which is based on @tgalal first
Yowsup version (**deprecated** and broken).
- `yowsup-2`_ Major rewrite from @moyamo for @tgalals new Yowsup 2
(**recommended**).
For production, please use the ``yowsup-2`` branch.
`Installation`_
---------------
`Usage`_
--------
`License`_
----------
Features Features
-------- --------
@ -17,24 +31,6 @@ Features
- Set status message - Set status message
- Groupchats - Groupchats
Installation
------------
transWhat requires a running and configured XMPP server.
Detailed instructions can be found on the `Installation`_ page.
Users find details on the `Usage`_ page.
Branches
--------
- `yowsup-1`_ My original version which is based on @tgalal first
Yowsup version (**deprecated** and broken).
- `yowsup-2`_ Major rewrite from @moyamo for @tgalals new Yowsup 2
(**recommended**).
For production, please use the ``yowsup-2`` branch.
Contributors Contributors
------------ ------------
@ -48,16 +44,12 @@ The following persons have contributed major parts of this code:
- @moyamo (Mohammed Yaseen Mowzer): Port to Yowsup 2 - @moyamo (Mohammed Yaseen Mowzer): Port to Yowsup 2
- @DaZZZl: Improvements to group chats, media & message receipts - @DaZZZl: Improvements to group chats, media & message receipts
License
-------
transWhat is licensed under the GPLv3_ license.
Links Links
----- -----
- An *outdated* project wiki is available `here`_. An *outdated* project wiki is available `here`_.
- An *outdated* writeup of this project is also availabe at my `blog`_.
An *outdated* writeup of this project is also availabe at my `blog`_.
.. _Spectrum 2: http://www.spectrum.im .. _Spectrum 2: http://www.spectrum.im
.. _Yowsup 2: https://github.com/tgalal/yowsup .. _Yowsup 2: https://github.com/tgalal/yowsup
@ -65,6 +57,6 @@ Links
.. _yowsup-2: http://github.com/stv0g/transwhat/tree/yowsup-2 .. _yowsup-2: http://github.com/stv0g/transwhat/tree/yowsup-2
.. _Installation: INSTALL.rst .. _Installation: INSTALL.rst
.. _Usage: USAGE.rst .. _Usage: USAGE.rst
.. _GPLv3: COPYING.rst .. _License: COPYING.rst
.. _here: https://dev.0l.de/wiki/projects/transwhat/ .. _here: https://dev.0l.de/wiki/projects/transwhat/
.. _blog: http://www.steffenvogel.de/2013/06/29/transwhat/ .. _blog: http://www.steffenvogel.de/2013/06/29/transwhat/

View file

@ -89,7 +89,6 @@ message Room {
message RoomList { message RoomList {
repeated string room = 1; repeated string room = 1;
repeated string name = 2; repeated string name = 2;
optional string user = 3;
} }
enum ParticipantFlag { enum ParticipantFlag {
@ -112,7 +111,6 @@ message Participant {
optional string statusMessage = 6; optional string statusMessage = 6;
optional string newname = 7; optional string newname = 7;
optional string iconHash = 8; optional string iconHash = 8;
optional string alias = 9;
} }
message VCard { message VCard {
@ -154,10 +152,6 @@ message BackendConfig {
required string config = 1; required string config = 1;
} }
message APIVersion {
required int32 version = 1;
}
message WrapperMessage { message WrapperMessage {
enum Type { enum Type {
TYPE_CONNECTED = 1; TYPE_CONNECTED = 1;
@ -194,10 +188,8 @@ message WrapperMessage {
TYPE_CONV_MESSAGE_ACK = 33; TYPE_CONV_MESSAGE_ACK = 33;
TYPE_RAW_XML = 34; TYPE_RAW_XML = 34;
TYPE_BUDDIES = 35; TYPE_BUDDIES = 35;
TYPE_API_VERSION = 36;
} }
required Type type = 1; required Type type = 1;
optional bytes payload = 2; optional bytes payload = 2;
} }
; ;

File diff suppressed because one or more lines are too long

5
setup.py Executable file → Normal file
View file

@ -1,5 +1,3 @@
#!/usr/bin/env python
import os import os
import codecs import codecs
from setuptools import setup from setuptools import setup
@ -35,9 +33,6 @@ setup(name='transwhat',
'transWhat', 'transWhat',
'Spectrum2' 'Spectrum2'
], ],
scripts=[
'transWhat/transwhat.py'
],
install_requires=[ install_requires=[
'protobuf', 'protobuf',
'yowsup2', 'yowsup2',

View file

@ -39,6 +39,7 @@ class Bot():
self.commands = { self.commands = {
"help": self._help, "help": self._help,
"prune": self._prune,
"groups": self._groups, "groups": self._groups,
"getgroups": self._getgroups "getgroups": self._getgroups
} }
@ -75,6 +76,7 @@ class Bot():
def _help(self): def _help(self):
self.send("""following bot commands are available: self.send("""following bot commands are available:
\\help show this message \\help show this message
\\prune clear your buddylist
following user commands are available: following user commands are available:
\\lastseen request last online timestamp from buddy \\lastseen request last online timestamp from buddy
@ -84,6 +86,11 @@ following group commands are available
\\groups print all attended groups \\groups print all attended groups
\\getgroups get current groups from WA""") \\getgroups get current groups from WA""")
def _prune(self):
self.session.buddies.prune()
self.session.updateRoster()
self.send("buddy list cleared")
def _groups(self): def _groups(self):
for group in self.session.groups: for group in self.session.groups:
buddy = self.session.groups[group].owner buddy = self.session.groups[group].owner

View file

@ -109,6 +109,7 @@ class BuddyList(dict):
try: del self[number] try: del self[number]
except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number) except KeyError: self.logger.warn("non-existing buddy really didn't exist: %s" % number)
def onStatus(self, contacts): def onStatus(self, contacts):
self.logger.debug("%s received statuses of: %s" % (self.user, contacts)) self.logger.debug("%s received statuses of: %s" % (self.user, contacts))
for number, (status, time) in contacts.iteritems(): for number, (status, time) in contacts.iteritems():
@ -120,6 +121,7 @@ class BuddyList(dict):
buddy.statusMsg = utils.softToUni(status) buddy.statusMsg = utils.softToUni(status)
self.updateSpectrum(buddy) self.updateSpectrum(buddy)
def load(self, buddies): def load(self, buddies):
if self.session.loggedIn: if self.session.loggedIn:
self._load(buddies) self._load(buddies)
@ -163,6 +165,7 @@ class BuddyList(dict):
self.backend.handleBuddyChanged(self.user, buddy.number, buddy.nick, self.backend.handleBuddyChanged(self.user, buddy.number, buddy.nick,
buddy.groups, status, statusMessage=statusmsg, iconHash=iconHash) buddy.groups, status, statusMessage=statusmsg, iconHash=iconHash)
def remove(self, number): def remove(self, number):
try: try:
buddy = self[number] buddy = self[number]
@ -171,7 +174,7 @@ class BuddyList(dict):
protocol_pb2.STATUS_NONE) protocol_pb2.STATUS_NONE)
self.backend.handleBuddyRemoved(self.user, number) self.backend.handleBuddyRemoved(self.user, number)
self.session.unsubscribePresence(number) self.session.unsubscribePresence(number)
# TODO Sync remove # TODO Sync remove
return buddy return buddy
except KeyError: except KeyError:
return None return None

View file

@ -33,9 +33,6 @@ import time
import sys import sys
import os import os
reload(sys)
sys.setdefaultencoding("utf-8")
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
@ -135,34 +132,39 @@ class Session(YowsupApp):
"\n".join(text) + "\nIf you do not join them you will lose messages" "\n".join(text) + "\nIf you do not join them you will lose messages"
#self.bot.send(message) #self.bot.send(message)
def _updateGroups(self, response, _): def _updateGroups(self, response, request):
self.logger.debug('Received groups list %s' % response) self.logger.debug('Received groups list %s' % response)
groups = response.getGroups() groups = response.getGroups()
for group in groups: for group in groups:
room = group.getId() room = group.getId()
# ensure self.groups[room] exists owner = group.getOwner().split('@')[0]
if room not in self.groups: subjectOwner = group.getSubjectOwner().split('@')[0]
owner = group.getOwner().split('@')[0] subject = utils.softToUni(group.getSubject())
subjectOwner = group.getSubjectOwner().split('@')[0]
subject = utils.softToUni(group.getSubject()) if room in self.groups:
self.groups[room] = Group(room, owner, subject, subjectOwner, oroom = self.groups[room]
self.backend, self.user) oroom.owner = owner
# add/update room participants oroom.subjectOwner = subjectOwner
oroom.subject = subject
else:
self.groups[room] = Group(room, owner, subject, subjectOwner, self.backend, self.user)
# self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0])
self.groups[room].addParticipants(group.getParticipants().keys(), self.groups[room].addParticipants(group.getParticipants().keys(),
self.buddies, self.legacyName) self.buddies, self.legacyName)
#self._addParticipantsToRoom(room, group.getParticipants())
if room in self.groupOfflineQueue:
while self.groupOfflineQueue[room]:
msg = self.groupOfflineQueue[room].pop(0)
self.backend.handleMessage(self.user, room, msg[1],
msg[0], "", msg[2])
self.logger.debug("Send queued group message to: %s %s %s" %
(msg[0],msg[1], msg[2]))
self.gotGroupList = True self.gotGroupList = True
# join rooms for room, nick in self.joinRoomQueue:
while self.joinRoomQueue: self.joinRoom(room, nick)
self.joinRoom(*self.joinRoomQueue.pop(0)) self.joinRoomQueue = []
# deliver queued offline messages
for room in self.groupOfflineQueue:
while self.groupOfflineQueue[room]:
msg = self.groupOfflineQueue[room].pop(0)
self.backend.handleMessage(self.user, room, msg[1], msg[0], "",
msg[2])
self.logger.debug("Send queued group message to: %s %s %s" %
(msg[0], msg[1], msg[2]))
# pass update to backend
self.updateRoomList() self.updateRoomList()
def joinRoom(self, room, nick): def joinRoom(self, room, nick):
@ -300,61 +302,81 @@ class Session(YowsupApp):
# Called by superclass # Called by superclass
def onImage(self, image): def onImage(self, image):
self.logger.debug('Received image message: %s' % image)
buddy = image._from.split('@')[0]
participant = image.participant
if image.caption is None: if image.caption is None:
image.caption = '' image.caption = ''
self.onMedia(image, "image") if image.isEncrypted():
self.logger.debug('Received encrypted image message')
if self.backend.specConf is not None and self.backend.specConf.__getitem__("service.web_directory") is not None and self.backend.specConf.__getitem__("service.web_url") is not None :
ipath = "/" + str(image.timestamp) + image.getExtension()
with open(self.backend.specConf.__getitem__("service.web_directory") + ipath,"wb") as f:
f.write(image.getMediaContent())
url = self.backend.specConf.__getitem__("service.web_url") + ipath
else:
self.logger.warn('Received encrypted image: web storage not set in config!')
url = image.url
else:
url = image.url
if participant is not None: # Group message
partname = participant.split('@')[0]
if image._from.split('@')[1] == 'broadcast': # Broadcast message
self.sendMessageToXMPP(partname, self.broadcast_prefix, image.timestamp)
self.sendMessageToXMPP(partname, url, image.timestamp)
self.sendMessageToXMPP(partname, image.caption, image.timestamp)
else: # Group message
self.sendGroupMessageToXMPP(buddy, partname, url, image.timestamp)
self.sendGroupMessageToXMPP(buddy, partname, image.caption, image.timestamp)
else:
self.sendMessageToXMPP(buddy, url, image.timestamp)
self.sendMessageToXMPP(buddy, image.caption, image.timestamp)
self.sendReceipt(image._id, image._from, None, image.participant)
self.recvMsgIDs.append((image._id, image._from, image.participant, image.timestamp))
# Called by superclass # Called by superclass
def onAudio(self, audio): def onAudio(self, audio):
self.onMedia(audio, "audio") self.logger.debug('Received audio message: %s' % audio)
buddy = audio._from.split('@')[0]
participant = audio.participant
message = audio.url
if participant is not None: # Group message
partname = participant.split('@')[0]
if audio._from.split('@')[1] == 'broadcast': # Broadcast message
self.sendMessageToXMPP(partname, self.broadcast_prefix, audio.timestamp)
self.sendMessageToXMPP(partname, message, audio.timestamp)
else: # Group message
self.sendGroupMessageToXMPP(buddy, partname, message, audio.timestamp)
else:
self.sendMessageToXMPP(buddy, message, audio.timestamp)
self.sendReceipt(audio._id, audio._from, None, audio.participant)
self.recvMsgIDs.append((audio._id, audio._from, audio.participant, audio.timestamp))
# Called by superclass # Called by superclass
def onVideo(self, video): def onVideo(self, video):
self.onMedia(video, "video") self.logger.debug('Received video message: %s' % video)
buddy = video._from.split('@')[0]
participant = video.participant
def onMedia(self, media, type):
self.logger.debug('Received %s message: %s' % (type, media))
buddy = media._from.split('@')[0]
participant = media.participant
caption = ''
if media.isEncrypted():
self.logger.debug('Received encrypted media message')
if self.backend.specConf is not None and self.backend.specConf.__getitem__("service.web_directory") is not None and self.backend.specConf.__getitem__("service.web_url") is not None :
ipath = "/" + str(media.timestamp) + media.getExtension()
with open(self.backend.specConf.__getitem__("service.web_directory") + ipath,"wb") as f:
f.write(media.getMediaContent())
url = self.backend.specConf.__getitem__("service.web_url") + ipath
else:
self.logger.warn('Received encrypted media: web storage not set in config!')
url = media.url
else:
url = media.url
if type == 'image':
caption = media.caption
message = video.url
if participant is not None: # Group message if participant is not None: # Group message
partname = participant.split('@')[0] partname = participant.split('@')[0]
if media._from.split('@')[1] == 'broadcast': # Broadcast message if video._from.split('@')[1] == 'broadcast': # Broadcast message
self.sendMessageToXMPP(partname, self.broadcast_prefix, media.timestamp) self.sendMessageToXMPP(partname, self.broadcast_prefix, video.timestamp)
self.sendMessageToXMPP(partname, url, media.timestamp) self.sendMessageToXMPP(partname, message, video.timestamp)
self.sendMessageToXMPP(partname, caption, media.timestamp)
else: # Group message else: # Group message
self.sendGroupMessageToXMPP(buddy, partname, url, media.timestamp) self.sendGroupMessageToXMPP(buddy, partname, message, video.timestamp)
self.sendGroupMessageToXMPP(buddy, partname, caption, media.timestamp)
else: else:
self.sendMessageToXMPP(buddy, url, media.timestamp) self.sendMessageToXMPP(buddy, message, video.timestamp)
self.sendMessageToXMPP(buddy, caption, media.timestamp) self.sendReceipt(video._id, video._from, None, video.participant)
self.recvMsgIDs.append((video._id, video._from, video.participant, video.timestamp))
self.sendReceipt(media._id, media._from, None, media.participant)
self.recvMsgIDs.append((media._id, media._from, media.participant, media.timestamp))
def onLocation(self, location): def onLocation(self, location):
buddy = location._from.split('@')[0] buddy = location._from.split('@')[0]
@ -668,7 +690,7 @@ class Session(YowsupApp):
waId = self.sendTextMessage(sender + '@s.whatsapp.net', message) waId = self.sendTextMessage(sender + '@s.whatsapp.net', message)
self.msgIDs[waId] = MsgIDs(ID, waId) self.msgIDs[waId] = MsgIDs(ID, waId)
# self.logger.info("WA Message send to %s with ID %s", buddy, waId) self.logger.info("WA Message send to %s with ID %s", buddy, waId)
def executeCommand(self, command, room): def executeCommand(self, command, room):
if command == '\\leave': if command == '\\leave':

View file

@ -33,13 +33,13 @@ import asyncore
import sys, os import sys, os
import e4u import e4u
import Queue import Queue
import transWhat.threadutils import threadutils
sys.path.insert(0, os.getcwd()) sys.path.insert(0, os.getcwd())
from Spectrum2.iochannel import IOChannel from Spectrum2.iochannel import IOChannel
from Spectrum2.config import SpectrumConfig from config import SpectrumConfig
from transWhat.whatsappbackend import WhatsAppBackend from whatsappbackend import WhatsAppBackend
from yowsup.common import YowConstants from yowsup.common import YowConstants
from yowsup.stacks import YowStack from yowsup.stacks import YowStack
@ -58,36 +58,36 @@ args, unknown = parser.parse_known_args()
YowConstants.PATH_STORAGE='/var/lib/spectrum2/' + args.j YowConstants.PATH_STORAGE='/var/lib/spectrum2/' + args.j
if args.log is None: if args.log is None:
args.log = '/var/log/spectrum2/' + args.j + '/backends/backend.log' args.log = '/var/log/spectrum2/' + args.j + '/backends/backend.log'
# Logging # Logging
logging.basicConfig( logging.basicConfig(
filename = args.log, filename = args.log,
format = "%(asctime)-15s %(levelname)s %(name)s: %(message)s", format = "%(asctime)-15s %(levelname)s %(name)s: %(message)s",
level = logging.DEBUG if args.debug else logging.INFO level = logging.DEBUG if args.debug else logging.INFO
) )
if args.config is not None: if args.config is not None:
specConf = SpectrumConfig(args.config) specConf = SpectrumConfig(args.config)
else: else:
specConf = None specConf = None
# Handler # Handler
def handleTransportData(data): def handleTransportData(data):
try: try:
plugin.handleDataRead(data) plugin.handleDataRead(data)
except SystemExit as e: except SystemExit as e:
raise e raise e
except: except:
logger = logging.getLogger('transwhat') logger = logging.getLogger('transwhat')
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())
e4u.load() e4u.load()
closed = False closed = False
def connectionClosed(): def connectionClosed():
global closed global closed
closed = True closed = True
# Main # Main
io = IOChannel(args.host, args.port, handleTransportData, connectionClosed) io = IOChannel(args.host, args.port, handleTransportData, connectionClosed)
@ -95,34 +95,34 @@ io = IOChannel(args.host, args.port, handleTransportData, connectionClosed)
plugin = WhatsAppBackend(io, args.j, specConf) plugin = WhatsAppBackend(io, args.j, specConf)
plugin.handleBackendConfig({ plugin.handleBackendConfig({
'features': [ 'features': [
('send_buddies_on_login', 1), ('send_buddies_on_login', 1),
('muc', 'true'), ('muc', 'true'),
], ],
}) })
def main():
while True: while True:
try: try:
asyncore.loop(timeout=1.0, count=10, use_poll = True) asyncore.loop(timeout=1.0, count=10, use_poll = True)
try: try:
callback = YowStack._YowStack__detachedQueue.get(False) #doesn't block callback = YowStack._YowStack__detachedQueue.get(False) #doesn't block
callback() callback()
except Queue.Empty: except Queue.Empty:
pass pass
else: else:
break break
if closed: if closed:
break break
while True: while True:
try: try:
callback = transWhat.threadutils.eventQueue.get_nowait() callback = threadutils.eventQueue.get_nowait()
except Queue.Empty: except Queue.Empty:
break break
else: else:
callback() callback()
except SystemExit: except SystemExit:
break break
except: except:
logger = logging.getLogger('transwhat') logger = logging.getLogger('transwhat')
logger.error(traceback.format_exc()) logger.error(traceback.format_exc())

View file

@ -165,7 +165,7 @@ class WhatsAppBackend(SpectrumBackend):
def handleRawXmlRequest(self, xml): def handleRawXmlRequest(self, xml):
pass pass
def handleMessageAckRequest(self, user, legacyName, ID = 0): def handleMessageAckRequest(self, user, legacyName, ID = 0):
self.logger.info("Meassage ACK request for %s !!" % legacyName) self.logger.info("Meassage ACK request for %s !!" % legacyName)
def sendData(self, data): def sendData(self, data):

View file

@ -25,14 +25,16 @@ __email__ = "post@steffenvogel.de"
""" """
import logging import logging
import os
from yowsup import env from yowsup import env
from yowsup.env import S40YowsupEnv from yowsup.env import S40YowsupEnv
from yowsup.stacks import YowStack, YowStackBuilder from yowsup.stacks import YowStack
from yowsup.common import YowConstants from yowsup.common import YowConstants
from yowsup.layers import YowLayerEvent, YowParallelLayer from yowsup.layers import YowLayerEvent, YowParallelLayer
from yowsup.layers.auth import AuthError from yowsup.layers.auth import AuthError
from yowsup.stacks import YowStack
from yowsup.stacks import YowStackBuilder
from yowsup.common import YowConstants
# Layers # Layers
from yowsup.layers.axolotl import AxolotlSendLayer, AxolotlControlLayer, AxolotlReceivelayer from yowsup.layers.axolotl import AxolotlSendLayer, AxolotlControlLayer, AxolotlReceivelayer
@ -54,10 +56,10 @@ from yowsup.layers.protocol_contacts import YowContactsIqProtocolLayer
from yowsup.layers.protocol_chatstate import YowChatstateProtocolLayer from yowsup.layers.protocol_chatstate import YowChatstateProtocolLayer
from yowsup.layers.protocol_privacy import YowPrivacyProtocolLayer from yowsup.layers.protocol_privacy import YowPrivacyProtocolLayer
from yowsup.layers.protocol_profiles import YowProfilesProtocolLayer from yowsup.layers.protocol_profiles import YowProfilesProtocolLayer
from yowsup.layers.protocol_calls import YowCallsProtocolLayer from yowsup.layers.protocol_calls import YowCallsProtocolLayer
from yowsup.layers.axolotl.props import PROP_IDENTITY_AUTOTRUST
# ProtocolEntities # ProtocolEntities
from yowsup.layers.protocol_acks.protocolentities import * from yowsup.layers.protocol_acks.protocolentities import *
from yowsup.layers.protocol_chatstate.protocolentities import * from yowsup.layers.protocol_chatstate.protocolentities import *
from yowsup.layers.protocol_contacts.protocolentities import * from yowsup.layers.protocol_contacts.protocolentities import *
@ -73,7 +75,9 @@ from yowsup.layers.protocol_iq.protocolentities import *
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
# Registration # Registration
from yowsup.registration import WACodeRequest from yowsup.registration import WACodeRequest
from yowsup.registration import WARegRequest from yowsup.registration import WARegRequest
@ -128,10 +132,9 @@ class YowsupApp(object):
and cellphone number) and cellphone number)
- password: (str) base64 encoded password - password: (str) base64 encoded password
""" """
self.stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, self.stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS,
(username, password)) (username, password))
self.stack.setProp(PROP_IDENTITY_AUTOTRUST, True)
# self.stack.setProp(YowIqProtocolLayer.PROP_PING_INTERVAL, 5) # self.stack.setProp(YowIqProtocolLayer.PROP_PING_INTERVAL, 5)
try: try: