From d8140f2dbbea3673a7ce937ad44892c98b9bbd95 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Sep 2015 12:37:39 +0200 Subject: [PATCH 01/10] updated link to wiki --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b204eb..b64f97f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,6 @@ The following persons have contributed major parts of this code: ## Documentation -A project wiki is available [here](http://dev.0l.de/projects/transwhat/start). +A project wiki is available [here](https://dev.0l.de/wiki/projects/transwhat/). An *outdated* writeup of this project is also availabe at my [blog](http://www.steffenvogel.de/2013/06/29/transwhat/). From 4497b2c5c92f3ea12685d5fbac43de3424e45be1 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 8 Sep 2015 12:39:49 +0200 Subject: [PATCH 02/10] added link and description to yowsup --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b64f97f..ac537d9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ transWhat is a WhatsApp XMPP Gateway based on [Spectrum 2](http://www.spectrum.i pip install e4u protobuf mysql dateutil - **e4u**: is a simple emoji4unicode python bindings - - **yowsup**: + - [**yowsup**](https://github.com/tgalal/yowsup): is a python library that enables you build application which use WhatsApp service. - **mysqldb**: MySQL client python bindings #### Spectrum 2 From 652a9f0463abac738a85b1e98cc2e2dc91afb969 Mon Sep 17 00:00:00 2001 From: moyamo Date: Fri, 9 Oct 2015 18:31:57 +0200 Subject: [PATCH 03/10] Pass only expected data to parseFromString Spectrum2/backend.py:handleDataRead is called when transwhat receives data from Spectrum. The parameter `data' contains multiple (or pieces of) WrapperMessages. Instead of passing all the data to wrapper.ParseFromString. We should only pass a single WrapperMessage. --- Spectrum2/backend.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index a027adc..a59567a 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -3,6 +3,7 @@ import socket import struct import sys import os +import logging import google.protobuf @@ -24,6 +25,7 @@ class SpectrumBackend: self.m_pingReceived = False self.m_data = "" self.m_init_res = 0 + self.logger = logging.getLogger(self.__class__.__name__) def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = ""): m = protocol_pb2.ConversationMessage() @@ -347,12 +349,20 @@ class SpectrumBackend: else: return - + packet = self.m_data[4:4+expected_size] wrapper = protocol_pb2.WrapperMessage() - if (wrapper.ParseFromString(self.m_data[4:]) == False): + try: + parseFromString = wrapper.ParseFromString(packet) + except: self.m_data = self.m_data[expected_size+4:] + self.logger.error("Parse from String exception") return - + + if parseFromString == False: + self.m_data = self.m_data[expected_size+4:] + self.logger.error("Parse from String failed") + return + self.m_data = self.m_data[4+expected_size:] if wrapper.type == protocol_pb2.WrapperMessage.TYPE_LOGIN: From f1a6b109f70e7d422307853de1f3daa83654b1f7 Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 14 Sep 2015 19:55:53 +0200 Subject: [PATCH 04/10] Regenerate protocol buffers --- Spectrum2/protocol_pb2.py | 612 +++++++++++++++++++++----------------- 1 file changed, 347 insertions(+), 265 deletions(-) diff --git a/Spectrum2/protocol_pb2.py b/Spectrum2/protocol_pb2.py index e01bd27..638435c 100644 --- a/Spectrum2/protocol_pb2.py +++ b/Spectrum2/protocol_pb2.py @@ -1,88 +1,99 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! +# source: protocol.proto -from google.protobuf import descriptor -from google.protobuf import message -from google.protobuf import reflection +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf.internal import enum_type_wrapper +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database from google.protobuf import descriptor_pb2 # @@protoc_insertion_point(imports) +_sym_db = _symbol_database.Default() -DESCRIPTOR = descriptor.FileDescriptor( + + + +DESCRIPTOR = _descriptor.FileDescriptor( name='protocol.proto', package='pbnetwork', - serialized_pb='\n\x0eprotocol.proto\x12\tpbnetwork\"\x19\n\tConnected\x12\x0c\n\x04user\x18\x01 \x02(\t\"<\n\x0c\x44isconnected\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\r\n\x05\x65rror\x18\x02 \x02(\x05\x12\x0f\n\x07message\x18\x03 \x01(\t\"P\n\x05Login\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\x12\n\nlegacyName\x18\x02 \x02(\t\x12\x10\n\x08password\x18\x03 \x02(\t\x12\x13\n\x0b\x65xtraFields\x18\x04 \x03(\t\"*\n\x06Logout\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\x12\n\nlegacyName\x18\x02 \x02(\t\"\xab\x01\n\x05\x42uddy\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\x12\r\n\x05group\x18\x04 \x03(\t\x12%\n\x06status\x18\x05 \x01(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x06 \x01(\t\x12\x10\n\x08iconHash\x18\x07 \x01(\t\x12\x0f\n\x07\x62locked\x18\x08 \x01(\x08\"\xa9\x01\n\x13\x43onversationMessage\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\x0f\n\x07message\x18\x03 \x02(\t\x12\x10\n\x08nickname\x18\x04 \x01(\t\x12\r\n\x05xhtml\x18\x05 \x01(\t\x12\x11\n\ttimestamp\x18\x06 \x01(\t\x12\x10\n\x08headline\x18\x07 \x01(\x08\x12\n\n\x02id\x18\x08 \x01(\t\x12\n\n\x02pm\x18\t \x01(\x08\"J\n\x04Room\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x10\n\x08nickname\x18\x02 \x02(\t\x12\x0c\n\x04room\x18\x03 \x02(\t\x12\x10\n\x08password\x18\x04 \x01(\t\"&\n\x08RoomList\x12\x0c\n\x04room\x18\x01 \x03(\t\x12\x0c\n\x04name\x18\x02 \x03(\t\"\x9c\x01\n\x0bParticipant\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x0c\n\x04room\x18\x02 \x02(\t\x12\x10\n\x08nickname\x18\x03 \x02(\t\x12\x0c\n\x04\x66lag\x18\x04 \x02(\x05\x12%\n\x06status\x18\x05 \x02(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x06 \x01(\t\x12\x0f\n\x07newname\x18\x07 \x01(\t\"k\n\x05VCard\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\n\n\x02id\x18\x03 \x02(\x05\x12\x10\n\x08\x66ullname\x18\x04 \x01(\t\x12\x10\n\x08nickname\x18\x05 \x01(\t\x12\r\n\x05photo\x18\x06 \x01(\x0c\"X\n\x06Status\x12\x10\n\x08userName\x18\x01 \x02(\t\x12%\n\x06status\x18\x03 \x02(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x04 \x01(\t\"B\n\x05Stats\x12\x0b\n\x03res\x18\x01 \x02(\x05\x12\x10\n\x08init_res\x18\x02 \x02(\x05\x12\x0e\n\x06shared\x18\x03 \x02(\x05\x12\n\n\x02id\x18\x04 \x02(\t\"Y\n\x04\x46ile\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\x10\n\x08\x66ileName\x18\x03 \x02(\t\x12\x0c\n\x04size\x18\x04 \x02(\x05\x12\x0c\n\x04\x66tID\x18\x05 \x01(\x05\".\n\x10\x46ileTransferData\x12\x0c\n\x04\x66tID\x18\x01 \x02(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x02(\x0c\"\x1f\n\rBackendConfig\x12\x0e\n\x06\x63onfig\x18\x01 \x02(\t\"\x9a\x06\n\x0eWrapperMessage\x12,\n\x04type\x18\x01 \x02(\x0e\x32\x1e.pbnetwork.WrapperMessage.Type\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xc8\x05\n\x04Type\x12\x12\n\x0eTYPE_CONNECTED\x10\x01\x12\x15\n\x11TYPE_DISCONNECTED\x10\x02\x12\x0e\n\nTYPE_LOGIN\x10\x03\x12\x0f\n\x0bTYPE_LOGOUT\x10\x04\x12\x16\n\x12TYPE_BUDDY_CHANGED\x10\x06\x12\x16\n\x12TYPE_BUDDY_REMOVED\x10\x07\x12\x15\n\x11TYPE_CONV_MESSAGE\x10\x08\x12\r\n\tTYPE_PING\x10\t\x12\r\n\tTYPE_PONG\x10\n\x12\x12\n\x0eTYPE_JOIN_ROOM\x10\x0b\x12\x13\n\x0fTYPE_LEAVE_ROOM\x10\x0c\x12\x1c\n\x18TYPE_PARTICIPANT_CHANGED\x10\r\x12\x1e\n\x1aTYPE_ROOM_NICKNAME_CHANGED\x10\x0e\x12\x1d\n\x19TYPE_ROOM_SUBJECT_CHANGED\x10\x0f\x12\x0e\n\nTYPE_VCARD\x10\x10\x12\x17\n\x13TYPE_STATUS_CHANGED\x10\x11\x12\x15\n\x11TYPE_BUDDY_TYPING\x10\x12\x12\x1d\n\x19TYPE_BUDDY_STOPPED_TYPING\x10\x13\x12\x14\n\x10TYPE_BUDDY_TYPED\x10\x14\x12\x15\n\x11TYPE_AUTH_REQUEST\x10\x15\x12\x12\n\x0eTYPE_ATTENTION\x10\x16\x12\x0e\n\nTYPE_STATS\x10\x17\x12\x11\n\rTYPE_FT_START\x10\x18\x12\x12\n\x0eTYPE_FT_FINISH\x10\x19\x12\x10\n\x0cTYPE_FT_DATA\x10\x1a\x12\x11\n\rTYPE_FT_PAUSE\x10\x1b\x12\x14\n\x10TYPE_FT_CONTINUE\x10\x1c\x12\r\n\tTYPE_EXIT\x10\x1d\x12\x17\n\x13TYPE_BACKEND_CONFIG\x10\x1e\x12\x0e\n\nTYPE_QUERY\x10\x1f\x12\x12\n\x0eTYPE_ROOM_LIST\x10 \x12\x19\n\x15TYPE_CONV_MESSAGE_ACK\x10!\x12\x10\n\x0cTYPE_RAW_XML\x10\"*\xb3\x05\n\x0f\x43onnectionError\x12\"\n\x1e\x43ONNECTION_ERROR_NETWORK_ERROR\x10\x00\x12%\n!CONNECTION_ERROR_INVALID_USERNAME\x10\x01\x12*\n&CONNECTION_ERROR_AUTHENTICATION_FAILED\x10\x02\x12.\n*CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE\x10\x03\x12#\n\x1f\x43ONNECTION_ERROR_NO_SSL_SUPPORT\x10\x04\x12%\n!CONNECTION_ERROR_ENCRYPTION_ERROR\x10\x05\x12 \n\x1c\x43ONNECTION_ERROR_NAME_IN_USE\x10\x06\x12%\n!CONNECTION_ERROR_INVALID_SETTINGS\x10\x07\x12&\n\"CONNECTION_ERROR_CERT_NOT_PROVIDED\x10\x08\x12#\n\x1f\x43ONNECTION_ERROR_CERT_UNTRUSTED\x10\t\x12!\n\x1d\x43ONNECTION_ERROR_CERT_EXPIRED\x10\n\x12\'\n#CONNECTION_ERROR_CERT_NOT_ACTIVATED\x10\x0b\x12+\n\'CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH\x10\x0c\x12.\n*CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH\x10\r\x12%\n!CONNECTION_ERROR_CERT_SELF_SIGNED\x10\x0e\x12%\n!CONNECTION_ERROR_CERT_OTHER_ERROR\x10\x0f\x12 \n\x1c\x43ONNECTION_ERROR_OTHER_ERROR\x10\x10*\x86\x01\n\nStatusType\x12\x11\n\rSTATUS_ONLINE\x10\x00\x12\x0f\n\x0bSTATUS_AWAY\x10\x01\x12\x0e\n\nSTATUS_FFC\x10\x02\x12\r\n\tSTATUS_XA\x10\x03\x12\x0e\n\nSTATUS_DND\x10\x04\x12\x0f\n\x0bSTATUS_NONE\x10\x05\x12\x14\n\x10STATUS_INVISIBLE\x10\x06*\x88\x02\n\x0fParticipantFlag\x12\x19\n\x15PARTICIPANT_FLAG_NONE\x10\x00\x12\x1e\n\x1aPARTICIPANT_FLAG_MODERATOR\x10\x01\x12\x1d\n\x19PARTICIPANT_FLAG_CONFLICT\x10\x02\x12\x1b\n\x17PARTICIPANT_FLAG_BANNED\x10\x04\x12#\n\x1fPARTICIPANT_FLAG_NOT_AUTHORIZED\x10\x08\x12\x17\n\x13PARTICIPANT_FLAG_ME\x10\x10\x12\x1b\n\x17PARTICIPANT_FLAG_KICKED\x10 \x12#\n\x1fPARTICIPANT_FLAG_ROOM_NOT_FOUND\x10@') + serialized_pb=_b('\n\x0eprotocol.proto\x12\tpbnetwork\"\x19\n\tConnected\x12\x0c\n\x04user\x18\x01 \x02(\t\"<\n\x0c\x44isconnected\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\r\n\x05\x65rror\x18\x02 \x02(\x05\x12\x0f\n\x07message\x18\x03 \x01(\t\"P\n\x05Login\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\x12\n\nlegacyName\x18\x02 \x02(\t\x12\x10\n\x08password\x18\x03 \x02(\t\x12\x13\n\x0b\x65xtraFields\x18\x04 \x03(\t\"*\n\x06Logout\x12\x0c\n\x04user\x18\x01 \x02(\t\x12\x12\n\nlegacyName\x18\x02 \x02(\t\"\xab\x01\n\x05\x42uddy\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\r\n\x05\x61lias\x18\x03 \x01(\t\x12\r\n\x05group\x18\x04 \x03(\t\x12%\n\x06status\x18\x05 \x01(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x06 \x01(\t\x12\x10\n\x08iconHash\x18\x07 \x01(\t\x12\x0f\n\x07\x62locked\x18\x08 \x01(\x08\"\xa9\x01\n\x13\x43onversationMessage\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\x0f\n\x07message\x18\x03 \x02(\t\x12\x10\n\x08nickname\x18\x04 \x01(\t\x12\r\n\x05xhtml\x18\x05 \x01(\t\x12\x11\n\ttimestamp\x18\x06 \x01(\t\x12\x10\n\x08headline\x18\x07 \x01(\x08\x12\n\n\x02id\x18\x08 \x01(\t\x12\n\n\x02pm\x18\t \x01(\x08\"J\n\x04Room\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x10\n\x08nickname\x18\x02 \x02(\t\x12\x0c\n\x04room\x18\x03 \x02(\t\x12\x10\n\x08password\x18\x04 \x01(\t\"&\n\x08RoomList\x12\x0c\n\x04room\x18\x01 \x03(\t\x12\x0c\n\x04name\x18\x02 \x03(\t\"\x9c\x01\n\x0bParticipant\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x0c\n\x04room\x18\x02 \x02(\t\x12\x10\n\x08nickname\x18\x03 \x02(\t\x12\x0c\n\x04\x66lag\x18\x04 \x02(\x05\x12%\n\x06status\x18\x05 \x02(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x06 \x01(\t\x12\x0f\n\x07newname\x18\x07 \x01(\t\"k\n\x05VCard\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\n\n\x02id\x18\x03 \x02(\x05\x12\x10\n\x08\x66ullname\x18\x04 \x01(\t\x12\x10\n\x08nickname\x18\x05 \x01(\t\x12\r\n\x05photo\x18\x06 \x01(\x0c\"X\n\x06Status\x12\x10\n\x08userName\x18\x01 \x02(\t\x12%\n\x06status\x18\x03 \x02(\x0e\x32\x15.pbnetwork.StatusType\x12\x15\n\rstatusMessage\x18\x04 \x01(\t\"B\n\x05Stats\x12\x0b\n\x03res\x18\x01 \x02(\x05\x12\x10\n\x08init_res\x18\x02 \x02(\x05\x12\x0e\n\x06shared\x18\x03 \x02(\x05\x12\n\n\x02id\x18\x04 \x02(\t\"Y\n\x04\x46ile\x12\x10\n\x08userName\x18\x01 \x02(\t\x12\x11\n\tbuddyName\x18\x02 \x02(\t\x12\x10\n\x08\x66ileName\x18\x03 \x02(\t\x12\x0c\n\x04size\x18\x04 \x02(\x05\x12\x0c\n\x04\x66tID\x18\x05 \x01(\x05\".\n\x10\x46ileTransferData\x12\x0c\n\x04\x66tID\x18\x01 \x02(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x02(\x0c\"\x1f\n\rBackendConfig\x12\x0e\n\x06\x63onfig\x18\x01 \x02(\t\"\x9a\x06\n\x0eWrapperMessage\x12,\n\x04type\x18\x01 \x02(\x0e\x32\x1e.pbnetwork.WrapperMessage.Type\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\"\xc8\x05\n\x04Type\x12\x12\n\x0eTYPE_CONNECTED\x10\x01\x12\x15\n\x11TYPE_DISCONNECTED\x10\x02\x12\x0e\n\nTYPE_LOGIN\x10\x03\x12\x0f\n\x0bTYPE_LOGOUT\x10\x04\x12\x16\n\x12TYPE_BUDDY_CHANGED\x10\x06\x12\x16\n\x12TYPE_BUDDY_REMOVED\x10\x07\x12\x15\n\x11TYPE_CONV_MESSAGE\x10\x08\x12\r\n\tTYPE_PING\x10\t\x12\r\n\tTYPE_PONG\x10\n\x12\x12\n\x0eTYPE_JOIN_ROOM\x10\x0b\x12\x13\n\x0fTYPE_LEAVE_ROOM\x10\x0c\x12\x1c\n\x18TYPE_PARTICIPANT_CHANGED\x10\r\x12\x1e\n\x1aTYPE_ROOM_NICKNAME_CHANGED\x10\x0e\x12\x1d\n\x19TYPE_ROOM_SUBJECT_CHANGED\x10\x0f\x12\x0e\n\nTYPE_VCARD\x10\x10\x12\x17\n\x13TYPE_STATUS_CHANGED\x10\x11\x12\x15\n\x11TYPE_BUDDY_TYPING\x10\x12\x12\x1d\n\x19TYPE_BUDDY_STOPPED_TYPING\x10\x13\x12\x14\n\x10TYPE_BUDDY_TYPED\x10\x14\x12\x15\n\x11TYPE_AUTH_REQUEST\x10\x15\x12\x12\n\x0eTYPE_ATTENTION\x10\x16\x12\x0e\n\nTYPE_STATS\x10\x17\x12\x11\n\rTYPE_FT_START\x10\x18\x12\x12\n\x0eTYPE_FT_FINISH\x10\x19\x12\x10\n\x0cTYPE_FT_DATA\x10\x1a\x12\x11\n\rTYPE_FT_PAUSE\x10\x1b\x12\x14\n\x10TYPE_FT_CONTINUE\x10\x1c\x12\r\n\tTYPE_EXIT\x10\x1d\x12\x17\n\x13TYPE_BACKEND_CONFIG\x10\x1e\x12\x0e\n\nTYPE_QUERY\x10\x1f\x12\x12\n\x0eTYPE_ROOM_LIST\x10 \x12\x19\n\x15TYPE_CONV_MESSAGE_ACK\x10!\x12\x10\n\x0cTYPE_RAW_XML\x10\"*\xb3\x05\n\x0f\x43onnectionError\x12\"\n\x1e\x43ONNECTION_ERROR_NETWORK_ERROR\x10\x00\x12%\n!CONNECTION_ERROR_INVALID_USERNAME\x10\x01\x12*\n&CONNECTION_ERROR_AUTHENTICATION_FAILED\x10\x02\x12.\n*CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE\x10\x03\x12#\n\x1f\x43ONNECTION_ERROR_NO_SSL_SUPPORT\x10\x04\x12%\n!CONNECTION_ERROR_ENCRYPTION_ERROR\x10\x05\x12 \n\x1c\x43ONNECTION_ERROR_NAME_IN_USE\x10\x06\x12%\n!CONNECTION_ERROR_INVALID_SETTINGS\x10\x07\x12&\n\"CONNECTION_ERROR_CERT_NOT_PROVIDED\x10\x08\x12#\n\x1f\x43ONNECTION_ERROR_CERT_UNTRUSTED\x10\t\x12!\n\x1d\x43ONNECTION_ERROR_CERT_EXPIRED\x10\n\x12\'\n#CONNECTION_ERROR_CERT_NOT_ACTIVATED\x10\x0b\x12+\n\'CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH\x10\x0c\x12.\n*CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH\x10\r\x12%\n!CONNECTION_ERROR_CERT_SELF_SIGNED\x10\x0e\x12%\n!CONNECTION_ERROR_CERT_OTHER_ERROR\x10\x0f\x12 \n\x1c\x43ONNECTION_ERROR_OTHER_ERROR\x10\x10*\x86\x01\n\nStatusType\x12\x11\n\rSTATUS_ONLINE\x10\x00\x12\x0f\n\x0bSTATUS_AWAY\x10\x01\x12\x0e\n\nSTATUS_FFC\x10\x02\x12\r\n\tSTATUS_XA\x10\x03\x12\x0e\n\nSTATUS_DND\x10\x04\x12\x0f\n\x0bSTATUS_NONE\x10\x05\x12\x14\n\x10STATUS_INVISIBLE\x10\x06*\x88\x02\n\x0fParticipantFlag\x12\x19\n\x15PARTICIPANT_FLAG_NONE\x10\x00\x12\x1e\n\x1aPARTICIPANT_FLAG_MODERATOR\x10\x01\x12\x1d\n\x19PARTICIPANT_FLAG_CONFLICT\x10\x02\x12\x1b\n\x17PARTICIPANT_FLAG_BANNED\x10\x04\x12#\n\x1fPARTICIPANT_FLAG_NOT_AUTHORIZED\x10\x08\x12\x17\n\x13PARTICIPANT_FLAG_ME\x10\x10\x12\x1b\n\x17PARTICIPANT_FLAG_KICKED\x10 \x12#\n\x1fPARTICIPANT_FLAG_ROOM_NOT_FOUND\x10@') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) -_CONNECTIONERROR = descriptor.EnumDescriptor( +_CONNECTIONERROR = _descriptor.EnumDescriptor( name='ConnectionError', full_name='pbnetwork.ConnectionError', filename=None, file=DESCRIPTOR, values=[ - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_NETWORK_ERROR', index=0, number=0, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_INVALID_USERNAME', index=1, number=1, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_AUTHENTICATION_FAILED', index=2, number=2, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE', index=3, number=3, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_NO_SSL_SUPPORT', index=4, number=4, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_ENCRYPTION_ERROR', index=5, number=5, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_NAME_IN_USE', index=6, number=6, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_INVALID_SETTINGS', index=7, number=7, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_NOT_PROVIDED', index=8, number=8, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_UNTRUSTED', index=9, number=9, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_EXPIRED', index=10, number=10, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_NOT_ACTIVATED', index=11, number=11, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH', index=12, number=12, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH', index=13, number=13, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_SELF_SIGNED', index=14, number=14, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_CERT_OTHER_ERROR', index=15, number=15, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='CONNECTION_ERROR_OTHER_ERROR', index=16, number=16, options=None, type=None), @@ -92,39 +103,40 @@ _CONNECTIONERROR = descriptor.EnumDescriptor( serialized_start=2102, serialized_end=2793, ) +_sym_db.RegisterEnumDescriptor(_CONNECTIONERROR) - -_STATUSTYPE = descriptor.EnumDescriptor( +ConnectionError = enum_type_wrapper.EnumTypeWrapper(_CONNECTIONERROR) +_STATUSTYPE = _descriptor.EnumDescriptor( name='StatusType', full_name='pbnetwork.StatusType', filename=None, file=DESCRIPTOR, values=[ - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_ONLINE', index=0, number=0, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_AWAY', index=1, number=1, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_FFC', index=2, number=2, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_XA', index=3, number=3, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_DND', index=4, number=4, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_NONE', index=5, number=5, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='STATUS_INVISIBLE', index=6, number=6, options=None, type=None), @@ -134,43 +146,44 @@ _STATUSTYPE = descriptor.EnumDescriptor( serialized_start=2796, serialized_end=2930, ) +_sym_db.RegisterEnumDescriptor(_STATUSTYPE) - -_PARTICIPANTFLAG = descriptor.EnumDescriptor( +StatusType = enum_type_wrapper.EnumTypeWrapper(_STATUSTYPE) +_PARTICIPANTFLAG = _descriptor.EnumDescriptor( name='ParticipantFlag', full_name='pbnetwork.ParticipantFlag', filename=None, file=DESCRIPTOR, values=[ - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_NONE', index=0, number=0, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_MODERATOR', index=1, number=1, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_CONFLICT', index=2, number=2, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_BANNED', index=3, number=4, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_NOT_AUTHORIZED', index=4, number=8, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_ME', index=5, number=16, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_KICKED', index=6, number=32, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='PARTICIPANT_FLAG_ROOM_NOT_FOUND', index=7, number=64, options=None, type=None), @@ -180,8 +193,9 @@ _PARTICIPANTFLAG = descriptor.EnumDescriptor( serialized_start=2933, serialized_end=3197, ) +_sym_db.RegisterEnumDescriptor(_PARTICIPANTFLAG) - +ParticipantFlag = enum_type_wrapper.EnumTypeWrapper(_PARTICIPANTFLAG) CONNECTION_ERROR_NETWORK_ERROR = 0 CONNECTION_ERROR_INVALID_USERNAME = 1 CONNECTION_ERROR_AUTHENTICATION_FAILED = 2 @@ -216,141 +230,141 @@ PARTICIPANT_FLAG_KICKED = 32 PARTICIPANT_FLAG_ROOM_NOT_FOUND = 64 -_WRAPPERMESSAGE_TYPE = descriptor.EnumDescriptor( +_WRAPPERMESSAGE_TYPE = _descriptor.EnumDescriptor( name='Type', full_name='pbnetwork.WrapperMessage.Type', filename=None, file=DESCRIPTOR, values=[ - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_CONNECTED', index=0, number=1, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_DISCONNECTED', index=1, number=2, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_LOGIN', index=2, number=3, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_LOGOUT', index=3, number=4, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BUDDY_CHANGED', index=4, number=6, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BUDDY_REMOVED', index=5, number=7, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_CONV_MESSAGE', index=6, number=8, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_PING', index=7, number=9, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_PONG', index=8, number=10, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_JOIN_ROOM', index=9, number=11, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_LEAVE_ROOM', index=10, number=12, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_PARTICIPANT_CHANGED', index=11, number=13, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_ROOM_NICKNAME_CHANGED', index=12, number=14, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_ROOM_SUBJECT_CHANGED', index=13, number=15, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_VCARD', index=14, number=16, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_STATUS_CHANGED', index=15, number=17, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BUDDY_TYPING', index=16, number=18, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BUDDY_STOPPED_TYPING', index=17, number=19, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BUDDY_TYPED', index=18, number=20, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_AUTH_REQUEST', index=19, number=21, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_ATTENTION', index=20, number=22, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_STATS', index=21, number=23, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_FT_START', index=22, number=24, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_FT_FINISH', index=23, number=25, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_FT_DATA', index=24, number=26, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_FT_PAUSE', index=25, number=27, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_FT_CONTINUE', index=26, number=28, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_EXIT', index=27, number=29, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_BACKEND_CONFIG', index=28, number=30, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_QUERY', index=29, number=31, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_ROOM_LIST', index=30, number=32, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_CONV_MESSAGE_ACK', index=31, number=33, options=None, type=None), - descriptor.EnumValueDescriptor( + _descriptor.EnumValueDescriptor( name='TYPE_RAW_XML', index=32, number=34, options=None, type=None), @@ -360,19 +374,20 @@ _WRAPPERMESSAGE_TYPE = descriptor.EnumDescriptor( serialized_start=1387, serialized_end=2099, ) +_sym_db.RegisterEnumDescriptor(_WRAPPERMESSAGE_TYPE) -_CONNECTED = descriptor.Descriptor( +_CONNECTED = _descriptor.Descriptor( name='Connected', full_name='pbnetwork.Connected', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='user', full_name='pbnetwork.Connected.user', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -385,36 +400,38 @@ _CONNECTED = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=29, serialized_end=54, ) -_DISCONNECTED = descriptor.Descriptor( +_DISCONNECTED = _descriptor.Descriptor( name='Disconnected', full_name='pbnetwork.Disconnected', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='user', full_name='pbnetwork.Disconnected.user', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='error', full_name='pbnetwork.Disconnected.error', index=1, number=2, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='message', full_name='pbnetwork.Disconnected.message', index=2, number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -427,40 +444,42 @@ _DISCONNECTED = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=56, serialized_end=116, ) -_LOGIN = descriptor.Descriptor( +_LOGIN = _descriptor.Descriptor( name='Login', full_name='pbnetwork.Login', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='user', full_name='pbnetwork.Login.user', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='legacyName', full_name='pbnetwork.Login.legacyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='password', full_name='pbnetwork.Login.password', index=2, number=3, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='extraFields', full_name='pbnetwork.Login.extraFields', index=3, number=4, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], @@ -476,29 +495,31 @@ _LOGIN = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=118, serialized_end=198, ) -_LOGOUT = descriptor.Descriptor( +_LOGOUT = _descriptor.Descriptor( name='Logout', full_name='pbnetwork.Logout', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='user', full_name='pbnetwork.Logout.user', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='legacyName', full_name='pbnetwork.Logout.legacyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -511,68 +532,70 @@ _LOGOUT = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=200, serialized_end=242, ) -_BUDDY = descriptor.Descriptor( +_BUDDY = _descriptor.Descriptor( name='Buddy', full_name='pbnetwork.Buddy', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.Buddy.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='buddyName', full_name='pbnetwork.Buddy.buddyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='alias', full_name='pbnetwork.Buddy.alias', index=2, number=3, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='group', full_name='pbnetwork.Buddy.group', index=3, number=4, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='status', full_name='pbnetwork.Buddy.status', index=4, number=5, type=14, cpp_type=8, label=1, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='statusMessage', full_name='pbnetwork.Buddy.statusMessage', index=5, number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='iconHash', full_name='pbnetwork.Buddy.iconHash', index=6, number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='blocked', full_name='pbnetwork.Buddy.blocked', index=7, number=8, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, @@ -588,75 +611,77 @@ _BUDDY = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=245, serialized_end=416, ) -_CONVERSATIONMESSAGE = descriptor.Descriptor( +_CONVERSATIONMESSAGE = _descriptor.Descriptor( name='ConversationMessage', full_name='pbnetwork.ConversationMessage', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.ConversationMessage.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='buddyName', full_name='pbnetwork.ConversationMessage.buddyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='message', full_name='pbnetwork.ConversationMessage.message', index=2, number=3, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='nickname', full_name='pbnetwork.ConversationMessage.nickname', index=3, number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='xhtml', full_name='pbnetwork.ConversationMessage.xhtml', index=4, number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='timestamp', full_name='pbnetwork.ConversationMessage.timestamp', index=5, number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='headline', full_name='pbnetwork.ConversationMessage.headline', index=6, number=7, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='id', full_name='pbnetwork.ConversationMessage.id', index=7, number=8, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='pm', full_name='pbnetwork.ConversationMessage.pm', index=8, number=9, type=8, cpp_type=7, label=1, has_default_value=False, default_value=False, @@ -672,43 +697,45 @@ _CONVERSATIONMESSAGE = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=419, serialized_end=588, ) -_ROOM = descriptor.Descriptor( +_ROOM = _descriptor.Descriptor( name='Room', full_name='pbnetwork.Room', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.Room.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='nickname', full_name='pbnetwork.Room.nickname', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='room', full_name='pbnetwork.Room.room', index=2, number=3, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='password', full_name='pbnetwork.Room.password', index=3, number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -721,26 +748,28 @@ _ROOM = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=590, serialized_end=664, ) -_ROOMLIST = descriptor.Descriptor( +_ROOMLIST = _descriptor.Descriptor( name='RoomList', full_name='pbnetwork.RoomList', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='room', full_name='pbnetwork.RoomList.room', index=0, number=1, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='name', full_name='pbnetwork.RoomList.name', index=1, number=2, type=9, cpp_type=9, label=3, has_default_value=False, default_value=[], @@ -756,64 +785,66 @@ _ROOMLIST = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=666, serialized_end=704, ) -_PARTICIPANT = descriptor.Descriptor( +_PARTICIPANT = _descriptor.Descriptor( name='Participant', full_name='pbnetwork.Participant', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.Participant.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='room', full_name='pbnetwork.Participant.room', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='nickname', full_name='pbnetwork.Participant.nickname', index=2, number=3, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='flag', full_name='pbnetwork.Participant.flag', index=3, number=4, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='status', full_name='pbnetwork.Participant.status', index=4, number=5, type=14, cpp_type=8, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='statusMessage', full_name='pbnetwork.Participant.statusMessage', index=5, number=6, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='newname', full_name='pbnetwork.Participant.newname', index=6, number=7, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -826,57 +857,59 @@ _PARTICIPANT = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=707, serialized_end=863, ) -_VCARD = descriptor.Descriptor( +_VCARD = _descriptor.Descriptor( name='VCard', full_name='pbnetwork.VCard', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.VCard.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='buddyName', full_name='pbnetwork.VCard.buddyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='id', full_name='pbnetwork.VCard.id', index=2, number=3, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='fullname', full_name='pbnetwork.VCard.fullname', index=3, number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='nickname', full_name='pbnetwork.VCard.nickname', index=4, number=5, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='photo', full_name='pbnetwork.VCard.photo', index=5, number=6, type=12, cpp_type=9, label=1, - has_default_value=False, default_value="", + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -889,36 +922,38 @@ _VCARD = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=865, serialized_end=972, ) -_STATUS = descriptor.Descriptor( +_STATUS = _descriptor.Descriptor( name='Status', full_name='pbnetwork.Status', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.Status.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='status', full_name='pbnetwork.Status.status', index=1, number=3, type=14, cpp_type=8, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='statusMessage', full_name='pbnetwork.Status.statusMessage', index=2, number=4, type=9, cpp_type=9, label=1, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -931,43 +966,45 @@ _STATUS = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=974, serialized_end=1062, ) -_STATS = descriptor.Descriptor( +_STATS = _descriptor.Descriptor( name='Stats', full_name='pbnetwork.Stats', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='res', full_name='pbnetwork.Stats.res', index=0, number=1, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='init_res', full_name='pbnetwork.Stats.init_res', index=1, number=2, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='shared', full_name='pbnetwork.Stats.shared', index=2, number=3, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='id', full_name='pbnetwork.Stats.id', index=3, number=4, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -980,47 +1017,49 @@ _STATS = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1064, serialized_end=1130, ) -_FILE = descriptor.Descriptor( +_FILE = _descriptor.Descriptor( name='File', full_name='pbnetwork.File', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='userName', full_name='pbnetwork.File.userName', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='buddyName', full_name='pbnetwork.File.buddyName', index=1, number=2, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='fileName', full_name='pbnetwork.File.fileName', index=2, number=3, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='size', full_name='pbnetwork.File.size', index=3, number=4, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='ftID', full_name='pbnetwork.File.ftID', index=4, number=5, type=5, cpp_type=1, label=1, has_default_value=False, default_value=0, @@ -1036,29 +1075,31 @@ _FILE = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1132, serialized_end=1221, ) -_FILETRANSFERDATA = descriptor.Descriptor( +_FILETRANSFERDATA = _descriptor.Descriptor( name='FileTransferData', full_name='pbnetwork.FileTransferData', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='ftID', full_name='pbnetwork.FileTransferData.ftID', index=0, number=1, type=5, cpp_type=1, label=2, has_default_value=False, default_value=0, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='data', full_name='pbnetwork.FileTransferData.data', index=1, number=2, type=12, cpp_type=9, label=2, - has_default_value=False, default_value="", + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -1071,22 +1112,24 @@ _FILETRANSFERDATA = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1223, serialized_end=1269, ) -_BACKENDCONFIG = descriptor.Descriptor( +_BACKENDCONFIG = _descriptor.Descriptor( name='BackendConfig', full_name='pbnetwork.BackendConfig', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='config', full_name='pbnetwork.BackendConfig.config', index=0, number=1, type=9, cpp_type=9, label=2, - has_default_value=False, default_value=unicode("", "utf-8"), + has_default_value=False, default_value=_b("").decode('utf-8'), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -1099,29 +1142,31 @@ _BACKENDCONFIG = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1271, serialized_end=1302, ) -_WRAPPERMESSAGE = descriptor.Descriptor( +_WRAPPERMESSAGE = _descriptor.Descriptor( name='WrapperMessage', full_name='pbnetwork.WrapperMessage', filename=None, file=DESCRIPTOR, containing_type=None, fields=[ - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='type', full_name='pbnetwork.WrapperMessage.type', index=0, number=1, type=14, cpp_type=8, label=2, has_default_value=False, default_value=1, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), - descriptor.FieldDescriptor( + _descriptor.FieldDescriptor( name='payload', full_name='pbnetwork.WrapperMessage.payload', index=1, number=2, type=12, cpp_type=9, label=1, - has_default_value=False, default_value="", + has_default_value=False, default_value=_b(""), message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, options=None), @@ -1135,111 +1180,148 @@ _WRAPPERMESSAGE = descriptor.Descriptor( options=None, is_extendable=False, extension_ranges=[], + oneofs=[ + ], serialized_start=1305, serialized_end=2099, ) - _BUDDY.fields_by_name['status'].enum_type = _STATUSTYPE _PARTICIPANT.fields_by_name['status'].enum_type = _STATUSTYPE _STATUS.fields_by_name['status'].enum_type = _STATUSTYPE _WRAPPERMESSAGE.fields_by_name['type'].enum_type = _WRAPPERMESSAGE_TYPE -_WRAPPERMESSAGE_TYPE.containing_type = _WRAPPERMESSAGE; +_WRAPPERMESSAGE_TYPE.containing_type = _WRAPPERMESSAGE +DESCRIPTOR.message_types_by_name['Connected'] = _CONNECTED +DESCRIPTOR.message_types_by_name['Disconnected'] = _DISCONNECTED +DESCRIPTOR.message_types_by_name['Login'] = _LOGIN +DESCRIPTOR.message_types_by_name['Logout'] = _LOGOUT +DESCRIPTOR.message_types_by_name['Buddy'] = _BUDDY +DESCRIPTOR.message_types_by_name['ConversationMessage'] = _CONVERSATIONMESSAGE +DESCRIPTOR.message_types_by_name['Room'] = _ROOM +DESCRIPTOR.message_types_by_name['RoomList'] = _ROOMLIST +DESCRIPTOR.message_types_by_name['Participant'] = _PARTICIPANT +DESCRIPTOR.message_types_by_name['VCard'] = _VCARD +DESCRIPTOR.message_types_by_name['Status'] = _STATUS +DESCRIPTOR.message_types_by_name['Stats'] = _STATS +DESCRIPTOR.message_types_by_name['File'] = _FILE +DESCRIPTOR.message_types_by_name['FileTransferData'] = _FILETRANSFERDATA +DESCRIPTOR.message_types_by_name['BackendConfig'] = _BACKENDCONFIG +DESCRIPTOR.message_types_by_name['WrapperMessage'] = _WRAPPERMESSAGE +DESCRIPTOR.enum_types_by_name['ConnectionError'] = _CONNECTIONERROR +DESCRIPTOR.enum_types_by_name['StatusType'] = _STATUSTYPE +DESCRIPTOR.enum_types_by_name['ParticipantFlag'] = _PARTICIPANTFLAG -class Connected(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CONNECTED - +Connected = _reflection.GeneratedProtocolMessageType('Connected', (_message.Message,), dict( + DESCRIPTOR = _CONNECTED, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Connected) + )) +_sym_db.RegisterMessage(Connected) -class Disconnected(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _DISCONNECTED - +Disconnected = _reflection.GeneratedProtocolMessageType('Disconnected', (_message.Message,), dict( + DESCRIPTOR = _DISCONNECTED, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Disconnected) + )) +_sym_db.RegisterMessage(Disconnected) -class Login(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _LOGIN - +Login = _reflection.GeneratedProtocolMessageType('Login', (_message.Message,), dict( + DESCRIPTOR = _LOGIN, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Login) + )) +_sym_db.RegisterMessage(Login) -class Logout(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _LOGOUT - +Logout = _reflection.GeneratedProtocolMessageType('Logout', (_message.Message,), dict( + DESCRIPTOR = _LOGOUT, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Logout) + )) +_sym_db.RegisterMessage(Logout) -class Buddy(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _BUDDY - +Buddy = _reflection.GeneratedProtocolMessageType('Buddy', (_message.Message,), dict( + DESCRIPTOR = _BUDDY, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Buddy) + )) +_sym_db.RegisterMessage(Buddy) -class ConversationMessage(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _CONVERSATIONMESSAGE - +ConversationMessage = _reflection.GeneratedProtocolMessageType('ConversationMessage', (_message.Message,), dict( + DESCRIPTOR = _CONVERSATIONMESSAGE, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.ConversationMessage) + )) +_sym_db.RegisterMessage(ConversationMessage) -class Room(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _ROOM - +Room = _reflection.GeneratedProtocolMessageType('Room', (_message.Message,), dict( + DESCRIPTOR = _ROOM, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Room) + )) +_sym_db.RegisterMessage(Room) -class RoomList(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _ROOMLIST - +RoomList = _reflection.GeneratedProtocolMessageType('RoomList', (_message.Message,), dict( + DESCRIPTOR = _ROOMLIST, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.RoomList) + )) +_sym_db.RegisterMessage(RoomList) -class Participant(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _PARTICIPANT - +Participant = _reflection.GeneratedProtocolMessageType('Participant', (_message.Message,), dict( + DESCRIPTOR = _PARTICIPANT, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Participant) + )) +_sym_db.RegisterMessage(Participant) -class VCard(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _VCARD - +VCard = _reflection.GeneratedProtocolMessageType('VCard', (_message.Message,), dict( + DESCRIPTOR = _VCARD, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.VCard) + )) +_sym_db.RegisterMessage(VCard) -class Status(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _STATUS - +Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), dict( + DESCRIPTOR = _STATUS, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Status) + )) +_sym_db.RegisterMessage(Status) -class Stats(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _STATS - +Stats = _reflection.GeneratedProtocolMessageType('Stats', (_message.Message,), dict( + DESCRIPTOR = _STATS, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.Stats) + )) +_sym_db.RegisterMessage(Stats) -class File(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _FILE - +File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), dict( + DESCRIPTOR = _FILE, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.File) + )) +_sym_db.RegisterMessage(File) -class FileTransferData(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _FILETRANSFERDATA - +FileTransferData = _reflection.GeneratedProtocolMessageType('FileTransferData', (_message.Message,), dict( + DESCRIPTOR = _FILETRANSFERDATA, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.FileTransferData) + )) +_sym_db.RegisterMessage(FileTransferData) -class BackendConfig(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _BACKENDCONFIG - +BackendConfig = _reflection.GeneratedProtocolMessageType('BackendConfig', (_message.Message,), dict( + DESCRIPTOR = _BACKENDCONFIG, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.BackendConfig) + )) +_sym_db.RegisterMessage(BackendConfig) -class WrapperMessage(message.Message): - __metaclass__ = reflection.GeneratedProtocolMessageType - DESCRIPTOR = _WRAPPERMESSAGE - +WrapperMessage = _reflection.GeneratedProtocolMessageType('WrapperMessage', (_message.Message,), dict( + DESCRIPTOR = _WRAPPERMESSAGE, + __module__ = 'protocol_pb2' # @@protoc_insertion_point(class_scope:pbnetwork.WrapperMessage) + )) +_sym_db.RegisterMessage(WrapperMessage) + # @@protoc_insertion_point(module_scope) From ecfa2d7f858a900463aaefae973eb55ba991aadb Mon Sep 17 00:00:00 2001 From: moyamo Date: Tue, 15 Sep 2015 21:29:26 +0200 Subject: [PATCH 05/10] Attempt to fix groupchats --- Spectrum2/backend.py | 3 +- session.py | 266 ++++++++++++++++++++++++++----------------- yowsupwrapper.py | 48 +++++++- 3 files changed, 211 insertions(+), 106 deletions(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index a59567a..2ecc968 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -27,7 +27,7 @@ class SpectrumBackend: self.m_init_res = 0 self.logger = logging.getLogger(self.__class__.__name__) - def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = ""): + def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = "", pm = True): m = protocol_pb2.ConversationMessage() m.userName = user m.buddyName = legacyName @@ -35,6 +35,7 @@ class SpectrumBackend: m.nickname = nickname m.xhtml = xhtml m.timestamp = str(timestamp) + m.pm = pm message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE) self.send(message) diff --git a/session.py b/session.py index b86fa97..b59544a 100644 --- a/session.py +++ b/session.py @@ -47,8 +47,6 @@ class Session(YowsupApp): self.backend = backend self.user = user self.legacyName = legacyName - self.buddies = BuddyList(self.legacyName, self.db) - self.bot = Bot(self) self.status = protocol_pb2.STATUS_NONE self.statusMessage = '' @@ -56,36 +54,36 @@ class Session(YowsupApp): self.groups = {} self.presenceRequested = [] self.offlineQueue = [] + self.msgIDs = { } self.groupOfflineQueue = { } + self.shouldBeConnected = False self.timer = None self.password = None self.initialized = False - self.loggedin = False + self.synced = False + self.buddies = BuddyList(self.legacyName, self.db) self.bot = Bot(self) def __del__(self): # handleLogoutRequest self.logout() - def call(self, method, **kwargs): - self.logger.debug("%s(%s)", method, - ", ".join(str(k) + ': ' + str(v) for k, v in kwargs.items())) - ##self.stack.broadcastEvent(YowLayerEvent(method, **kwargs)) - def logout(self): - self.loggedin = False + self.logger.info("%s logged out", self.user) super(Session, self).logout() def login(self, password): - self.loggedin = True + self.logger.info("%s attempting login", self.user) self.password = password + self.shouldBeConncted = True super(Session, self).login(self.legacyName, self.password) def updateRoomList(self): rooms = [] for room, group in self.groups.iteritems(): rooms.append([room, group.subject]) + self.logger.debug("Got rooms: %s", rooms) self.backend.handleRoomList(rooms) @@ -95,6 +93,11 @@ class Session(YowsupApp): old = self.buddies.keys() self.buddies.load() new = self.buddies.keys() + contacts = new + + if self.synced == False: + self.sendSync(contacts, delta = False, interactive = True) + self.synced = True add = set(new) - set(old) remove = set(old) - set(new) @@ -103,27 +106,28 @@ class Session(YowsupApp): self.logger.debug("Roster add: %s", str(list(add))) 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.unsubscribePresence(number) for number in add: buddy = self.buddies[number] self.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.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.requestLastSeen(number, self._lastSeen) - self.logger.debug('Requesting groups list') - self.requestGroupsList(self._updateGroups) - + def _updateGroups(self, response, request): self.logger.debug('Received groups list %s', response) - # This XMPP client is not receiving this for some reason. groups = response.getGroups() for group in groups: room = group.getId() - owner = group.getOwner() - subjectOwner = group.getSubjectOwner() - subject = group.getSubject() + owner = group.getOwner().split('@')[0] + subjectOwner = group.getSubjectOwner().split('@')[0] + subject = utils.softToUni(group.getSubject()) if room in self.groups: oroom = self.groups[room] @@ -132,22 +136,61 @@ class Session(YowsupApp): oroom.subject = subject else: self.groups[room] = Group(room, owner, subject, subjectOwner) - # A crude implemtation of groups that act like buddies + self.joinRoom(room, self.user.split("@")[0]) - self.backend.handleBuddyChanged(self.user, room, subject, [], protocol_pb2.STATUS_NONE) - # This XMPP client is not receiving this for some reason. -# self.updateRoomList() -# for group in groups: -# room = group.getId() -# subjectOwner = group.getSubjectOwner() -# subject = group.getSubject() -# self.backend.handleSubject(self.user, room, subject, subjectOwner) -# for participant in group.getParticipants(): -# buddy = participant.split('@')[0] -# self.logger.debug("Added %s to room %s", buddy, room) -# self.backend.handleParticipantChanged(self.user, buddy, room, -# protocol_pb2.PARTICIPANT_FLAG_NONE, protocol_pb2.STATUS_ONLINE) + 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.updateRoomList() + + def joinRoom(self, room, nick): + if room in self.groups: + self.logger.info("Joining room: %s room=%s, nick=%s", + self.legacyName, room, nick) + + group = self.groups[room] + group.nick = nick + try: + ownerNick = self.buddies[group.subjectOwner].nick + except KeyError: + ownerNick = group.subjectOwner + + self.backend.handleSubject(self.user, room, group.subject, + ownerNick) + self.backend.handleRoomNicknameChanged(self.user, room, + group.subject) + else: + self.logger.warn("Room doesn't exist: %s", room) + + def _addParticipantsToRoom(self, room, participants): + group = self.groups[room] + + for jid, _type in participants.iteritems(): + buddy = jid.split("@")[0] + buddyFull = buddy + self.logger.info("Added %s to room %s", buddy, room) + try: + nick = self.buddies[buddy].nick + except KeyError: + nick = buddy + buddyFull = buddy + if _type == 'admin': + flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR + else: + flags = protocol_pb2.PARTICIPANT_FLAG_NONE + if buddy == self.legacyName: + nick = group.nick + flags = protocol_pb2.PARTICIPANT_FLAG_ME + buddyFull = self.user + + self.backend.handleParticipantChanged(self.user, buddyFull, + room, flags, protocol_pb2.STATUS_ONLINE, buddy, nick) def _lastSeen(self, number, seconds): @@ -163,23 +206,29 @@ class Session(YowsupApp): self.logger.info("Auth success: %s", self.user) self.backend.handleConnected(self.user) - self.backend.handleBuddyChanged(self.user, "bot", self.bot.name, ["Admin"], protocol_pb2.STATUS_ONLINE) - self.initialized = True + self.backend.handleBuddyChanged(self.user, "bot", self.bot.name, + ["Admin"], protocol_pb2.STATUS_ONLINE) + if self.initialized == False: + self.sendOfflineMessages() + self.bot.call("welcome") + self.initialized = True self.sendPresence(True) - self.updateRoster() + self.logger.debug('Requesting groups list') + self.requestGroupsList(self._updateGroups) + # Called by superclass def onAuthFailed(self, reason): self.logger.info("Auth failed: %s (%s)", self.user, reason) self.backend.handleDisconnected(self.user, 0, reason) self.password = None + self.shouldBeConnected = False # Called by superclass def onDisconnect(self): self.logger.debug('Disconnected') self.backend.handleDisconnected(self.user, 0, 'Disconnected for unknown reasons') - self.loggedin = False # Called by superclass def onReceipt(self, _id, _from, timestamp, type, participant, offline, items): @@ -198,8 +247,9 @@ class Session(YowsupApp): ) # Called by superclass - def onTextMessage(self, _id, _from, to, notify, timestamp, participant, offline, retry, body): - self.logger.debug('received TextMessage' + + def onTextMessage(self, _id, _from, to, notify, timestamp, participant, + offline, retry, body): + self.logger.debug('received TextMessage' + ' '.join(map(str, [ _id, _from, to, notify, timestamp, participant, offline, retry, body @@ -210,10 +260,10 @@ class Session(YowsupApp): self.sendReceipt(_id, _from, None, participant) self.logger.info("Message received from %s to %s: %s (at ts=%s)", buddy, self.legacyName, messageContent, timestamp) - if participant is not None: + if participant is not None: # Group message partname = participant.split('@')[0] - message = partname + ': ' + messageContent - self.sendMessageToXMPP(buddy, message, timestamp) + self.sendGroupMessageToXMPP(buddy, partname, messageContent, + timestamp) else: self.sendMessageToXMPP(buddy, messageContent, timestamp) # isBroadcast always returns false, I'm not sure how to get a broadcast @@ -229,7 +279,7 @@ class Session(YowsupApp): buddy = image._from.split('@')[0] message = image.url + ' ' + image.caption self.sendMessageToXMPP(buddy, message, image.timestamp) - self.sendReceipt(image._id, image._from, None, image.participant) + self.sendReceipt(image._id, image._from, None, image.participant) # Called by superclass def onAudio(self, audio): @@ -237,7 +287,7 @@ class Session(YowsupApp): buddy = audio._from.split('@')[0] message = audio.url self.sendMessageToXMPP(buddy, message, audio.timestamp) - self.sendReceipt(audio._id, audio._from, None, audio.participant) + self.sendReceipt(audio._id, audio._from, None, audio.participant) # Called by superclass def onVideo(self, video): @@ -245,21 +295,35 @@ class Session(YowsupApp): buddy = video._from.split('@')[0] message = video.url self.sendMessageToXMPP(buddy, message, video.timestamp) - self.sendReceipt(video._id, video._from, None, video.participant) + self.sendReceipt(video._id, video._from, None, video.participant) + + def onLocation(self, location): + buddy = location._from.split('@')[0] + latitude = location.getLatitude() + longitude = location.getLongitude() + url = location.getLocationUrl() + + self.logger.debug("Location received from %s: %s, %s", + buddy, latitude, longitude) + + self.sendMessageToXMPP(buddy, url, location.timestamp) + self.sendMessageToXMPP(buddy, 'geo:' + latitude + ',' + longitude, + location.timestamp) + # Called by superclass def onVCard(self, _id, _from, name, card_data, to, notify, timestamp, participant): - self.logger.debug('received VCard' + + self.logger.debug('received VCard' + ' '.join(map(str, [ _id, _from, name, card_data, to, notify, timestamp, participant ])) ) buddy = _from.split("@")[0] self.sendMessageToXMPP(buddy, "Received VCard (not implemented yet)") - self.sendMessageToXMPP(buddy, card_data) +# self.sendMessageToXMPP(buddy, card_data) self.transferFile(buddy, str(name), card_data) self.sendReceipt(_id, _from, None, participant) - + def transferFile(self, buddy, name, data): # Not working self.logger.debug('transfering file %s', name) @@ -270,17 +334,21 @@ class Session(YowsupApp): # Called by superclass def onContactTyping(self, buddy): self.logger.info("Started typing: %s", buddy) - self.sendPresence(True) - self.backend.handleBuddyTyping(self.user, buddy) + if buddy != 'bot': + self.sendPresence(True) + self.backend.handleBuddyTyping(self.user, buddy) - if self.timer != None: - self.timer.cancel() + if self.timer != None: + self.timer.cancel() # Called by superclass def onContactPaused(self, buddy): self.logger.info("Paused typing: %s", buddy) - self.backend.handleBuddyTyped(self.user, buddy) - self.timer = Timer(3, self.backend.handleBuddyStoppedTyping, (self.user, buddy)).start() + if buddy != 'bot': + self.backend.handleBuddyTyped(self.user, buddy) + self.timer = Timer(3, self.backend.handleBuddyStoppedTyping, + (self.user, buddy)).start() + def onPresenceReceived(self, _type, name, jid, lastseen): self.logger.info("Presence received: %s %s %s %s", _type, name, jid, lastseen) buddy = jid.split("@")[0] @@ -302,7 +370,8 @@ class Session(YowsupApp): try: buddy = self.buddies[buddy] self.logger.info("Is available: %s", buddy) - self.backend.handleBuddyChanged(self.user, buddy.number.number, buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE) + self.backend.handleBuddyChanged(self.user, buddy.number.number, + buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE) except KeyError: self.logger.error("Buddy not found: %s", buddy) @@ -310,7 +379,8 @@ class Session(YowsupApp): try: buddy = self.buddies[buddy] self.logger.info("Is unavailable: %s", buddy) - self.backend.handleBuddyChanged(self.user, buddy.number.number, buddy.nick, buddy.groups, protocol_pb2.STATUS_XA) + self.backend.handleBuddyChanged(self.user, buddy.number.number, + buddy.nick, buddy.groups, protocol_pb2.STATUS_XA) except KeyError: self.logger.error("Buddy not found: %s", buddy) @@ -330,20 +400,33 @@ class Session(YowsupApp): self.sendTyping(buddy, False) def sendMessageToWA(self, sender, message): - self.logger.info("Message sent from %s to %s: %s", self.legacyName, sender, message) + self.logger.info("Message sent from %s to %s: %s", + self.legacyName, sender, message) + message = message.encode("utf-8") if sender == "bot": self.bot.parse(message) elif "-" in sender: # group msg - if "/" in sender: - room, buddy = sender.split("/") - self.sendTextMessage(buddy + '@s.whatsapp.net', message) + if "/" in sender: # directed at single user + room, nick = sender.split("/") + for buddy, buddy3 in self.buddies.iteritems(): + self.logger.info("Group buddy=%s nick=%s", buddy, + buddy3.nick) + if buddy3.nick == nick: + nick = buddy + self.sendTextMessage(nick + '@s.whatsapp.net', message) else: room = sender -# group = self.groups[room] - -# self.backend.handleMessage(self.user, room, message, group.nick) + try: + group = self.groups[room] + self.logger.info("Group Message from %s to %s Groups: %s", + group.nick , group , self.groups) + self.backend.handleMessage( + self.user, room, message.decode('utf-8'), group.nick + ) + except KeyError: + self.logger.error('Group not found: %s', room) self.sendTextMessage(room + '@g.us', message) else: # private msg @@ -368,26 +451,37 @@ class Session(YowsupApp): "", timestamp) def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""): + try: + nick = self.buddies[buddy].nick + except KeyError: + nick = buddy + if timestamp: timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp)) if self.initialized == False: - self.logger.debug("Group message queued from %s to %s: %s", buddy, room, messageContent) + self.logger.debug("Group message queued from %s to %s: %s", + buddy, room, messageContent) if room not in self.groupOfflineQueue: self.groupOfflineQueue[room] = [ ] - self.groupOfflineQueue[room].append((buddy, messageContent, timestamp)) + self.groupOfflineQueue[room].append( + (buddy, messageContent, timestamp) + ) else: - self.logger.debug("Group message sent from %s to %s: %s", buddy, room, messageContent) - self.backend.handleMessage(self.user, room, messageContent, buddy, "", timestamp) + self.logger.debug("Group message sent from %s to %s: %s", buddy, + room, messageContent) + self.backend.handleMessage(self.user, room, messageContent, nick, + "", timestamp, False) def changeStatus(self, status): if status != self.status: self.logger.info("Status changed: %s", 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.sendPresence(True) else: self.sendPresence(False) @@ -421,21 +515,8 @@ class Session(YowsupApp): self.buddies.remove(buddy) self.updateRoster() - def joinRoom(self, room, nick): - if room in self.groups: - group = self.groups[room] - self.logger.info("Joining room: %s room=%s, nick=%s", self.legacyName, room, nick) - - group.nick = nick - - self.call("group_getParticipants", (room + "@g.us",)) - self.backend.handleSubject(self.user, room, group.subject, group.subjectOwner) - else: - self.logger.warn("Room doesn't exist: %s", room) - def requestVCard(self, buddy, ID): - def onSuccess(response, request): self.logger.debug('Sending VCard (%s) with image id %s', ID, response.pictureId) @@ -458,32 +539,11 @@ class Session(YowsupApp): if receiptRequested: self.call("message_ack", (jid, messageId)) - def onGroupGotParticipants(self, gjid, jids): - room = gjid.split("@")[0] - group = self.groups[room] - - for jid in jids: - buddy = jid.split("@")[0] - self.logger.info("Added %s to room %s", buddy, room) - - if buddy == group.owner: - flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR - else: - flags = protocol_pb2.PARTICIPANT_FLAG_NONE - - self.backend.handleParticipantChanged(self.user, buddy, room, flags, protocol_pb2.STATUS_ONLINE) # TODO check status - - 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]) - def onGroupMessageReceived(self, messageId, gjid, jid, messageContent, timestamp, receiptRequested, pushName): buddy = jid.split("@")[0] room = gjid.split("@")[0] - self.logger.info("Group message received in %s from %s: %s", room, buddy, messageContent) + self.logger.info("Group message received in %s from %s: %s", room, buddy, messageContent) self.sendGroupMessageToXMPP(room, buddy, utils.softToUni(messageContent), timestamp) if receiptRequested: self.call("message_ack", (gjid, messageId)) diff --git a/yowsupwrapper.py b/yowsupwrapper.py index 8058b10..2a8349b 100644 --- a/yowsupwrapper.py +++ b/yowsupwrapper.py @@ -30,6 +30,7 @@ from yowsup.layers.protocol_calls import YowCallsProtocolLayer from yowsup.layers.protocol_acks.protocolentities import * from yowsup.layers.protocol_chatstate.protocolentities import * +from yowsup.layers.protocol_contacts.protocolentities import * from yowsup.layers.protocol_groups.protocolentities import * from yowsup.layers.protocol_media.protocolentities import * from yowsup.layers.protocol_messages.protocolentities import * @@ -197,6 +198,26 @@ class YowsupApp(object): ) self.sendEntity(state) + def sendSync(self, contacts, delta = False, interactive = True): + """ + You need to sync new contacts before you interact with + them, failure to do so could result in a temporary ban. + + Args: + - contacts: ([str]) a list of phone numbers of the + contacts you wish to sync + - delta: (bool; default: False) If true only send new + contacts to sync, if false you should send your full + contact list. + - interactive: (bool; default: True) Set to false if you are + sure this is the first time registering + """ + # TODO: Implement callbacks + mode = GetSyncIqProtocolEntity.MODE_DELTA if delta else GetSyncIqProtocolEntity.MODE_FULL + context = GetSyncIqProtocolEntity.CONTEXT_INTERACTIVE if interactive else GetSyncIqProtocolEntity.CONTEXT_REGISTRATION + iq = GetSyncIqProtocolEntity(contacts, mode, context) + self.sendIq(iq) + def requestLastSeen(self, phoneNumber, success = None, failure = None): """ Requests when user was last seen. @@ -219,8 +240,8 @@ class YowsupApp(object): Requests profile picture of whatsapp user Args: - phoneNumber: (str) the phone number of the user - - success: (func) called when request is successfully processed. - - failure: (func) called when request has failed + - onSuccess: (func) called when request is successfully processed. + - onFailure: (func) called when request has failed """ iq = GetPictureIqProtocolEntity(phoneNumber + '@s.whatsapp.net') self.sendIq(iq, onSuccess = onSuccess, onError = onFailure) @@ -229,6 +250,18 @@ class YowsupApp(object): iq = ListGroupsIqProtocolEntity() self.sendIq(iq, onSuccess = onSuccess, onError = onFailure) + def requestGroupInfo(self, group, onSuccess = None, onFailure = None): + """ + Request info on a specific group (includes participants, subject, owner etc.) + + Args: + - group: (str) the group id in the form of xxxxxxxxx-xxxxxxxx + - onSuccess: (func) called when request is successfully processed. + - onFailure: (func) called when request is has failed + """ + iq = InfoGroupsIqProtocolEntity(group + '@g.us') + self.sendIq(iq, onSuccess = onSuccess, onError = onFailure) + def onAuthSuccess(self, status, kind, creation, expiration, props, nonce, t): """ Called when login is successful. @@ -361,6 +394,15 @@ class YowsupApp(object): - entity: VideoDownloadableMediaMessageProtocolEntity """ pass + + def onLocation(self, entity): + """ + Called when location message is received + + Args: + - entity: LocationMediaMessageProtocolEntity + """ + pass def onVCard(self, _id, _from, name, card_data, to, notify, timestamp, participant): """ @@ -508,6 +550,8 @@ class YowsupAppLayer(YowInterfaceLayer): entity.timestamp, entity.participant ) + elif isinstance(entity, LocationMediaMessageProtocolEntity): + self.caller.onLocation(entity) @ProtocolEntityCallback('presence') def onPresenceReceived(self, presence): From 29d92b456ed270c5eb80606e7cabba3d3526f57c Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 21 Sep 2015 20:30:11 +0200 Subject: [PATCH 06/10] Shorten the name of groupchats to overcome truncation bug The names of groupchats are truncated internally to 22 characters. This causes many problems with groupchats, since spectrum incorrectly identifies the chat by the long name. To overcome this the phoneNumber-unixTime is converted to hexadecimal, to shorten the groupchat below 22 characters --- Spectrum2/backend.py | 3 +- buddy.py | 4 +-- session.py | 77 +++++++++++++++++++++++++++++++------------- whatsappbackend.py | 2 ++ 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index 2ecc968..a59567a 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -27,7 +27,7 @@ class SpectrumBackend: self.m_init_res = 0 self.logger = logging.getLogger(self.__class__.__name__) - def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = "", pm = True): + def handleMessage(self, user, legacyName, msg, nickname = "", xhtml = "", timestamp = ""): m = protocol_pb2.ConversationMessage() m.userName = user m.buddyName = legacyName @@ -35,7 +35,6 @@ class SpectrumBackend: m.nickname = nickname m.xhtml = xhtml m.timestamp = str(timestamp) - m.pm = pm message = WRAP(m.SerializeToString(), protocol_pb2.WrapperMessage.TYPE_CONV_MESSAGE) self.send(message) diff --git a/buddy.py b/buddy.py index 1ab9944..e07ec46 100644 --- a/buddy.py +++ b/buddy.py @@ -23,7 +23,6 @@ __status__ = "Prototype" """ from Spectrum2 import protocol_pb2 -from Yowsup.Contacts.contacts import WAContactsSyncRequest import logging @@ -61,7 +60,8 @@ class Buddy(): def update(self, nick, groups, image_hash): self.nick = nick self.groups = groups - self.image_hash = image_hash + if image_hash is not None: + self.image_hash = image_hash groups = u",".join(groups).encode("latin-1") cur = self.db.cursor() diff --git a/session.py b/session.py index b59544a..d65361f 100644 --- a/session.py +++ b/session.py @@ -79,10 +79,18 @@ class Session(YowsupApp): self.shouldBeConncted = True super(Session, self).login(self.legacyName, self.password) + def _shortenGroupId(self, gid): + # FIXME: will have problems if number begins with 0 + return '-'.join(hex(int(s))[2:] for s in gid.split('-')) + + def _lengthenGroupId(self, gid): + # FIXME: will have problems if number begins with 0 + return '-'.join(str(int(s, 16)) for s in gid.split('-')) + def updateRoomList(self): rooms = [] for room, group in self.groups.iteritems(): - rooms.append([room, group.subject]) + rooms.append([self._shortenGroupId(room), group.subject]) self.logger.debug("Got rooms: %s", rooms) self.backend.handleRoomList(rooms) @@ -136,7 +144,7 @@ class Session(YowsupApp): oroom.subject = subject else: self.groups[room] = Group(room, owner, subject, subjectOwner) - self.joinRoom(room, self.user.split("@")[0]) + self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0]) self._addParticipantsToRoom(room, group.getParticipants()) @@ -150,6 +158,7 @@ class Session(YowsupApp): self.updateRoomList() def joinRoom(self, room, nick): + room = self._lengthenGroupId(room) if room in self.groups: self.logger.info("Joining room: %s room=%s, nick=%s", self.legacyName, room, nick) @@ -165,11 +174,38 @@ class Session(YowsupApp): ownerNick) self.backend.handleRoomNicknameChanged(self.user, room, group.subject) + self._refreshParticipants(room) else: self.logger.warn("Room doesn't exist: %s", room) + def _refreshParticipants(self, room): + group = self.groups[room] + for jid in group.participants: + buddy = jid.split("@")[0] + self.logger.info("Added %s to room %s", buddy, room) + try: + nick = self.buddies[buddy].nick + except KeyError: + nick = buddy + if nick == "": + nick = buddy + + buddyFull = buddy + if buddy == group.owner: + flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR + else: + flags = protocol_pb2.PARTICIPANT_FLAG_NONE + if buddy == self.legacyName: + nick = group.nick + flags = flags | protocol_pb2.PARTICIPANT_FLAG_ME + buddyFull = self.user + self.backend.handleParticipantChanged( + self.user, buddyFull, self._shortenGroupId(room), flags, + protocol_pb2.STATUS_ONLINE, buddy, nick) + def _addParticipantsToRoom(self, room, participants): group = self.groups[room] + group.participants = participants for jid, _type in participants.iteritems(): buddy = jid.split("@")[0] @@ -190,7 +226,7 @@ class Session(YowsupApp): buddyFull = self.user self.backend.handleParticipantChanged(self.user, buddyFull, - room, flags, protocol_pb2.STATUS_ONLINE, buddy, nick) + self._shortenGroupId(room), flags, protocol_pb2.STATUS_ONLINE, buddy, nick) def _lastSeen(self, number, seconds): @@ -224,7 +260,7 @@ class Session(YowsupApp): self.backend.handleDisconnected(self.user, 0, reason) self.password = None self.shouldBeConnected = False - + # Called by superclass def onDisconnect(self): self.logger.debug('Disconnected') @@ -236,9 +272,12 @@ class Session(YowsupApp): ' '.join(map(str, [_id, _from, timestamp, type, participant, offline, items])) ) - buddy = self.buddies[_from.split('@')[0]] - self.backend.handleBuddyChanged(self.user, buddy.number.number, - buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE) + try: + buddy = self.buddies[_from.split('@')[0]] + self.backend.handleBuddyChanged(self.user, buddy.number.number, + buddy.nick, buddy.groups, protocol_pb2.STATUS_ONLINE) + except KeyError: + pass # Called by superclass def onAck(self, _id, _class, _from, timestamp): @@ -427,7 +466,7 @@ class Session(YowsupApp): ) except KeyError: self.logger.error('Group not found: %s', room) - self.sendTextMessage(room + '@g.us', message) + self.sendTextMessage(self._lengthenGroupId(room) + '@g.us', message) else: # private msg buddy = sender @@ -451,10 +490,13 @@ class Session(YowsupApp): "", timestamp) def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""): + self._refreshParticipants(room) try: nick = self.buddies[buddy].nick except KeyError: nick = buddy + if nick == "": + nick = buddy if timestamp: timestamp = time.strftime("%Y%m%dT%H%M%S", time.gmtime(timestamp)) @@ -470,10 +512,10 @@ class Session(YowsupApp): (buddy, messageContent, timestamp) ) else: - self.logger.debug("Group message sent from %s to %s: %s", buddy, - room, messageContent) - self.backend.handleMessage(self.user, room, messageContent, nick, - "", timestamp, False) + self.logger.debug("Group message sent from %s (%s) to %s: %s", + buddy, nick, room, messageContent) + self.backend.handleMessage(self.user, self._shortenGroupId(room), + messageContent, nick, "", timestamp) def changeStatus(self, status): if status != self.status: @@ -504,7 +546,7 @@ class Session(YowsupApp): self.backend.handleMessage(self.user, msg[0], msg[1], "", "", msg[2]) # also for adding a new buddy - def updateBuddy(self, buddy, nick, groups, image_hash =""): + def updateBuddy(self, buddy, nick, groups, image_hash = None): if buddy != "bot": self.buddies.update(buddy, nick, groups, image_hash) self.updateRoster() @@ -539,15 +581,6 @@ class Session(YowsupApp): if receiptRequested: self.call("message_ack", (jid, messageId)) - def onGroupMessageReceived(self, messageId, gjid, jid, messageContent, timestamp, receiptRequested, pushName): - buddy = jid.split("@")[0] - room = gjid.split("@")[0] - - self.logger.info("Group message received in %s from %s: %s", room, buddy, messageContent) - - self.sendGroupMessageToXMPP(room, buddy, utils.softToUni(messageContent), timestamp) - if receiptRequested: self.call("message_ack", (gjid, messageId)) - def onGroupSubjectReceived(self, messageId, gjid, jid, subject, timestamp, receiptRequested): room = gjid.split("@")[0] buddy = jid.split("@")[0] diff --git a/whatsappbackend.py b/whatsappbackend.py index b7b9827..b973f76 100644 --- a/whatsappbackend.py +++ b/whatsappbackend.py @@ -67,6 +67,7 @@ class WhatsAppBackend(SpectrumBackend): # # TODO Proper fix, this work around drops all duplicate messages even # intentional ones. + # IDEA there is an ID field in ConvMessage. If it is extracted it will work usersMessage = self.lastMessage[user] if buddy not in usersMessage or usersMessage[buddy] != message: self.sessions[user].sendMessageToWA(buddy, message) @@ -105,6 +106,7 @@ class WhatsAppBackend(SpectrumBackend): self.logger.debug("handleVCardRequest(user=%s, buddy=%s, ID=%s)", user, buddy, ID) self.sessions[user].requestVCard(buddy, ID) + # TODO def handleBuddyBlockToggled(self, user, buddy, blocked): pass From a5877bc1a9e698cad6a96c078a565e1bb8201078 Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 21 Sep 2015 21:45:18 +0200 Subject: [PATCH 07/10] Try to prevent transwhat from crashing on malformed protobuf --- Spectrum2/backend.py | 1 - session.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index a59567a..a4bdd50 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -4,7 +4,6 @@ import struct import sys import os import logging - import google.protobuf def WRAP(MESSAGE, TYPE): diff --git a/session.py b/session.py index d65361f..bdd9144 100644 --- a/session.py +++ b/session.py @@ -458,7 +458,7 @@ class Session(YowsupApp): else: room = sender try: - group = self.groups[room] + group = self.groups[self._lengthenGroupId(room)] self.logger.info("Group Message from %s to %s Groups: %s", group.nick , group , self.groups) self.backend.handleMessage( From 744efd154ff80131ba3d5a80c17f362e9dc5398e Mon Sep 17 00:00:00 2001 From: moyamo Date: Tue, 22 Sep 2015 16:14:25 +0200 Subject: [PATCH 08/10] Use notify as buddies nickname when sending groupchats. --- session.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/session.py b/session.py index bdd9144..7193be3 100644 --- a/session.py +++ b/session.py @@ -54,7 +54,6 @@ class Session(YowsupApp): self.groups = {} self.presenceRequested = [] self.offlineQueue = [] - self.msgIDs = { } self.groupOfflineQueue = { } self.shouldBeConnected = False @@ -170,10 +169,12 @@ class Session(YowsupApp): except KeyError: ownerNick = group.subjectOwner - self.backend.handleSubject(self.user, room, group.subject, + self.backend.handleSubject(self.user, self._shortenGroupId(room), + group.subject, ownerNick) - self.backend.handleRoomNicknameChanged(self.user, room, - group.subject) + self.backend.handleRoomNicknameChanged( + self.user, self._shortenGroupId(room), group.subject + ) self._refreshParticipants(room) else: self.logger.warn("Room doesn't exist: %s", room) @@ -225,8 +226,10 @@ class Session(YowsupApp): flags = protocol_pb2.PARTICIPANT_FLAG_ME buddyFull = self.user - self.backend.handleParticipantChanged(self.user, buddyFull, - self._shortenGroupId(room), flags, protocol_pb2.STATUS_ONLINE, buddy, nick) + self.backend.handleParticipantChanged( + self.user, buddyFull, self._shortenGroupId(room), flags, + protocol_pb2.STATUS_ONLINE, buddy, nick + ) def _lastSeen(self, number, seconds): @@ -296,11 +299,22 @@ class Session(YowsupApp): ) buddy = _from.split('@')[0] messageContent = utils.softToUni(body) - self.sendReceipt(_id, _from, None, participant) + self.sendReceipt(_id, _from, None, participant) self.logger.info("Message received from %s to %s: %s (at ts=%s)", buddy, self.legacyName, messageContent, timestamp) if participant is not None: # Group message partname = participant.split('@')[0] + try: + part = self.buddies[partname] + if part.nick == "": + part.nick = notify + self.backend.handleParticipantChanged( + self.user, partname, buddy, + protocol_pb2.PARTICIPANT_FLAG_NONE, + protocol_pb2.STATUS_NONE, "", part.nick + ) # TODO + except KeyError: + self.updateBuddy(partname, notify, []) self.sendGroupMessageToXMPP(buddy, partname, messageContent, timestamp) else: From 1c0ae79ec2b5308595b15cefde137ea0024375f2 Mon Sep 17 00:00:00 2001 From: moyamo Date: Mon, 26 Oct 2015 18:47:17 +0200 Subject: [PATCH 09/10] Fix join room, inform user of all groups, and new participants In the previous implementation join_room was called on all groups immediately after the user was authenticated. When a user joined a group, join_room will be called again. This was incorrect behaviour and confused spectrum. There was no truncation error, thus _shortenGroupId and _lengthenGroupId have edited to be a no-op (and should be removed in the next commit). The correct behavoiur is to only call join_room in whatsappbackend.py:handleRoomJoined, however the user may do this before the groups have been loaded, in which case those requests must be added to a queue. The bot informs the user of all the groups the user has joined and when the user is added to a new group. --- session.py | 100 +++++++++++++++++++++++++-------------------- transwhat.py | 2 +- whatsappbackend.py | 3 +- yowsupwrapper.py | 37 ++++++++++++----- 4 files changed, 85 insertions(+), 57 deletions(-) diff --git a/session.py b/session.py index 7193be3..a8a4bbd 100644 --- a/session.py +++ b/session.py @@ -52,6 +52,8 @@ class Session(YowsupApp): self.statusMessage = '' self.groups = {} + self.gotGroupList = False + self.joinRoomQueue = [] self.presenceRequested = [] self.offlineQueue = [] self.groupOfflineQueue = { } @@ -79,20 +81,27 @@ class Session(YowsupApp): super(Session, self).login(self.legacyName, self.password) def _shortenGroupId(self, gid): - # FIXME: will have problems if number begins with 0 - return '-'.join(hex(int(s))[2:] for s in gid.split('-')) - + # FIXME: might have problems if number begins with 0 + return gid +# return '-'.join(hex(int(s))[2:] for s in gid.split('-')) + def _lengthenGroupId(self, gid): - # FIXME: will have problems if number begins with 0 - return '-'.join(str(int(s, 16)) for s in gid.split('-')) + return gid + # FIXME: might have problems if number begins with 0 +# return '-'.join(str(int(s, 16)) for s in gid.split('-')) def updateRoomList(self): rooms = [] + text = [] for room, group in self.groups.iteritems(): rooms.append([self._shortenGroupId(room), group.subject]) + text.append(self._shortenGroupId(room) + '@' + self.backend.spectrum_jid + ' :' + group.subject) self.logger.debug("Got rooms: %s", rooms) self.backend.handleRoomList(rooms) + message = "Note, you are a participant of the following groups:\n" +\ + '\n'.join(text) + '\nIf you do not join them you will lose messages' + self.bot.send(message) def updateRoster(self): self.logger.debug("Update roster") @@ -143,9 +152,10 @@ class Session(YowsupApp): oroom.subject = subject else: self.groups[room] = Group(room, owner, subject, subjectOwner) - self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0]) +# self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0]) + self.groups[room].participants = group.getParticipants().keys() - self._addParticipantsToRoom(room, group.getParticipants()) + #self._addParticipantsToRoom(room, group.getParticipants()) if room in self.groupOfflineQueue: while self.groupOfflineQueue[room]: @@ -154,9 +164,16 @@ class Session(YowsupApp): msg[0], "", msg[2]) self.logger.debug("Send queued group message to: %s %s %s", msg[0],msg[1], msg[2]) + self.gotGroupList = True + for room, nick in self.joinRoomQueue: + self.joinRoom(room, nick) + self.joinRoomQueue = [] self.updateRoomList() def joinRoom(self, room, nick): + if not self.gotGroupList: + self.joinRoomQueue.append((room, nick)) + return room = self._lengthenGroupId(room) if room in self.groups: self.logger.info("Joining room: %s room=%s, nick=%s", @@ -169,13 +186,14 @@ class Session(YowsupApp): except KeyError: ownerNick = group.subjectOwner + self._refreshParticipants(room) self.backend.handleSubject(self.user, self._shortenGroupId(room), - group.subject, - ownerNick) + group.subject) + self.logger.debug("Room subject: room=%s, subject=%s", + room, group.subject) self.backend.handleRoomNicknameChanged( self.user, self._shortenGroupId(room), group.subject ) - self._refreshParticipants(room) else: self.logger.warn("Room doesn't exist: %s", room) @@ -191,7 +209,6 @@ class Session(YowsupApp): if nick == "": nick = buddy - buddyFull = buddy if buddy == group.owner: flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR else: @@ -199,38 +216,9 @@ class Session(YowsupApp): if buddy == self.legacyName: nick = group.nick flags = flags | protocol_pb2.PARTICIPANT_FLAG_ME - buddyFull = self.user self.backend.handleParticipantChanged( - self.user, buddyFull, self._shortenGroupId(room), flags, - protocol_pb2.STATUS_ONLINE, buddy, nick) - - def _addParticipantsToRoom(self, room, participants): - group = self.groups[room] - group.participants = participants - - for jid, _type in participants.iteritems(): - buddy = jid.split("@")[0] - buddyFull = buddy - self.logger.info("Added %s to room %s", buddy, room) - try: - nick = self.buddies[buddy].nick - except KeyError: - nick = buddy - buddyFull = buddy - if _type == 'admin': - flags = protocol_pb2.PARTICIPANT_FLAG_MODERATOR - else: - flags = protocol_pb2.PARTICIPANT_FLAG_NONE - if buddy == self.legacyName: - nick = group.nick - flags = protocol_pb2.PARTICIPANT_FLAG_ME - buddyFull = self.user - - self.backend.handleParticipantChanged( - self.user, buddyFull, self._shortenGroupId(room), flags, - protocol_pb2.STATUS_ONLINE, buddy, nick - ) - + self.user, nick, self._shortenGroupId(room), flags, + protocol_pb2.STATUS_ONLINE, buddy) def _lastSeen(self, number, seconds): self.logger.debug("Last seen %s at %s seconds" % (number, str(seconds))) @@ -309,9 +297,9 @@ class Session(YowsupApp): if part.nick == "": part.nick = notify self.backend.handleParticipantChanged( - self.user, partname, buddy, + self.user, partname, self._shortenGroupId(buddy), protocol_pb2.PARTICIPANT_FLAG_NONE, - protocol_pb2.STATUS_NONE, "", part.nick + protocol_pb2.STATUS_ONLINE, "", part.nick ) # TODO except KeyError: self.updateBuddy(partname, notify, []) @@ -402,6 +390,28 @@ class Session(YowsupApp): self.timer = Timer(3, self.backend.handleBuddyStoppedTyping, (self.user, buddy)).start() + # Called by superclass + def onAddedToGroup(self, group): + self.logger.debug("Added to group: %s", group) + room = group.getGroupId() + owner = group.getCreatorJid(full = False) + subjectOwner = group.getSubjectOwnerJid(full = False) + subject = utils.softToUni(group.getSubject()) + + self.groups[room] = Group(room, owner, subject, subjectOwner) + self.groups[room].participants = group.getParticipants().keys() +# self.joinRoom(self._shortenGroupId(room), self.user.split("@")[0]) + + #self._addParticipantsToRoom(room, group.getParticipants()) + self.bot.send("You have been added to group: %s@%s (%s)" + % (self._shortenGroupId(room), subject, self.backend.spectrum_jid)) + + def onParticipantsAddedToGroup(self, group): + self.logger.debug("Participants added to group: %s", group) + room = group.getGroupId().split('@')[0] + self.groups[room].participants.extend(group.getParticipants()) + self._refreshParticipants(room) + def onPresenceReceived(self, _type, name, jid, lastseen): self.logger.info("Presence received: %s %s %s %s", _type, name, jid, lastseen) buddy = jid.split("@")[0] @@ -504,7 +514,7 @@ class Session(YowsupApp): "", timestamp) def sendGroupMessageToXMPP(self, room, buddy, messageContent, timestamp = ""): - self._refreshParticipants(room) + # self._refreshParticipants(room) try: nick = self.buddies[buddy].nick except KeyError: diff --git a/transwhat.py b/transwhat.py index 84abc31..5875dc4 100755 --- a/transwhat.py +++ b/transwhat.py @@ -78,7 +78,7 @@ def connectionClosed(): db = MySQLdb.connect(DB_HOST, DB_USER, DB_PASS, DB_TABLE) io = IOChannel(args.host, args.port, handleTransportData, connectionClosed) -plugin = WhatsAppBackend(io, db) +plugin = WhatsAppBackend(io, db, args.j) while True: try: diff --git a/whatsappbackend.py b/whatsappbackend.py index b973f76..c645330 100644 --- a/whatsappbackend.py +++ b/whatsappbackend.py @@ -30,12 +30,13 @@ from session import Session import logging class WhatsAppBackend(SpectrumBackend): - def __init__(self, io, db): + def __init__(self, io, db, spectrum_jid): SpectrumBackend.__init__(self) self.logger = logging.getLogger(self.__class__.__name__) self.io = io self.db = db self.sessions = { } + self.spectrum_jid = spectrum_jid # Used to prevent duplicate messages self.lastMessage = {} diff --git a/yowsupwrapper.py b/yowsupwrapper.py index 2a8349b..7ed3d4a 100644 --- a/yowsupwrapper.py +++ b/yowsupwrapper.py @@ -1,3 +1,5 @@ +import logging + from yowsup import env from yowsup.stacks import YowStack from yowsup.common import YowConstants @@ -67,6 +69,7 @@ class YowsupApp(object): YowStanzaRegulator, YowNetworkLayer ) + self.logger = logging.getLogger(self.__class__.__name__) self.stack = YowStack(layers) self.stack.broadcastEvent( YowLayerEvent(YowsupAppLayer.EVENT_START, caller = self) @@ -108,7 +111,7 @@ class YowsupApp(object): Logout from whatsapp """ self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT)) - + def sendReceipt(self, _id, _from, read, participant): """ Send a receipt (delivered: double-tick, read: blue-ticks) @@ -168,7 +171,7 @@ class YowsupApp(object): jid = phone_number + '@s.whatsapp.net' entity = UnsubscribePresenceProtocolEntity(jid) self.sendEntity(entity) - + def setStatus(self, statusText): """ Send status to whatsapp @@ -313,7 +316,7 @@ class YowsupApp(object): - timestamp """ pass - + def onPresenceReceived(self, _type, name, _from, last): """ Called when presence (e.g. available, unavailable) is received @@ -331,7 +334,7 @@ class YowsupApp(object): """ Called when disconnected from whatsapp """ - + def onContactTyping(self, number): """ Called when contact starts to type @@ -366,7 +369,7 @@ class YowsupApp(object): - body: The content of the message """ pass - + def onImage(self, entity): """ Called when image message is received @@ -384,7 +387,7 @@ class YowsupApp(object): - entity: AudioDownloadableMediaMessageProtocolEntity """ pass - + def onVideo(self, entity): """ @@ -403,7 +406,7 @@ class YowsupApp(object): - entity: LocationMediaMessageProtocolEntity """ pass - + def onVCard(self, _id, _from, name, card_data, to, notify, timestamp, participant): """ Called when VCard message is received @@ -420,12 +423,20 @@ class YowsupApp(object): """ pass + def onAddedToGroup(self, entity): + """Called when the user has been added to a new group""" + pass + + def onParticipantsAddedToGroup(self, entity): + """Called when participants have been added to a group""" + pass + def sendEntity(self, entity): """Sends an entity down the stack (as if YowsupAppLayer called toLower)""" self.stack.broadcastEvent(YowLayerEvent(YowsupAppLayer.TO_LOWER_EVENT, entity = entity )) - + def sendIq(self, iq, onSuccess = None, onError = None): self.stack.broadcastEvent( YowLayerEvent( @@ -450,6 +461,7 @@ class YowsupAppLayer(YowInterfaceLayer): # return True otherwise if layerEvent.getName() == YowsupAppLayer.EVENT_START: self.caller = layerEvent.getArg('caller') + self.logger = logging.getLogger(self.__class__.__name__) return True elif layerEvent.getName() == YowNetworkLayer.EVENT_STATE_DISCONNECTED: self.caller.onDisconnect() @@ -514,8 +526,13 @@ class YowsupAppLayer(YowInterfaceLayer): """ Sends ack automatically """ + self.logger.debug("Received notification: %s", entity) self.toLower(entity.ack()) - + if isinstance(entity, CreateGroupsNotificationProtocolEntity): + self.caller.onAddedToGroup(entity) + elif isinstance(entity, AddGroupsNotificationProtocolEntity): + self.caller.onParticipantsAddedToGroup(entity) + @ProtocolEntityCallback('message') def onMessageReceived(self, entity): if entity.getType() == MessageProtocolEntity.MESSAGE_TYPE_TEXT: @@ -560,7 +577,7 @@ class YowsupAppLayer(YowInterfaceLayer): _from = presence.getFrom() last = presence.getLast() self.caller.onPresenceReceived(_type, name, _from, last) - + @ProtocolEntityCallback('chatstate') def onChatstate(self, chatstate): number = chatstate._from.split('@')[0] From dbb66e03815bcf36afc6da1fc73125f11635b066 Mon Sep 17 00:00:00 2001 From: moyamo Date: Thu, 5 Nov 2015 17:57:16 +0200 Subject: [PATCH 10/10] Prevent no caption in an image from crashing transwhat --- Spectrum2/backend.py | 2 +- session.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Spectrum2/backend.py b/Spectrum2/backend.py index a4bdd50..c09ed33 100644 --- a/Spectrum2/backend.py +++ b/Spectrum2/backend.py @@ -7,7 +7,7 @@ import logging import google.protobuf def WRAP(MESSAGE, TYPE): - wrap = protocol_pb2.WrapperMessage() + wrap = protocol_pb2.WrapperMessage() wrap.type = TYPE wrap.payload = MESSAGE return wrap.SerializeToString() diff --git a/session.py b/session.py index a8a4bbd..d03eaaa 100644 --- a/session.py +++ b/session.py @@ -318,6 +318,8 @@ class Session(YowsupApp): def onImage(self, image): self.logger.debug('Received image message %s', str(image)) buddy = image._from.split('@')[0] + if image.caption is None: + image.caption = '' message = image.url + ' ' + image.caption self.sendMessageToXMPP(buddy, message, image.timestamp) self.sendReceipt(image._id, image._from, None, image.participant)