Exemplo n.º 1
0
class WAXMPP():
	message_store = None
	def __init__(self,domain,resource,user,push_name,password):
		
		WADebug.attach(self);
		
		self.domain = domain;
		self.resource = resource;
		self.user=user;
		self.push_name=push_name;
		self.password = password;
		self.jid = user+'@'+domain
		self.fromm = user+'@'+domain+'/'+resource;
		self.supports_receipt_acks = False;
		self.msg_id = 0;
		self.state = 0 #0 disconnected 1 connecting 2 connected
		self.retry = True
		self.eventHandler = WAEventHandler(self);
		self.conn =MySocketConnection();		
		self.stanzaReader = None
		self.login = None;
		
		self.disconnectRequested = False
		
		self.connTries = 0;
		
		self.verbose = True
		self.iqId = 0;
		self.lock = threading.Lock()
		
		self.waiting = 0;
		
		#super(WAXMPP,self).__init__();
		
		self.eventHandler.initialConnCheck();
		
		#self.do_login();
		
	
	
	
	def setContactsManager(self,contactsManager):
		self.contactsManager = contactsManager
		
	def setReceiptAckCapable(self,can):
		#print "Switching to True"
		self.supports_receipt_acks = True;
		#print self.supports_receipt_acks

		
	
	
	
	def onLoginSuccess(self):
		self.changeState(4)
		
		self.connectionTries = 0
		c = StanzaReader(self);
		
		c.setEventHandler(self.eventHandler);
		
		#initial presence
		self.stanzaReader = c
		
		self.stanzaReader.start();
		
		
		self.sendClientConfig('','',False,'');
		self.sendAvailableForChat();
		self.eventHandler.connected.emit();
		
		

	def onConnectionError(self):
		self.login.wait()
		self.conn.close()	

		self.changeState(3)
		
		'''
		if self.connTries < 4:
			print "trying connect "+str(self.connTries)
			self.retryLogin()
		else:
			print "Too many tries, trying in 30000"
			t = QTimer.singleShot(30000,self.retryLogin)
		'''
	
	
	
	def disconnect(self):
		self.conn.close()
	
	def retryLogin(self):
		self.changeState(3);
	
	def changeState(self,newState):
		self._d("Entering critical area")
		self.waiting+=1
		self.lock.acquire()
		self.waiting-=1
		self._d("inside critical area")
		
		if self.state == 0:
			if newState == 2:
				self.state = 1
				self.do_login();
				
		elif self.state == 1:
			#raise Exception("mutex violated! I SHOULDN'T BE HERE !!!")
			if newState == 0:
				self.retry = False
			elif newState == 2:
				self.retry = True
			elif newState == 3: #failed
				if self.retry:
					
					
					if self.connTries >= 3:
						self._d("%i or more failed connections. Will try again in 30 seconds" % self.connTries)
						QTimer.singleShot(30000,self.retryLogin)
						self.connTries-=1
						
					else:	
						self.do_login()
						self.connTries+=1
				else:
					self.connTries = 0
					self.state = 0
					self.retry = True
					
			elif newState == 4:#connected
				self.connTries = 0
				self.retry = True
				self.state = 2
		elif self.state == 2:
			if newState == 2:
				self.disconnect()
				self.state = 1
				self.do_login()
			elif newState == 0:
				self.disconnect()
				self.state = 0
		
		
		self._d("Releasing lock")
		self.lock.release()
		
		
			

	def do_login(self):
		
		self.conn = conn = MySocketConnection();
		#conn.connect((HOST, PORT));

		self.inn = BinTreeNodeReader(conn,WALogin.dictionary);
		self.out = BinTreeNodeWriter(conn,WALogin.dictionary);
		
		
		self.login = WALogin(conn,self.inn,self.out,S40MD5Digest());
		
		
		self.login.setConnection(self);
		
		self.login.loginSuccess.connect(self.onLoginSuccess)
		self.login.loginFailed.connect(self.eventHandler.onLoginFailed);
		
		self.login.connectionError.connect(self.onConnectionError)
		self.login.start();
		
		'''try:
			self.login.login();
		except:
			print "LOGIN FAILED"
			#sys.exit()
			return
		'''
		



		#fmsg = FMessage();
		#fmsg.setData('*****@*****.**',True,"Hello World");
		
		#self.sendIq();
		#self.inn.nextTree();
		#print self.inn.inn.buf;
		#exit();
		#self.inn.nextTree();
		
		
		
		#self.sendMessageWithBody("ok");
		#node = self.inn.nextTree();
		#print node.toString();

		#self.sendSubscribe("*****@*****.**");
		
		#self.sendMessageWithBody("OK");
		#self.sendMessageWithBody("OK");
		#node = self.inn.nextTree();
		#print node.toString();
		#raw_input();
		#self.sendMessageWithBody(fmsg);
	
	
	def resendUnsent(self):
		'''
			Resends all unsent messages, should invoke on connect
		'''
		
		
		messages = WAXMPP.message_store.getUnsent();
		self._d("Resending %i old messages"%(len(messages)))
		for m in messages:
			self.sendMessageWithBody(m);
		
		
	
	def sendTyping(self,jid):
		self._d("SEND TYPING TO JID")
		composing = ProtocolTreeNode("composing",{"xmlns":"http://jabber.org/protocol/chatstates"})
		message = ProtocolTreeNode("message",{"to":jid,"type":"chat"},[composing]);
		self.out.write(message);
		
	
		
	def sendPaused(self,jid):
		self._d("SEND PAUSED TO JID")
		composing = ProtocolTreeNode("paused",{"xmlns":"http://jabber.org/protocol/chatstates"})
		message = ProtocolTreeNode("message",{"to":jid,"type":"chat"},[composing]);
		self.out.write(message);

	
	
	def getSubjectMessage(self,to,msg_id,child):
		messageNode = ProtocolTreeNode("message",{"to":to,"type":"subject","id":msg_id},[child]);
		
		return messageNode
	
	def sendSubjectReceived(self,to,msg_id):
		self._d("Sending subject recv receipt")
		receivedNode = ProtocolTreeNode("received",{"xmlns": "urn:xmpp:receipts"});
		messageNode = self.getSubjectMessage(to,msg_id,receivedNode);
		self.out.write(messageNode);

	def sendMessageReceived(self,fmsg):
		receivedNode = ProtocolTreeNode("received",{"xmlns": "urn:xmpp:receipts"})
		messageNode = ProtocolTreeNode("message",{"to":fmsg.key.remote_jid,"type":"chat","id":fmsg.key.id},[receivedNode]);
		self.out.write(messageNode);


	def sendDeliveredReceiptAck(self,to,msg_id):
		self.out.write(self.getReceiptAck(to,msg_id,"delivered"));
	
	def sendVisibleReceiptAck(self,to,msg_id):
		self.out.write(self.getReceiptAck(to,msg_id,"visible"));
	
	def getReceiptAck(self,to,msg_id,receiptType):
		ackNode = ProtocolTreeNode("ack",{"xmlns":"urn:xmpp:receipts","type":receiptType})
		messageNode = ProtocolTreeNode("message",{"to":to,"type":"chat","id":msg_id},[ackNode]);
		return messageNode;

	def makeId(self,prefix):
		self.iqId += 1
		idx = ""
		if self.verbose:
			idx += prefix + str(self.iqId);
		else:
			idx = "%x" % self.iqId
		
		return idx
		 	
	
	def sendPing(self):
		
		idx = self.makeId("ping_")
		self.stanzaReader.requests[idx] = self.stanzaReader.handlePingResponse;
		
		pingNode = ProtocolTreeNode("ping",{"xmlns":"w:p"});
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":self.domain},[pingNode]);
		self.out.write(iqNode);
		
	
	def sendPong(self,idx):
		iqNode = ProtocolTreeNode("iq",{"type":"result","to":self.domain,"id":idx})
		self.out.write(iqNode);
	
	def getLastOnline(self,jid):
		
		if len(jid.split('-')) == 2: #SUPER CANCEL SUBSCRIBE TO GROUP
			return
		
		self.sendSubscribe(jid);
		
		self._d("presence request Initiated for %s"%(jid))
		idx = self.makeId("last_")
		self.stanzaReader.requests[idx] = self.stanzaReader.handleLastOnline;
		
		query = ProtocolTreeNode("query",{"xmlns":"jabber:iq:last"});
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":jid},[query]);
		self.out.write(iqNode)
	
	
	def sendIq(self):
		node = ProtocolTreeNode("iq",{"to":"g.us","type":"get","id":str(int(time.time()))+"-0"},None,'expired');
		self.out.write(node);

		node = ProtocolTreeNode("iq",{"to":"s.whatsapp.net","type":"set","id":str(int(time.time()))+"-1"},None,'expired');
		self.out.write(node);

	def sendAvailableForChat(self):
		presenceNode = ProtocolTreeNode("presence",{"name":self.push_name})
		self.out.write(presenceNode);
		
	def sendAvailable(self):
		if self.state != 2:
			return
		presenceNode = ProtocolTreeNode("presence",{"type":"available"})
		self.out.write(presenceNode);
	
	
	def sendUnavailable(self):
		if self.state != 2:
			return
		presenceNode = ProtocolTreeNode("presence",{"type":"unavailable"})
		self.out.write(presenceNode);
		

	def sendSubscribe(self,to):
			presenceNode = ProtocolTreeNode("presence",{"type":"subscribe","to":to});
			
			self.out.write(presenceNode);

	def sendMessageWithBody(self,fmsg):
			#bodyNode = ProtocolTreeNode("body",None,message.data);
			#self.out.write(self.getMessageNode(message,bodyNode));

			bodyNode = ProtocolTreeNode("body",None,None,fmsg.content);
			self.out.write(self.getMessageNode(fmsg,bodyNode));
			self.msg_id+=1;

	
	def sendClientConfig(self,sound,pushID,preview,platform):
		idx = self.makeId("config_");
		configNode = ProtocolTreeNode("config",{"xmlns":"urn:xmpp:whatsapp:push","sound":sound,"id":pushID,"preview":"1" if preview else "0","platform":platform})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":self.domain},[configNode]);
		
		self.out.write(iqNode);
		
	
	
	def sendGetGroupInfo(self,jid):
		idx = self.makeId("get_g_info_")
		self.stanzaReader.requests[idx] = self.stanzaReader.handleGroupInfo;
		
		queryNode = ProtocolTreeNode("query",{"xmlns":"w:g"})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":jid},[queryNode])
		
		self.out.write(iqNode)

	
	def getMessageNode(self,fmsg,child):
			requestNode = None;
			serverNode = ProtocolTreeNode("server",None);
			xNode = ProtocolTreeNode("x",{"xmlns":"jabber:x:event"},[serverNode]);
			childCount = (0 if requestNode is None else 1) +2;
			messageChildren = [None]*childCount;
			i = 0;
			if requestNode is not None:
				messageChildren[i] = requestNode;
				i+=1;
			#System.currentTimeMillis() / 1000L + "-"+1
			messageChildren[i] = xNode;
			i+=1;
			messageChildren[i]= child;
			i+=1;
			
			key = eval(fmsg.key)
			messageNode = ProtocolTreeNode("message",{"to":key.remote_jid,"type":"chat","id":key.id},messageChildren)
			
			
			return messageNode;
Exemplo n.º 2
0
class WAXMPP():
    message_store = None

    def __init__(self, domain, resource, user, push_name, password):

        self.domain = domain
        self.resource = resource
        self.user = user
        self.push_name = push_name
        self.password = password
        self.jid = user + '@' + domain
        self.fromm = user + '@' + domain + '/' + resource
        self.supports_receipt_acks = False
        self.msg_id = 0
        self.state = 0  #0 disconnected 1 connecting 2 connected
        self.retry = True
        self.eventHandler = WAEventHandler(self)
        self.conn = MySocketConnection()
        self.stanzaReader = None
        self.login = None

        self.disconnectRequested = False

        self.connTries = 0

        self.verbose = True
        self.iqId = 0
        self.lock = threading.Lock()

        self.waiting = 0

        #super(WAXMPP,self).__init__();

        self.eventHandler.initialConnCheck()

        #self.do_login();

    def setContactsManager(self, contactsManager):
        self.contactsManager = contactsManager

    def setReceiptAckCapable(self, can):
        #print "Switching to True"
        self.supports_receipt_acks = True
        #print self.supports_receipt_acks

    def onLoginSuccess(self):
        self.changeState(4)

        self.connectionTries = 0
        c = StanzaReader(self)

        c.setEventHandler(self.eventHandler)

        #initial presence
        self.stanzaReader = c

        self.stanzaReader.start()

        self.sendClientConfig('', '', False, '')
        self.sendAvailableForChat()
        self.eventHandler.connected.emit()

    def onConnectionError(self):
        self.login.wait()
        self.conn.close()

        self.changeState(3)
        '''
		if self.connTries < 4:
			print "trying connect "+str(self.connTries)
			self.retryLogin()
		else:
			print "Too many tries, trying in 30000"
			t = QTimer.singleShot(30000,self.retryLogin)
		'''

    def disconnect(self):
        self.conn.close()

    def retryLogin(self):
        self.changeState(3)

    def changeState(self, newState):
        print "Entering critical area"
        self.waiting += 1
        self.lock.acquire()
        self.waiting -= 1
        print "inside critical area"

        if self.state == 0:
            if newState == 2:
                self.state = 1
                self.do_login()

        elif self.state == 1:
            #raise Exception("mutex violated! I SHOULDN'T BE HERE !!!")
            if newState == 0:
                self.retry = False
            elif newState == 2:
                self.retry = True
            elif newState == 3:  #failed
                if self.retry:

                    if self.connTries >= 3:
                        print "%i or more failed connections. Will try again in 30 seconds" % self.connTries
                        QTimer.singleShot(30000, self.retryLogin)
                        self.connTries -= 1

                    else:
                        self.do_login()
                        self.connTries += 1
                else:
                    self.connTries = 0
                    self.state = 0
                    self.retry = True

            elif newState == 4:  #connected
                self.connTries = 0
                self.retry = True
                self.state = 2
        elif self.state == 2:
            if newState == 2:
                self.disconnect()
                self.state = 1
                self.do_login()
            elif newState == 0:
                self.disconnect()
                self.state = 0

        print "Releasing lock"
        self.lock.release()

    def do_login(self):

        self.conn = conn = MySocketConnection()
        #conn.connect((HOST, PORT));

        self.inn = BinTreeNodeReader(conn, WALogin.dictionary)
        self.out = BinTreeNodeWriter(conn, WALogin.dictionary)

        self.login = WALogin(conn, self.inn, self.out, S40MD5Digest())

        self.login.setConnection(self)

        self.login.loginSuccess.connect(self.onLoginSuccess)
        self.login.loginFailed.connect(self.eventHandler.onLoginFailed)

        self.login.connectionError.connect(self.onConnectionError)
        self.login.start()
        '''try:
			self.login.login();
		except:
			print "LOGIN FAILED"
			#sys.exit()
			return
		'''

        #fmsg = FMessage();
        #fmsg.setData('*****@*****.**',True,"Hello World");

        #self.sendIq();
        #self.inn.nextTree();
        #print self.inn.inn.buf;
        #exit();
        #self.inn.nextTree();

        #self.sendMessageWithBody("ok");
        #node = self.inn.nextTree();
        #print node.toString();

        #self.sendSubscribe("*****@*****.**");

        #self.sendMessageWithBody("OK");
        #self.sendMessageWithBody("OK");
        #node = self.inn.nextTree();
        #print node.toString();
        #raw_input();
        #self.sendMessageWithBody(fmsg);

    def resendUnsent(self):
        '''
			Resends all unsent messages, should invoke on connect
		'''

        messages = WAXMPP.message_store.getUnsent()
        print "Resending %i old messages" % (len(messages))
        for m in messages:
            self.sendMessageWithBody(m)

    def sendTyping(self, jid):
        print "SEND TYPING TO JID"
        composing = ProtocolTreeNode(
            "composing", {"xmlns": "http://jabber.org/protocol/chatstates"})
        message = ProtocolTreeNode("message", {
            "to": jid,
            "type": "chat"
        }, [composing])
        self.out.write(message)

    def sendPaused(self, jid):
        print "SEND PAUSED TO JID"
        composing = ProtocolTreeNode(
            "paused", {"xmlns": "http://jabber.org/protocol/chatstates"})
        message = ProtocolTreeNode("message", {
            "to": jid,
            "type": "chat"
        }, [composing])
        self.out.write(message)

    def getSubjectMessage(self, to, msg_id, child):
        messageNode = ProtocolTreeNode("message", {
            "to": to,
            "type": "subject",
            "id": msg_id
        }, [child])

        return messageNode

    def sendSubjectReceived(self, to, msg_id):
        print "Sending subject recv receipt"
        receivedNode = ProtocolTreeNode("received",
                                        {"xmlns": "urn:xmpp:receipts"})
        messageNode = self.getSubjectMessage(to, msg_id, receivedNode)
        self.out.write(messageNode)

    def sendMessageReceived(self, fmsg):
        receivedNode = ProtocolTreeNode("received",
                                        {"xmlns": "urn:xmpp:receipts"})
        messageNode = ProtocolTreeNode("message", {
            "to": fmsg.key.remote_jid,
            "type": "chat",
            "id": fmsg.key.id
        }, [receivedNode])
        self.out.write(messageNode)

    def sendDeliveredReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, "delivered"))

    def sendVisibleReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, "visible"))

    def getReceiptAck(self, to, msg_id, receiptType):
        ackNode = ProtocolTreeNode("ack", {
            "xmlns": "urn:xmpp:receipts",
            "type": receiptType
        })
        messageNode = ProtocolTreeNode("message", {
            "to": to,
            "type": "chat",
            "id": msg_id
        }, [ackNode])
        return messageNode

    def makeId(self, prefix):
        self.iqId += 1
        idx = ""
        if self.verbose:
            idx += prefix + str(self.iqId)
        else:
            idx = "%x" % self.iqId

        return idx

    def sendPing(self):

        idx = self.makeId("ping_")
        self.stanzaReader.requests[idx] = self.stanzaReader.handlePingResponse

        pingNode = ProtocolTreeNode("ping", {"xmlns": "w:p"})
        iqNode = ProtocolTreeNode("iq", {
            "id": idx,
            "type": "get",
            "to": self.domain
        }, [pingNode])
        self.out.write(iqNode)

    def sendPong(self, idx):
        iqNode = ProtocolTreeNode("iq", {
            "type": "result",
            "to": self.domain,
            "id": idx
        })
        self.out.write(iqNode)

    def getLastOnline(self, jid):

        if len(jid.split('-')) == 2:  #SUPER CANCEL SUBSCRIBE TO GROUP
            return

        self.sendSubscribe(jid)

        print "presence request Initiated for %s" % (jid)
        idx = self.makeId("last_")
        self.stanzaReader.requests[idx] = self.stanzaReader.handleLastOnline

        query = ProtocolTreeNode("query", {"xmlns": "jabber:iq:last"})
        iqNode = ProtocolTreeNode("iq", {
            "id": idx,
            "type": "get",
            "to": jid
        }, [query])
        self.out.write(iqNode)

    def sendIq(self):
        node = ProtocolTreeNode("iq", {
            "to": "g.us",
            "type": "get",
            "id": str(int(time.time())) + "-0"
        }, None, 'expired')
        self.out.write(node)

        node = ProtocolTreeNode(
            "iq", {
                "to": "s.whatsapp.net",
                "type": "set",
                "id": str(int(time.time())) + "-1"
            }, None, 'expired')
        self.out.write(node)

    def sendAvailableForChat(self):
        presenceNode = ProtocolTreeNode("presence", {"name": self.push_name})
        self.out.write(presenceNode)

    def sendAvailable(self):
        if self.state != 2:
            return
        presenceNode = ProtocolTreeNode("presence", {"type": "available"})
        self.out.write(presenceNode)

    def sendUnavailable(self):
        if self.state != 2:
            return
        presenceNode = ProtocolTreeNode("presence", {"type": "unavailable"})
        self.out.write(presenceNode)

    def sendSubscribe(self, to):
        presenceNode = ProtocolTreeNode("presence", {
            "type": "subscribe",
            "to": to
        })

        self.out.write(presenceNode)

    def sendMessageWithBody(self, fmsg):
        #bodyNode = ProtocolTreeNode("body",None,message.data);
        #self.out.write(self.getMessageNode(message,bodyNode));

        bodyNode = ProtocolTreeNode("body", None, None, fmsg.content)
        self.out.write(self.getMessageNode(fmsg, bodyNode))
        self.msg_id += 1

    def sendClientConfig(self, sound, pushID, preview, platform):
        idx = self.makeId("config_")
        configNode = ProtocolTreeNode(
            "config", {
                "xmlns": "urn:xmpp:whatsapp:push",
                "sound": sound,
                "id": pushID,
                "preview": "1" if preview else "0",
                "platform": platform
            })
        iqNode = ProtocolTreeNode("iq", {
            "id": idx,
            "type": "set",
            "to": self.domain
        }, [configNode])

        self.out.write(iqNode)

    def getMessageNode(self, fmsg, child):
        requestNode = None
        serverNode = ProtocolTreeNode("server", None)
        xNode = ProtocolTreeNode("x", {"xmlns": "jabber:x:event"},
                                 [serverNode])
        childCount = (0 if requestNode is None else 1) + 2
        messageChildren = [None] * childCount
        i = 0
        if requestNode is not None:
            messageChildren[i] = requestNode
            i += 1
        #System.currentTimeMillis() / 1000L + "-"+1
        messageChildren[i] = xNode
        i += 1
        messageChildren[i] = child
        i += 1

        key = eval(fmsg.key)
        messageNode = ProtocolTreeNode("message", {
            "to": key.remote_jid,
            "type": "chat",
            "id": key.id
        }, messageChildren)

        return messageNode
Exemplo n.º 3
0
class WAXMPP:
    SERVER = 's.whatsapp.net'
    USER_AGENT = "iPhone-2.8.3"

    def __init__(
        self,
        user,
        push_name,
        password,
        ):

        self.domain = WAXMPP.SERVER
        self.resource = WAXMPP.USER_AGENT
        self.user = user
        self.push_name = push_name
        self.password = password
        self.jid = user + '@' + WAXMPP.SERVER
        self.fromm = user + '@' + WAXMPP.SERVER + '/' + WAXMPP.USER_AGENT
        self.supports_receipt_acks = False
        self.msg_id = 0

        self.retry = True
        self.event = WAEventHandler(self)
        self.stanzaReader = None

        self.disconnectRequested = False

        self.connTries = 0

        self.verbose = True
        self.iqId = 0
        self.lock = threading.Lock()

        self.waiting = 0

        self.conn = None
        self.inn = None
        self.out = None
        self.event.loginSuccess.connect(self.onLoginSuccess)
        self.event.connectionError.connect(self.onConnectionError)

    def onLoginSuccess(self):
        self.connectionTries = 0
        c = StanzaReader(self)

        self.stanzaReader = c

        self.stanzaReader.start()

        self.sendClientConfig('', '', False, '')
        self.sendAvailableForChat()
        self.event.connected.emit()

    def onConnectionError(self):
        pass

    def disconnect(self):
        self.event.disconnectRequested.emit()
        self.disconnectRequested = True

    def login(self):
        self.conn = MySocketConnection()
        self.inn = BinTreeNodeReader(self.conn, Login.dictionary)
        self.out = BinTreeNodeWriter(self.conn, Login.dictionary)

        self.walogin = Login(self)
        self.walogin.start()

    def sendTyping(self, jid):
        composing = ProtocolTreeNode('composing',
                {'xmlns': 'http://jabber.org/protocol/chatstates'})
        message = ProtocolTreeNode('message', {'to': jid, 'type': 'chat'
                                   }, [composing])
        self.out.write(message)

    def sendPaused(self, jid):
        composing = ProtocolTreeNode('paused',
                {'xmlns': 'http://jabber.org/protocol/chatstates'})
        message = ProtocolTreeNode('message', {'to': jid, 'type': 'chat'
                                   }, [composing])
        self.out.write(message)

    def getSubjectMessage(
        self,
        to,
        msg_id,
        child,
        ):
        messageNode = ProtocolTreeNode('message', {'to': to,
                'type': 'subject', 'id': msg_id}, [child])

        return messageNode


    def sendSubjectReceived(self, to, msg_id):
        receivedNode = ProtocolTreeNode('received',
                {'xmlns': 'urn:xmpp:receipts'})
        messageNode = self.getSubjectMessage(to, msg_id, receivedNode)
        self.out.write(messageNode)

    def sendMessageReceived(self, fmsg):
        receivedNode = ProtocolTreeNode('received',
                {'xmlns': 'urn:xmpp:receipts'})
        messageNode = ProtocolTreeNode('message',
                {'to': fmsg.remote, 'type': 'chat',
                'id': fmsg.id}, [receivedNode])

        self.out.write(messageNode)

    def sendDeliveredReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, 'delivered'))

    def sendVisibleReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, 'visible'))

    def getReceiptAck(
        self,
        to,
        msg_id,
        receiptType,
        ):
        ackNode = ProtocolTreeNode('ack', {'xmlns': 'urn:xmpp:receipts'
                                   , 'type': receiptType})
        messageNode = ProtocolTreeNode('message', {'to': to,
                'type': 'chat', 'id': msg_id}, [ackNode])
        return messageNode

    def makeId(self, prefix):
        self.iqId += 1
        idx = ''
        if self.verbose:
            idx += prefix + str(self.iqId)
        else:
            idx = '%x' % self.iqId

        return idx

    def sendPing(self):
        idx = self.makeId('ping_')
        self.stanzaReader.requests[idx] = \
            self.stanzaReader.handlePingResponse

        pingNode = ProtocolTreeNode('ping', {'xmlns': 'w:p'})
        iqNode = ProtocolTreeNode('iq', {'id': idx, 'type': 'get',
                                  'to': self.domain}, [pingNode])
        self.out.write(iqNode)

    def sendPong(self, idx):
        iqNode = ProtocolTreeNode('iq', {'type': 'result',
                                  'to': self.domain, 'id': idx})
        self.out.write(iqNode)

    def getLastOnline(self, jid):

        if len(jid.split('-')) == 2:
            return

        self.sendSubscribe(jid)

        idx = self.makeId('last_')
        self.stanzaReader.requests[idx] = \
            self.stanzaReader.handleLastOnline

        query = ProtocolTreeNode('query', {'xmlns': 'jabber:iq:last'})
        iqNode = ProtocolTreeNode('iq', {'id': idx, 'type': 'get',
                                  'to': jid}, [query])
        self.out.write(iqNode)

    def sendIq(self):
        node = ProtocolTreeNode('iq', {'to': 'g.us', 'type': 'get',
                                'id': str(int(time.time())) + '-0'},
                                None, 'expired')
        self.out.write(node)

        node = ProtocolTreeNode('iq', {'to': 's.whatsapp.net',
                                'type': 'set',
                                'id': str(int(time.time())) + '-1'},
                                None, 'expired')
        self.out.write(node)

    def leaveGroup(self, group):
        group_nodes = [ProtocolTreeNode('group', {'id': group})]
        node = ProtocolTreeNode('leave', {'xmlns': 'w:g'}, group_nodes)

        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': 'g.us'
            }, [node])

        self.out.write(node_out)

    def addParticipant(self, group, participant):
        self.addParticipants(group, [participant])

    def removeParticipant(self, group, participant):
        self.removeParticipants(group, [participant])

    def addParticipants(self, group, participants):
        self.sendVerbParticipants(group, participants, 'add')

    def removeParticipants(self, group, participants):
        self.sendVerbParticipants(group, participants, 'remove')

    def sendVerbParticipants(self, group, participants, verb):
        participant_nodes = map(lambda p: ProtocolTreeNode('participants', {'jid': p}), participants)

        node = ProtocolTreeNode(verb, {'xmlns': 'w:g'}, participant_nodes)
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': group
            }, [node])

        self.out.write(node_out)

    def setGroupSubject(self, group, subject):
        node = ProtocolTreeNode('subject', {'xmlns': 'w:g', 'value': subject})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': group
            }, [node])

        self.out.write(node_out)

    def sendAvailableForChat(self):
        presenceNode = ProtocolTreeNode('presence',
                {'name': self.push_name})
        self.out.write(presenceNode)

    def sendAvailable(self):
        presenceNode = ProtocolTreeNode('presence', {'type': 'available'})
        self.out.write(presenceNode)

    def sendUnavailable(self):
        presenceNode = ProtocolTreeNode('presence', {'type': 'unavailable'})
        self.out.write(presenceNode)

    def sendSubscribe(self, to):
        presenceNode = ProtocolTreeNode('presence', {'type': 'subscribe', 'to': to})

        self.out.write(presenceNode)

    def getGroups(self):
        self.sendGetGroups('participating')

    def getOwningGroups(self):
        self.sendGetGroups('owning')

    def getParticipants(self, group):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g'})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': group
            }, [node])

        self.out.write(node_out)

    def getServerProperties(self):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g', 'type': 'props'})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': 'g.us'
            }, [node])

        self.out.write(node_out)

    def sendGetGroups(self, group_type):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g', 'type': group_type})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': 'g.us'
            }, [node])

        self.out.write(node_out)

    def sendMessage(self, fmsg):
        bodyNode = ProtocolTreeNode('body', None, None, fmsg.data)
        msgNode = self.getMessageNode(fmsg, bodyNode)

        self.out.write(msgNode)
        self.msg_id += 1

    def sendClientConfig(
        self,
        sound,
        pushID,
        preview,
        platform,
        ):
        idx = self.makeId('config_')
        configNode = ProtocolTreeNode('config', {
            'xmlns': 'urn:xmpp:whatsapp:push',
            'sound': sound,
            'id': pushID,
            'preview': ('1' if preview else '0'),
            'platform': platform,
            })
        iqNode = ProtocolTreeNode('iq', {'id': idx, 'type': 'set',
                                  'to': self.domain}, [configNode])

        self.out.write(iqNode)

    def getMessageNode(self, fmsg, child):
        requestNode = None
        serverNode = ProtocolTreeNode('server', None)
        xNode = ProtocolTreeNode('x', {'xmlns': 'jabber:x:event'},
                                 [serverNode])
        childCount = ((0 if requestNode is None else 1)) + 2
        messageChildren = [None] * childCount
        i = 0
        if requestNode is not None:
            messageChildren[i] = requestNode
            i += 1

        messageChildren[i] = xNode
        i += 1
        messageChildren[i] = child
        i += 1

        messageNode = ProtocolTreeNode('message',
                {'to': fmsg.remote, 'type': 'chat', 'id': fmsg.id},
                messageChildren)

        return messageNode
Exemplo n.º 4
0
class WAXMPP:
    SERVER = 's.whatsapp.net'
    USER_AGENT = "iPhone-2.8.3"

    def __init__(
        self,
        user,
        push_name,
        password,
    ):

        self.domain = WAXMPP.SERVER
        self.resource = WAXMPP.USER_AGENT
        self.user = user
        self.push_name = push_name
        self.password = password
        self.jid = user + '@' + WAXMPP.SERVER
        self.fromm = user + '@' + WAXMPP.SERVER + '/' + WAXMPP.USER_AGENT
        self.supports_receipt_acks = False
        self.msg_id = 0

        self.retry = True
        self.event = WAEventHandler(self)
        self.stanzaReader = None

        self.disconnectRequested = False

        self.connTries = 0

        self.verbose = True
        self.iqId = 0
        self.lock = threading.Lock()

        self.waiting = 0

        self.conn = None
        self.inn = None
        self.out = None
        self.event.loginSuccess.connect(self.onLoginSuccess)
        self.event.connectionError.connect(self.onConnectionError)

    def onLoginSuccess(self):
        self.connectionTries = 0
        c = StanzaReader(self)

        self.stanzaReader = c

        self.stanzaReader.start()

        self.sendClientConfig('', '', False, '')
        self.sendAvailableForChat()
        self.event.connected.emit()

    def onConnectionError(self):
        pass

    def disconnect(self):
        self.event.disconnectRequested.emit()
        self.disconnectRequested = True

    def login(self):
        self.conn = MySocketConnection()
        self.inn = BinTreeNodeReader(self.conn, Login.dictionary)
        self.out = BinTreeNodeWriter(self.conn, Login.dictionary)

        self.walogin = Login(self)
        self.walogin.start()

    def sendTyping(self, jid):
        composing = ProtocolTreeNode(
            'composing', {'xmlns': 'http://jabber.org/protocol/chatstates'})
        message = ProtocolTreeNode('message', {
            'to': jid,
            'type': 'chat'
        }, [composing])
        self.out.write(message)

    def sendPaused(self, jid):
        composing = ProtocolTreeNode(
            'paused', {'xmlns': 'http://jabber.org/protocol/chatstates'})
        message = ProtocolTreeNode('message', {
            'to': jid,
            'type': 'chat'
        }, [composing])
        self.out.write(message)

    def getSubjectMessage(
        self,
        to,
        msg_id,
        child,
    ):
        messageNode = ProtocolTreeNode('message', {
            'to': to,
            'type': 'subject',
            'id': msg_id
        }, [child])

        return messageNode

    def sendSubjectReceived(self, to, msg_id):
        receivedNode = ProtocolTreeNode('received',
                                        {'xmlns': 'urn:xmpp:receipts'})
        messageNode = self.getSubjectMessage(to, msg_id, receivedNode)
        self.out.write(messageNode)

    def sendMessageReceived(self, fmsg):
        receivedNode = ProtocolTreeNode('received',
                                        {'xmlns': 'urn:xmpp:receipts'})
        messageNode = ProtocolTreeNode('message', {
            'to': fmsg.remote,
            'type': 'chat',
            'id': fmsg.id
        }, [receivedNode])

        self.out.write(messageNode)

    def sendDeliveredReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, 'delivered'))

    def sendVisibleReceiptAck(self, to, msg_id):
        self.out.write(self.getReceiptAck(to, msg_id, 'visible'))

    def getReceiptAck(
        self,
        to,
        msg_id,
        receiptType,
    ):
        ackNode = ProtocolTreeNode('ack', {
            'xmlns': 'urn:xmpp:receipts',
            'type': receiptType
        })
        messageNode = ProtocolTreeNode('message', {
            'to': to,
            'type': 'chat',
            'id': msg_id
        }, [ackNode])
        return messageNode

    def makeId(self, prefix):
        self.iqId += 1
        idx = ''
        if self.verbose:
            idx += prefix + str(self.iqId)
        else:
            idx = '%x' % self.iqId

        return idx

    def sendPing(self):
        idx = self.makeId('ping_')
        self.stanzaReader.requests[idx] = \
            self.stanzaReader.handlePingResponse

        pingNode = ProtocolTreeNode('ping', {'xmlns': 'w:p'})
        iqNode = ProtocolTreeNode('iq', {
            'id': idx,
            'type': 'get',
            'to': self.domain
        }, [pingNode])
        self.out.write(iqNode)

    def sendPong(self, idx):
        iqNode = ProtocolTreeNode('iq', {
            'type': 'result',
            'to': self.domain,
            'id': idx
        })
        self.out.write(iqNode)

    def getLastOnline(self, jid):

        if len(jid.split('-')) == 2:
            return

        self.sendSubscribe(jid)

        idx = self.makeId('last_')
        self.stanzaReader.requests[idx] = \
            self.stanzaReader.handleLastOnline

        query = ProtocolTreeNode('query', {'xmlns': 'jabber:iq:last'})
        iqNode = ProtocolTreeNode('iq', {
            'id': idx,
            'type': 'get',
            'to': jid
        }, [query])
        self.out.write(iqNode)

    def sendIq(self):
        node = ProtocolTreeNode('iq', {
            'to': 'g.us',
            'type': 'get',
            'id': str(int(time.time())) + '-0'
        }, None, 'expired')
        self.out.write(node)

        node = ProtocolTreeNode(
            'iq', {
                'to': 's.whatsapp.net',
                'type': 'set',
                'id': str(int(time.time())) + '-1'
            }, None, 'expired')
        self.out.write(node)

    def leaveGroup(self, group):
        group_nodes = [ProtocolTreeNode('group', {'id': group})]
        node = ProtocolTreeNode('leave', {'xmlns': 'w:g'}, group_nodes)

        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': 'g.us'
        }, [node])

        self.out.write(node_out)

    def addParticipant(self, group, participant):
        self.addParticipants(group, [participant])

    def removeParticipant(self, group, participant):
        self.removeParticipants(group, [participant])

    def addParticipants(self, group, participants):
        self.sendVerbParticipants(group, participants, 'add')

    def removeParticipants(self, group, participants):
        self.sendVerbParticipants(group, participants, 'remove')

    def sendVerbParticipants(self, group, participants, verb):
        participant_nodes = map(
            lambda p: ProtocolTreeNode('participants', {'jid': p}),
            participants)

        node = ProtocolTreeNode(verb, {'xmlns': 'w:g'}, participant_nodes)
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': group
        }, [node])

        self.out.write(node_out)

    def setGroupSubject(self, group, subject):
        node = ProtocolTreeNode('subject', {'xmlns': 'w:g', 'value': subject})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'set',
            'to': group
        }, [node])

        self.out.write(node_out)

    def sendAvailableForChat(self):
        presenceNode = ProtocolTreeNode('presence', {'name': self.push_name})
        self.out.write(presenceNode)

    def sendAvailable(self):
        presenceNode = ProtocolTreeNode('presence', {'type': 'available'})
        self.out.write(presenceNode)

    def sendUnavailable(self):
        presenceNode = ProtocolTreeNode('presence', {'type': 'unavailable'})
        self.out.write(presenceNode)

    def sendSubscribe(self, to):
        presenceNode = ProtocolTreeNode('presence', {
            'type': 'subscribe',
            'to': to
        })

        self.out.write(presenceNode)

    def getGroups(self):
        self.sendGetGroups('participating')

    def getOwningGroups(self):
        self.sendGetGroups('owning')

    def getParticipants(self, group):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g'})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': group
        }, [node])

        self.out.write(node_out)

    def getServerProperties(self):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g', 'type': 'props'})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': 'g.us'
        }, [node])

        self.out.write(node_out)

    def sendGetGroups(self, group_type):
        node = ProtocolTreeNode('list', {'xmlns': 'w:g', 'type': group_type})
        node_out = ProtocolTreeNode('iq', {
            'id': str(int(time.time())) + '-0',
            'type': 'get',
            'to': 'g.us'
        }, [node])

        self.out.write(node_out)

    def sendMessage(self, fmsg):
        bodyNode = ProtocolTreeNode('body', None, None, fmsg.data)
        msgNode = self.getMessageNode(fmsg, bodyNode)

        self.out.write(msgNode)
        self.msg_id += 1

    def sendClientConfig(
        self,
        sound,
        pushID,
        preview,
        platform,
    ):
        idx = self.makeId('config_')
        configNode = ProtocolTreeNode(
            'config', {
                'xmlns': 'urn:xmpp:whatsapp:push',
                'sound': sound,
                'id': pushID,
                'preview': ('1' if preview else '0'),
                'platform': platform,
            })
        iqNode = ProtocolTreeNode('iq', {
            'id': idx,
            'type': 'set',
            'to': self.domain
        }, [configNode])

        self.out.write(iqNode)

    def getMessageNode(self, fmsg, child):
        requestNode = None
        serverNode = ProtocolTreeNode('server', None)
        xNode = ProtocolTreeNode('x', {'xmlns': 'jabber:x:event'},
                                 [serverNode])
        childCount = ((0 if requestNode is None else 1)) + 2
        messageChildren = [None] * childCount
        i = 0
        if requestNode is not None:
            messageChildren[i] = requestNode
            i += 1

        messageChildren[i] = xNode
        i += 1
        messageChildren[i] = child
        i += 1

        messageNode = ProtocolTreeNode('message', {
            'to': fmsg.remote,
            'type': 'chat',
            'id': fmsg.id
        }, messageChildren)

        return messageNode