예제 #1
0
	def sendBroadcast(self, jids, content):
		
		broadcastNode = ProtocolTreeNode("broadcast", None, [ProtocolTreeNode("to", {"jid": jid}) for jid in jids])
		
		messageNode = ProtocolTreeNode("body",None,None,content);
		
		return [broadcastNode, messageNode]
예제 #2
0
	def sendAddParticipants(self, gjid, participants):
		self._d("opening group: %s"%(gjid))
		self._d("adding participants: %s"%(participants))
		idx = self.makeId("add_group_participants_")
		self.readerThread.requests[idx] = self.readerThread.parseAddedParticipants;
		
		innerNodeChildren = []

		for part in participants:
			innerNodeChildren.append( ProtocolTreeNode("participant",{"jid":part}) )

		queryNode = ProtocolTreeNode("add",{"xmlns":"w:g"},innerNodeChildren)
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":gjid},[queryNode])

		self._writeNode(iqNode)

		def sendAddParticipant(self, gjid, participants):
			self._d("opening group: %s"%(gjid))
			self._d("adding participants: %s"%(participants))
			idx = self.makeId("add_group_participants_")
			self.readerThread.requests[idx] = self.readerThread.parseAddedParticipants;
			innerNodeChildren = []
			
			innerNodeChildren.append( ProtocolTreeNode("participant",{"jid":participants}) )
			
			queryNode = ProtocolTreeNode("add",{"xmlns":"w:g"},innerNodeChildren)
			iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":gjid},[queryNode])
			
			self._writeNode(iqNode)
예제 #3
0
	def sendGetParticipants(self,jid):
		idx = self.makeId("get_participants_")
		self.readerThread.requests[idx] = self.readerThread.parseParticipants

		listNode = ProtocolTreeNode("list",{"xmlns":"w:g"})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":jid},[listNode]);

		self._writeNode(iqNode)
예제 #4
0
	def sendCreateGroupChat(self,subject):
		self._d("creating group: %s"%(subject))
		idx = self.makeId("create_group_")
		self.readerThread.requests[idx] = self.readerThread.parseGroupCreated;

		queryNode = ProtocolTreeNode("group",{"xmlns":"w:g","action":"create","subject":subject})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":"g.us"},[queryNode])

		self._writeNode(iqNode)
예제 #5
0
	def sendGetGroupInfo(self,jid):
		self._d("getting group info for %s"%(jid))
		idx = self.makeId("get_g_info_")
		self.readerThread.requests[idx] = self.readerThread.parseGroupInfo;

		queryNode = ProtocolTreeNode("query",{"xmlns":"w:g"})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":jid},[queryNode])

		self._writeNode(iqNode)
예제 #6
0
	def sendGetGroups(self,gtype):
		self._d("getting groups %s"%(gtype))
		idx = self.makeId("get_groups_")
		self.readerThread.requests[idx] = self.readerThread.parseGroups;

		queryNode = ProtocolTreeNode("list",{"xmlns":"w:g","type":gtype})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":"g.us"},[queryNode])

		self._writeNode(iqNode)
예제 #7
0
	def sendSetGroupSubject(self,gjid,subject):
		#subject = subject.encode('utf-8')
		#self._d("setting group subject of " + gjid + " to " + subject)
		idx = self.makeId("set_group_subject_")
		self.readerThread.requests[idx] = self.readerThread.parseGroupSubject

		queryNode = ProtocolTreeNode("subject",{"xmlns":"w:g","value":subject})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":gjid},[queryNode]);

		self._writeNode(iqNode)
예제 #8
0
	def sendPing(self):

		idx = self.makeId("ping_")

		self.readerThread.requests[idx] = self.readerThread.parsePingResponse;

		pingNode = ProtocolTreeNode("ping",{"xmlns":"w:p"});
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":self.domain},[pingNode]);
		self._writeNode(iqNode);
		return idx
예제 #9
0
	def sendGetPicture(self,jid):
		self._d("GETTING PICTURE FROM " + jid)
		idx = self.makeId("get_picture_")

		#@@TODO, ?!
		self.readerThread.requests[idx] =  self.readerThread.parseGetPicture

		listNode = ProtocolTreeNode("picture",{"xmlns":"w:profile:picture","type":"image"})
		iqNode = ProtocolTreeNode("iq",{"id":idx,"to":jid,"type":"get"},[listNode]);

		self._writeNode(iqNode)
예제 #10
0
	def sendGetPictureIds(self,jids):
		idx = self.makeId("get_picture_ids_")
		self.readerThread.requests[idx] = self.readerThread.parseGetPictureIds

		innerNodeChildren = []
		for jid in jids:
			innerNodeChildren.append( ProtocolTreeNode("user",{"jid": jid}) )

		queryNode = ProtocolTreeNode("list",{"xmlns":"w:profile:picture"},innerNodeChildren)
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get"},[queryNode])

		self._writeNode(iqNode)
예제 #11
0
	def parseGroupCreated(self,node):
		jid = node.getAttributeValue("from");
		groupNode = node.getChild(0)
		
		if ProtocolTreeNode.tagEquals(groupNode,"error"):
			errorCode = groupNode.getAttributeValue("code")
			self.signalInterface.send("group_createFail", (errorCode,))
			return

		ProtocolTreeNode.require(groupNode,"group")
		group_id = groupNode.getAttributeValue("id")
		self.signalInterface.send("group_createSuccess", (group_id + "@g.us",))
예제 #12
0
	def parseGroupCreated(self,node):
		jid = node.getAttributeValue("from");
		groupNode = node.getChild(0)
		
		if ProtocolTreeNode.tagEquals(groupNode,"error"):
			errorCode = groupNode.getAttributeValue("code")
			self.signalInterface.send("group_createFail", (errorCode,))
			return

		ProtocolTreeNode.require(groupNode,"group")
		group_id = groupNode.getAttributeValue("id")
		self.signalInterface.send("group_createSuccess", (group_id + "@g.us",))
예제 #13
0
	def sendEndGroupChat(self,gjid):
		self._d("removing group: %s"%(gjid))
		idx = self.makeId("leave_group_")
		self.readerThread.requests[idx] = self.readerThread.parseGroupEnded;

		innerNodeChildren = []
		innerNodeChildren.append( ProtocolTreeNode("group",{"id":gjid}) )

		queryNode = ProtocolTreeNode("leave",{"xmlns":"w:g"},innerNodeChildren)
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"set","to":"g.us"},[queryNode])

		self._writeNode(iqNode)
예제 #14
0
파일: wauth.py 프로젝트: yunsiong/yowsup
    def readSuccess(self):
        node = self.conn.reader.nextTree()
        self._d("Login Status: %s" % (node.tag))

        if ProtocolTreeNode.tagEquals(node, "failure"):
            self.authObject.authenticationFailed()
            return 0
            #raise Exception("Login Failure");

        ProtocolTreeNode.require(node, "success")

        expiration = node.getAttributeValue("expiration")

        if expiration is not None:
            self._d("Expires: " + str(expiration))
            self.authObject.expireDate = expiration

        kind = node.getAttributeValue("kind")
        self._d("Account type: %s" % (kind))

        if kind == "paid":
            self.authObject.accountKind = 1
        elif kind == "free":
            self.authObject.accountKind = 0
        else:
            self.authObject.accountKind = -1

        status = node.getAttributeValue("status")
        self._d("Account status: %s" % (status))

        if status == "expired":
            self.loginFailed.emit()
            raise Exception("Account expired on " +
                            str(self.authObject.expireDate))

        if status == "active":
            if expiration is None:
                #raise Exception ("active account with no expiration");
                '''@@TODO expiration changed to creation'''
        else:
            self.authObject.accountKind = 1

        self.conn.reader.inn.buf = []

        nextChallenge = node.data
        f = open("/home/user/.wazapp/challenge", "wb")
        f.write(nextChallenge)
        f.close()

        self.conn.writer.outputKey = self.outputKey
        self.authObject.authenticationComplete()
        return 1
예제 #15
0
	def readSuccess(self):
		node = self.conn.reader.nextTree();
		self._d("Login Status: %s"%(node.tag));

		if ProtocolTreeNode.tagEquals(node,"failure"):
			self.authObject.authenticationFailed()
			return 0
			#raise Exception("Login Failure");

		ProtocolTreeNode.require(node,"success");

		expiration = node.getAttributeValue("expiration");

		if expiration is not None:
			self._d("Expires: "+str(expiration));
			self.authObject.expireDate = expiration;

		kind = node.getAttributeValue("kind");
		self._d("Account type: %s"%(kind))

		if kind == "paid":
			self.authObject.accountKind = 1;
		elif kind == "free":
			self.authObject.accountKind = 0;
		else:
			self.authObject.accountKind = -1;

		status = node.getAttributeValue("status");
		self._d("Account status: %s"%(status));

		if status == "expired":
			self.loginFailed.emit()
			raise Exception("Account expired on "+str(self.authObject.expireDate));

		if status == "active":
			if expiration is None:
				#raise Exception ("active account with no expiration");
				'''@@TODO expiration changed to creation'''
		else:
			self.authObject.accountKind = 1;

		self.conn.reader.inn.buf = [];

		nextChallenge = node.data;
		f = open("/home/user/.wazapp/challenge", "wb")
		f.write(nextChallenge)
		f.close()

		self.conn.writer.outputKey = self.outputKey
		self.authObject.authenticationComplete()
		return 1
예제 #16
0
	def getLastOnline(self,jid):

		if len(jid.split('-')) == 2 or jid == "*****@*****.**": #SUPER CANCEL SUBSCRIBE TO GROUP AND SERVER
			return

		self.sendSubscribe(jid);

		self._d("presence request Initiated for %s"%(jid))
		idx = self.makeId("last_")
		self.readerThread.requests[idx] = self.readerThread.parseLastOnline;

		query = ProtocolTreeNode("query",{"xmlns":"jabber:iq:last"});
		iqNode = ProtocolTreeNode("iq",{"id":idx,"type":"get","to":jid},[query]);
		self._writeNode(iqNode)
예제 #17
0
	def parseGroupInfo(self,node):
		jid = node.getAttributeValue("from");
		groupNode = node.getChild(0)
		if "error code" in groupNode.toString():
			self.signalInterface.send("group_infoError",(0,)) #@@TODO replace with real error code
		else:
			ProtocolTreeNode.require(groupNode,"group")
			#gid = groupNode.getAttributeValue("id")
			owner = groupNode.getAttributeValue("owner")
			subject = groupNode.getAttributeValue("subject") if sys.version_info < (3, 0) else groupNode.getAttributeValue("subject").encode('latin-1').decode();
			subjectT = groupNode.getAttributeValue("s_t")
			subjectOwner = groupNode.getAttributeValue("s_o")
			creation = groupNode.getAttributeValue("creation")
		
			self.signalInterface.send("group_gotInfo",(jid, owner, subject, subjectOwner, int(subjectT),int(creation)))
예제 #18
0
	def sendSetPicture(self, jid, imagePath):

		f = open(imagePath, 'rb')
		imageData = f.read()
		imageData = bytearray(imageData)
		f.close()
		
		idx = self.makeId("set_picture_")
		self.readerThread.requests[idx] = self.readerThread.parseSetPicture

		listNode = ProtocolTreeNode("picture",{"xmlns":"w:profile:picture","type":"image"}, None, imageData)

		iqNode = ProtocolTreeNode("iq",{"id":idx,"to":jid,"type":"set"},[listNode])

		self._writeNode(iqNode)
예제 #19
0
	def parseGroupInfo(self,node):
		jid = node.getAttributeValue("from");
		groupNode = node.getChild(0)
		if "error code" in groupNode.toString():
			self.signalInterface.send("group_infoError",(0,)) #@@TODO replace with real error code
		else:
			ProtocolTreeNode.require(groupNode,"group")
			#gid = groupNode.getAttributeValue("id")
			owner = groupNode.getAttributeValue("owner")
			subject = groupNode.getAttributeValue("subject") if sys.version_info < (3, 0) else groupNode.getAttributeValue("subject").encode('latin-1').decode();
			subjectT = groupNode.getAttributeValue("s_t")
			subjectOwner = groupNode.getAttributeValue("s_o")
			creation = groupNode.getAttributeValue("creation")
		
			self.signalInterface.send("group_gotInfo",(jid, owner, subject, subjectOwner, int(subjectT),int(creation)))
예제 #20
0
파일: wauth.py 프로젝트: SikiFn/yowsup
	def readFeaturesAndChallenge(self):
		root = self.conn.reader.nextTree();

		while root is not None:
			if ProtocolTreeNode.tagEquals(root,"stream:features"):
				self._d("GOT FEATURES !!!!");
				self.authObject.supportsReceiptAcks  = root.getChild("receipt_acks") is not None;
				root = self.conn.reader.nextTree();

				continue;

			if ProtocolTreeNode.tagEquals(root,"challenge"):
				self._d("GOT CHALLENGE !!!!");
				#data = base64.b64decode(root.data);
				return root.data;
		raise Exception("fell out of loop in readFeaturesAndChallenge");
예제 #21
0
	def parseLastOnline(self,node):
		jid = node.getAttributeValue("from");
		firstChild = node.getChild(0);

		if "error" in firstChild.toString():
			return

		ProtocolTreeNode.require(firstChild,"query");
		seconds = firstChild.getAttributeValue("seconds");
		status = None
		status = firstChild.data #@@TODO discarded?

		try:
			if seconds is not None and jid is not None:
				self.signalInterface.send("presence_updated", (jid, int(seconds)))
		except:
			self._d("Ignored exception in handleLastOnline "+ sys.exc_info()[1])
예제 #22
0
    def sendResponse(self, challengeData):

        authBlob = self.getAuthBlob(challengeData)
        node = ProtocolTreeNode("response",
                                {"xmlns": "urn:ietf:params:xml:ns:xmpp-sasl"},
                                None, authBlob)
        self.conn.writer.write(node)
        self.conn.reader.inn.buf = []
예제 #23
0
	def parseLastOnline(self,node):
		jid = node.getAttributeValue("from");
		firstChild = node.getChild(0);

		if "error" in firstChild.toString():
			return

		ProtocolTreeNode.require(firstChild,"query");
		seconds = firstChild.getAttributeValue("seconds");
		status = None
		status = firstChild.data #@@TODO discarded?

		try:
			if seconds is not None and jid is not None:
				self.signalInterface.send("presence_updated", (jid, int(seconds)))
		except:
			self._d("Ignored exception in handleLastOnline "+ sys.exc_info()[1])
예제 #24
0
	def sendChangeStatus(self,status):
		self._d("updating status to: %s"%(status))
		
		bodyNode = ProtocolTreeNode("body",None,None,status);
		messageNode = self.getMessageNode("s.us",bodyNode)
		self._writeNode(messageNode);
		
		return messageNode.getAttributeValue("id")
예제 #25
0
    def readFeaturesAndChallenge(self):
        root = self.conn.reader.nextTree()

        while root is not None:
            if ProtocolTreeNode.tagEquals(root, "stream:features"):
                self._d("GOT FEATURES !!!!")
                self.authObject.supportsReceiptAcks = root.getChild(
                    "receipt_acks") is not None
                root = self.conn.reader.nextTree()

                continue

            if ProtocolTreeNode.tagEquals(root, "challenge"):
                self._d("GOT CHALLENGE !!!!")
                #data = base64.b64decode(root.data);
                return root.data
        raise Exception("fell out of loop in readFeaturesAndChallenge")
예제 #26
0
	def sendRequestUpload(self, b64Hash, t, size, b64OrigHash = None):
		idx = self.makeId("upload_")
		
		self.readerThread.requests[idx] = lambda iqresnode: self.readerThread.parseRequestUpload(iqresnode, b64Hash)

		if type(size) is not str:
			size = str(size)

		attribs = {"xmlns":"w:m","hash":b64Hash, "type":t, "size":size}

		if b64OrigHash:
			attribs["orighash"] = b64OrigHash

		mediaNode = ProtocolTreeNode("media", attribs)
		iqNode = ProtocolTreeNode("iq",{"id":idx,"to":"s.whatsapp.net","type":"set"},[mediaNode])
		
		
		self._writeNode(iqNode)
예제 #27
0
파일: wauth.py 프로젝트: yunsiong/yowsup
 def sendAuth(self):
     # "user":self.connection.user,
     blob = self.createAuthBlob()
     node = ProtocolTreeNode(
         "auth", {
             "user": self.username,
             "xmlns": "urn:ietf:params:xml:ns:xmpp-sasl",
             "mechanism": "WAUTH-1"
         }, None, blob)
     self.conn.writer.write(node)
예제 #28
0
 def sendAuth(self):
     # "user":self.connection.user,
     blob = []
     node = ProtocolTreeNode("auth", {
         "passive": "false",
         "mechanism": "WAUTH-2",
         "user": self.username
     })
     #node = ProtocolTreeNode("auth",{"user":self.username,"xmlns":"urn:ietf:params:xml:ns:xmpp-sasl","mechanism":"WAUTH-1"}, None, ''.join(map(chr, blob)));
     self.conn.writer.write(node)
예제 #29
0
		def wrapped(self, *args):
				mediaType = fn(self, *args)
				
				
				url = args[1]
				name = args[2]
				size = args[3]
				
				mmNode = ProtocolTreeNode("media", {"xmlns":"urn:xmpp:whatsapp:mms","type":mediaType,"file":name,"size":size,"url":url},None, args[4:][0] if args[4:] else None);
				return mmNode
예제 #30
0
	def getMessageNode(self, jid, 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;
			if requestNode is not None:
				messageChildren.append(requestNode);
			#System.currentTimeMillis() / 1000L + "-"+1
			messageChildren.append(xNode)
			
			if type(child) == list:
				messageChildren.extend(child)
			else:
				messageChildren.append(child)
				
			msgId = str(int(time.time()))+"-"+ str(self.currKeyId)
			
			messageNode = ProtocolTreeNode("message",{"to":jid,"type":"chat","id":msgId},messageChildren)
			
			self.currKeyId += 1


			return messageNode;
예제 #31
0
파일: wauth.py 프로젝트: yunsiong/yowsup
    def sendFeatures(self):
        toWrite = ProtocolTreeNode("stream:features", None, [
            ProtocolTreeNode("receipt_acks", None, None),
            ProtocolTreeNode("w:profile:picture", {"type": "all"}, None),
            ProtocolTreeNode("w:profile:picture", {"type": "group"}, None),
            ProtocolTreeNode("notification", {"type": "participant"}, None),
            ProtocolTreeNode("status", None, None)
        ])

        self.conn.writer.write(toWrite)
예제 #32
0
    def sendFeatures(self):
        toWrite = ProtocolTreeNode("stream:features", None)

        self.conn.writer.write(toWrite)
예제 #33
0
	def sendVCard(self, jid, data, name):
		
		cardNode = ProtocolTreeNode("vcard",{"name":name},None,data);
		return ProtocolTreeNode("media", {"xmlns":"urn:xmpp:whatsapp:mms","type":"vcard"},[cardNode])
예제 #34
0
	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._writeNode(iqNode);
예제 #35
0
	def run(self):
		self._d("Read thread startedX");
		while True:

			
			countdown = self.timeout - ((int(time.time()) - self.lastPongTime))
			
			remainder = countdown % self.selectTimeout
			countdown = countdown - remainder
					
			if countdown <= 0:
				self._d("No hope, dying!")
				self.sendDisconnected("closed")
				return
			else:
				if countdown % (self.selectTimeout*10) == 0 or countdown < 11:
					self._d("Waiting, time to die: T-%i seconds" % countdown )
					
				if self.timeout-countdown == 150 and self.ping and self.autoPong:
					self.ping()

				self.selectTimeout = 1 if countdown < 11 else 3


			try:
				ready = select.select([self.socket.reader.rawIn], [], [], self.selectTimeout)
			except:
				self._d("Error in ready")
				raise
				return
			
			if self.terminateRequested:
				return

			if ready[0]:
				try:
					node = self.socket.reader.nextTree()
				except ConnectionClosedException:
					#print traceback.format_exc()
					self._d("Socket closed, got 0 bytes!")
					#self.signalInterface.send("disconnected", ("closed",))
					self.sendDisconnected("closed")
					return

				self.lastPongTime = int(time.time());

				if node is not None:
					if ProtocolTreeNode.tagEquals(node,"iq"):
						iqType = node.getAttributeValue("type")
						idx = node.getAttributeValue("id")

						if iqType is None:
							raise Exception("iq doesn't have type")

						if iqType == "result":
							if idx in self.requests:
								self.requests[idx](node)
								del self.requests[idx]
							elif idx.startswith(self.connection.user):
								accountNode = node.getChild(0)
								ProtocolTreeNode.require(accountNode,"account")
								kind = accountNode.getAttributeValue("kind")

								if kind == "paid":
									self.connection.account_kind = 1
								elif kind == "free":
									self.connection.account_kind = 0
								else:
									self.connection.account_kind = -1

								expiration = accountNode.getAttributeValue("expiration")

								if expiration is None:
									raise Exception("no expiration")

								try:
									self.connection.expire_date = long(expiration)
								except ValueError:
									raise IOError("invalid expire date %s"%(expiration))

								self.eventHandler.onAccountChanged(self.connection.account_kind,self.connection.expire_date)
						elif iqType == "error":
							if idx in self.requests:
								self.requests[idx](node)
								del self.requests[idx]
						elif iqType == "get":
							childNode = node.getChild(0)
							if ProtocolTreeNode.tagEquals(childNode,"ping"):
								if self.autoPong:
									self.onPing(idx)
									
								self.signalInterface.send("ping", (idx,))	
							elif ProtocolTreeNode.tagEquals(childNode,"query") and node.getAttributeValue("from") is not None and "http://jabber.org/protocol/disco#info" == childNode.getAttributeValue("xmlns"):
								pin = childNode.getAttributeValue("pin");
								timeoutString = childNode.getAttributeValue("timeout");
								try:
									timeoutSeconds = int(timeoutString) if timeoutString is not None else None
								except ValueError:
									raise Exception("relay-iq exception parsing timeout %s "%(timeoutString))

								if pin is not None:
									self.eventHandler.onRelayRequest(pin,timeoutSeconds,idx)
						elif iqType == "set":
							childNode = node.getChild(0)
							if ProtocolTreeNode.tagEquals(childNode,"query"):
								xmlns = childNode.getAttributeValue("xmlns")

								if xmlns == "jabber:iq:roster":
									itemNodes = childNode.getAllChildren("item");
									ask = ""
									for itemNode in itemNodes:
										jid = itemNode.getAttributeValue("jid")
										subscription = itemNode.getAttributeValue("subscription")
										ask = itemNode.getAttributeValue("ask")
						else:
							raise Exception("Unkown iq type %s"%(iqType))

					elif ProtocolTreeNode.tagEquals(node,"presence"):
						xmlns = node.getAttributeValue("xmlns")
						jid = node.getAttributeValue("from")

						if (xmlns is None or xmlns == "urn:xmpp") and jid is not None:
							presenceType = node.getAttributeValue("type")
							if presenceType == "unavailable":
								self.signalInterface.send("presence_unavailable", (jid,))
							elif presenceType is None or presenceType == "available":
								self.signalInterface.send("presence_available", (jid,))

						elif xmlns == "w" and jid is not None:
							status = node.getAttributeValue("status")

							if status == "dirty":
								#categories = self.parseCategories(node); #@@TODO, send along with signal
								self._d("WILL SEND DIRTY")
								self.signalInterface.send("status_dirty")
								self._d("SENT DIRTY")

					elif ProtocolTreeNode.tagEquals(node,"message"):
						self.parseMessage(node)
					

		self._d("Reader thread terminating now!")
예제 #36
0
	def parseMessage(self,messageNode):


		bodyNode = messageNode.getChild("body");
#		offlineNode = messageNode.getChild("offline")

		
		newSubject = "" if bodyNode is None else bodyNode.data;
		msgData = None
#		timestamp =long(time.time()*1000) if not offlineNode else int(messageNode.getAttributeValue("t"))*1000;
		timestamp =int(messageNode.getAttributeValue("t"))
		isGroup = False
		isBroadcast = False
		
		if newSubject.find("New version of WhatsApp Messenger is now available")>-1:
			self._d("Rejecting whatsapp server message")
			return #REJECT THIS F*****G MESSAGE!


		fromAttribute = messageNode.getAttributeValue("from");

		try:
			fromAttribute.index('-')
			isGroup = True
		except:
			pass

		author = messageNode.getAttributeValue("author");
		#@@TODO reactivate blocked contacts check from client
		'''if fromAttribute is not None and fromAttribute in self.eventHandler.blockedContacts:
			self._d("CONTACT BLOCKED!")
			return

		if author is not None and author in self.eventHandler.blockedContacts:
			self._d("CONTACT BLOCKED!")
			return
		'''

		pushName = None
		notifNode = messageNode.getChild("notify")
		if notifNode is not None:
			pushName = notifNode.getAttributeValue("name");
			#pushName = pushName.decode("utf8")


		msgId = messageNode.getAttributeValue("id");
		attribute_t = messageNode.getAttributeValue("t");

		typeAttribute = messageNode.getAttributeValue("type");

		if typeAttribute == "error":
			errorCode = 0;
			errorNodes = messageNode.getAllChildren("error");
			for errorNode in errorNodes:
				codeString = errorNode.getAttributeValue("code")
				try:
					errorCode = int(codeString);
				except ValueError:
					'''catch value error'''
				self.signalInterface.send("message_error", (msgId, fromAttribute, errorCode))

		elif typeAttribute == "notification":

			receiptRequested = False;
			pictureUpdated = None

			pictureUpdated = messageNode.getChild("notification").getAttributeValue("type");

			wr = None
			wr = messageNode.getChild("request").getAttributeValue("xmlns");
			if wr == "urn:xmpp:receipts":
				receiptRequested = True
				
			if pictureUpdated == "picture":
				notifNode = messageNode.getChild("notification");
				#bodyNode = messageNode.getChild("notification").getChild("set") or messageNode.getChild("notification").getChild("delete")

				bodyNode = notifNode.getChild("set")
				
				if bodyNode:
					pictureId = int(bodyNode.getAttributeValue("id"))
					if isGroup:
						self.signalInterface.send("notification_groupPictureUpdated",(bodyNode.getAttributeValue("jid"), bodyNode.getAttributeValue("author"), timestamp, msgId, pictureId, receiptRequested))
					else:
						self.signalInterface.send("notification_contactProfilePictureUpdated",(bodyNode.getAttributeValue("jid"), timestamp, msgId, pictureId, receiptRequested))

				else:
					bodyNode = notifNode.getChild("delete")

					if bodyNode:
						if isGroup:
							self.signalInterface.send("notification_groupPictureRemoved",(bodyNode.getAttributeValue("jid"), bodyNode.getAttributeValue("author"), timestamp, msgId, receiptRequested))
						else:
							self.signalInterface.send("notification_contactProfilePictureRemoved",(bodyNode.getAttributeValue("jid"), timestamp, msgId, receiptRequested))

				#if isGroup:
				#	
				#	self.signalInterface.send("notification_groupPictureUpdated",(bodyNode.getAttributeValue("jid"), bodyNode.getAttributeValue("author"), timestamp, msgId, receiptRequested))
				#else:
				#	self.signalInterface.send("notification_contactProfilePictureUpdated",(bodyNode.getAttributeValue("jid"), timestamp, msgId, receiptRequested))

			else:
				addSubject = None
				removeSubject = None
				author = None

				bodyNode = messageNode.getChild("notification").getChild("add");
				if bodyNode is not None:
					addSubject = bodyNode.getAttributeValue("jid");
					author = bodyNode.getAttributeValue("author") or addSubject

				bodyNode = messageNode.getChild("notification").getChild("remove");
				if bodyNode is not None:
					removeSubject = bodyNode.getAttributeValue("jid");
					author = bodyNode.getAttributeValue("author") or removeSubject

				if addSubject is not None:
					
					self.signalInterface.send("notification_groupParticipantAdded", (fromAttribute, addSubject, author, timestamp, msgId, receiptRequested))
					
				if removeSubject is not None:
					self.signalInterface.send("notification_groupParticipantRemoved", (fromAttribute, removeSubject, author, timestamp, msgId, receiptRequested))


		elif typeAttribute == "subject":
			receiptRequested = False;
			requestNodes = messageNode.getAllChildren("request");
			for requestNode in requestNodes:
				if requestNode.getAttributeValue("xmlns") == "urn:xmpp:receipts":
					receiptRequested = True;

			bodyNode = messageNode.getChild("body");
			newSubject = None if bodyNode is None else (bodyNode.data if sys.version_info < (3, 0) else bodyNode.data.encode('latin-1').decode());
			
			if newSubject is not None:
				self.signalInterface.send("group_subjectReceived",(msgId, fromAttribute, author, newSubject, int(attribute_t),  receiptRequested))

		elif typeAttribute == "chat":
			wantsReceipt = False;
			messageChildren = [] if messageNode.children is None else messageNode.children

			for childNode in messageChildren:
				if ProtocolTreeNode.tagEquals(childNode,"request"):
					wantsReceipt = True;
				
				if ProtocolTreeNode.tagEquals(childNode,"broadcast"):
					isBroadcast = True
				elif ProtocolTreeNode.tagEquals(childNode,"composing"):
						self.signalInterface.send("contact_typing", (fromAttribute,))
				elif ProtocolTreeNode.tagEquals(childNode,"paused"):
						self.signalInterface.send("contact_paused",(fromAttribute,))

				elif ProtocolTreeNode.tagEquals(childNode,"media") and msgId is not None:
	
					self._d("MULTIMEDIA MESSAGE!");
					
					mediaUrl = messageNode.getChild("media").getAttributeValue("url");
					mediaType = messageNode.getChild("media").getAttributeValue("type")
					mediaSize = messageNode.getChild("media").getAttributeValue("size")
					encoding = messageNode.getChild("media").getAttributeValue("encoding")
					mediaPreview = None


					if mediaType == "image":
						mediaPreview = messageNode.getChild("media").data
						
						if encoding == "raw" and mediaPreview:
							mediaPreview = base64.b64encode(mediaPreview) if sys.version_info < (3, 0) else base64.b64encode(mediaPreview.encode('latin-1')).decode()

						if isGroup:
							self.signalInterface.send("group_imageReceived", (msgId, fromAttribute, author, mediaPreview, mediaUrl, mediaSize, wantsReceipt))
						else:
							self.signalInterface.send("image_received", (msgId, fromAttribute, mediaPreview, mediaUrl, mediaSize,  wantsReceipt, isBroadcast))

					elif mediaType == "video":
						mediaPreview = messageNode.getChild("media").data
						
						if encoding == "raw" and mediaPreview:
							mediaPreview = base64.b64encode(mediaPreview) if sys.version_info < (3, 0) else base64.b64encode(mediaPreview.encode('latin-1')).decode()

						if isGroup:
							self.signalInterface.send("group_videoReceived", (msgId, fromAttribute, author, mediaPreview, mediaUrl, mediaSize, wantsReceipt))
						else:
							self.signalInterface.send("video_received", (msgId, fromAttribute, mediaPreview, mediaUrl, mediaSize, wantsReceipt, isBroadcast))

					elif mediaType == "audio":
						mediaPreview = messageNode.getChild("media").data

						if isGroup:
							self.signalInterface.send("group_audioReceived", (msgId, fromAttribute, author, mediaUrl, mediaSize, wantsReceipt))
						else:
							self.signalInterface.send("audio_received", (msgId, fromAttribute, mediaUrl, mediaSize, wantsReceipt, isBroadcast))

					elif mediaType == "location":
						mlatitude = messageNode.getChild("media").getAttributeValue("latitude")
						mlongitude = messageNode.getChild("media").getAttributeValue("longitude")
						name = messageNode.getChild("media").getAttributeValue("name")
						
						if name and not sys.version_info < (3, 0):
							name = name.encode('latin-1').decode()
						
						mediaPreview = messageNode.getChild("media").data
						
						if encoding == "raw" and mediaPreview:
							mediaPreview = base64.b64encode(mediaPreview) if sys.version_info < (3, 0) else base64.b64encode(mediaPreview.encode('latin-1')).decode()

						if isGroup:
							self.signalInterface.send("group_locationReceived", (msgId, fromAttribute, author, name or "", mediaPreview, mlatitude, mlongitude, wantsReceipt))
						else:
							self.signalInterface.send("location_received", (msgId, fromAttribute, name or "", mediaPreview, mlatitude, mlongitude, wantsReceipt, isBroadcast))
		
					elif mediaType =="vcard":
						#return
						#mediaItem.preview = messageNode.getChild("media").data
						vcardData = messageNode.getChild("media").getChild("vcard").toString()
						vcardName = messageNode.getChild("media").getChild("vcard").getAttributeValue("name")
						
						if vcardName and not sys.version_info < (3, 0):
							vcardName = vcardName.encode('latin-1').decode()
						
						if vcardData is not None:
							n = vcardData.find(">") +1
							vcardData = vcardData[n:]
							vcardData = vcardData.replace("</vcard>","")

							if isGroup:
								self.signalInterface.send("group_vcardReceived", (msgId, fromAttribute, author, vcardName, vcardData, wantsReceipt))
							else:
								self.signalInterface.send("vcard_received", (msgId, fromAttribute, vcardName, vcardData, wantsReceipt, isBroadcast))
							
					else:
						self._d("Unknown media type")
						return

				elif ProtocolTreeNode.tagEquals(childNode,"body") and msgId is not None:
					msgData = childNode.data;
					
					#fmsg.setData({"status":0,"key":key.toString(),"content":msgdata,"type":WAXMPP.message_store.store.Message.TYPE_RECEIVED});

				elif ProtocolTreeNode.tagEquals(childNode,"received") and fromAttribute is not None and msgId is not None:

					if fromAttribute == "s.us":
						self.signalInterface.send("profile_setStatusSuccess", ("s.us", msgId,))
						return;

					#@@TODO autosend ack from client
					#print "NEW MESSAGE RECEIVED NOTIFICATION!!!"
					#self.connection.sendDeliveredReceiptAck(fromAttribute,msg_id);
					self.signalInterface.send("receipt_messageDelivered", (fromAttribute, msgId))
					
					return


				elif not (ProtocolTreeNode.tagEquals(childNode,"active")):
					if ProtocolTreeNode.tagEquals(childNode,"request"):
						wantsReceipt = True;

					elif ProtocolTreeNode.tagEquals(childNode,"notify"):
						notify_name = childNode.getAttributeValue("name");


					elif ProtocolTreeNode.tagEquals(childNode,"delay"):
						xmlns = childNode.getAttributeValue("xmlns");
						if "urn:xmpp:delay" == xmlns:
							stamp_str = childNode.getAttributeValue("stamp");
							if stamp_str is not None:
								stamp = stamp_str
								timestamp = self.parseOfflineMessageStamp(stamp)*1000;

					elif ProtocolTreeNode.tagEquals(childNode,"x"):
						xmlns = childNode.getAttributeValue("xmlns");
						if "jabber:x:event" == xmlns and msgId is not None:
							
							if fromAttribute == "broadcast":
								self.signalInterface.send("receipt_broadcastSent", (msgId,))
							else:
								self.signalInterface.send("receipt_messageSent", (fromAttribute, msgId))

						elif "jabber:x:delay" == xmlns:
							continue; #@@TODO FORCED CONTINUE, WHAT SHOULD I DO HERE? #wtf?
							stamp_str = childNode.getAttributeValue("stamp");
							if stamp_str is not None:
								stamp = stamp_str
								timestamp = stamp;
					else:
						if ProtocolTreeNode.tagEquals(childNode,"delay") or not ProtocolTreeNode.tagEquals(childNode,"received") or msgId is None:
							continue;

							
							receipt_type = childNode.getAttributeValue("type");
							if receipt_type is None or receipt_type == "delivered":
								self.signalInterface.send("receipt_messageDelivered", (fromAttribute, msgId))
							elif receipt_type == "visible":
								self.signalInterface.send("receipt_visible", (fromAttribute, msgId))
							




			if msgData:
				msgData = msgData if sys.version_info < (3, 0) else msgData.encode('latin-1').decode()
				if isGroup:
					self.signalInterface.send("group_messageReceived", (msgId, fromAttribute, author, msgData, timestamp, wantsReceipt, pushName))

				else:
					self.signalInterface.send("message_received", (msgId, fromAttribute, msgData, timestamp, wantsReceipt, pushName, isBroadcast))

				##@@TODO FROM CLIENT
				'''if conversation.type == "group":
					if conversation.subject is None:
						signal = False
						self._d("GETTING GROUP INFO")
						self.connection.sendGetGroupInfo(fromAttribute)
				'''
					#if not len(conversation.getContacts()):
					#	self._d("GETTING GROUP CONTACTS")
					#	self.connection.sendGetParticipants(fromAttribute)

				'''@@TODO FROM CLIENT
예제 #37
0
	def run(self):
		self._d("Read thread startedX");
		while True:

			
			countdown = self.timeout - ((int(time.time()) - self.lastPongTime))
			
			remainder = countdown % self.selectTimeout
			countdown = countdown - remainder
					
			if countdown <= 0:
				self._d("No hope, dying!")
				self.sendDisconnected("closed")
				return
			else:
				if countdown % (self.selectTimeout*10) == 0 or countdown < 11:
					self._d("Waiting, time to die: T-%i seconds" % countdown )
					
				if self.timeout-countdown == 150 and self.ping and self.autoPong:
					self.ping()

				self.selectTimeout = 1 if countdown < 11 else 3


			try:
				ready = select.select([self.socket.reader.rawIn], [], [], self.selectTimeout)
			except:
				self._d("Error in ready")
				raise
				return
			
			if self.terminateRequested:
				return

			if ready[0]:
				try:
					node = self.socket.reader.nextTree()
				except ConnectionClosedException:
					#print traceback.format_exc()
					self._d("Socket closed, got 0 bytes!")
					#self.signalInterface.send("disconnected", ("closed",))
					self.sendDisconnected("closed")
					return

				self.lastPongTime = int(time.time());

				if node is not None:
					if ProtocolTreeNode.tagEquals(node,"iq"):
						iqType = node.getAttributeValue("type")
						idx = node.getAttributeValue("id")

						if iqType is None:
							raise Exception("iq doesn't have type")

						if iqType == "result":
							if idx in self.requests:
								self.requests[idx](node)
								del self.requests[idx]
							elif idx.startswith(self.connection.user):
								accountNode = node.getChild(0)
								ProtocolTreeNode.require(accountNode,"account")
								kind = accountNode.getAttributeValue("kind")

								if kind == "paid":
									self.connection.account_kind = 1
								elif kind == "free":
									self.connection.account_kind = 0
								else:
									self.connection.account_kind = -1

								expiration = accountNode.getAttributeValue("expiration")

								if expiration is None:
									raise Exception("no expiration")

								try:
									self.connection.expire_date = long(expiration)
								except ValueError:
									raise IOError("invalid expire date %s"%(expiration))

								self.eventHandler.onAccountChanged(self.connection.account_kind,self.connection.expire_date)
						elif iqType == "error":
							if idx in self.requests:
								self.requests[idx](node)
								del self.requests[idx]
						elif iqType == "get":
							childNode = node.getChild(0)
							if ProtocolTreeNode.tagEquals(childNode,"ping"):
								if self.autoPong:
									self.onPing(idx)
									
								self.signalInterface.send("ping", (idx,))	
							elif ProtocolTreeNode.tagEquals(childNode,"query") and node.getAttributeValue("from") is not None and "http://jabber.org/protocol/disco#info" == childNode.getAttributeValue("xmlns"):
								pin = childNode.getAttributeValue("pin");
								timeoutString = childNode.getAttributeValue("timeout");
								try:
									timeoutSeconds = int(timeoutString) if timeoutString is not None else None
								except ValueError:
									raise Exception("relay-iq exception parsing timeout %s "%(timeoutString))

								if pin is not None:
									self.eventHandler.onRelayRequest(pin,timeoutSeconds,idx)
						elif iqType == "set":
							childNode = node.getChild(0)
							if ProtocolTreeNode.tagEquals(childNode,"query"):
								xmlns = childNode.getAttributeValue("xmlns")

								if xmlns == "jabber:iq:roster":
									itemNodes = childNode.getAllChildren("item");
									ask = ""
									for itemNode in itemNodes:
										jid = itemNode.getAttributeValue("jid")
										subscription = itemNode.getAttributeValue("subscription")
										ask = itemNode.getAttributeValue("ask")
						else:
							raise Exception("Unkown iq type %s"%(iqType))

					elif ProtocolTreeNode.tagEquals(node,"presence"):
						xmlns = node.getAttributeValue("xmlns")
						jid = node.getAttributeValue("from")

						if (xmlns is None or xmlns == "urn:xmpp") and jid is not None:
							presenceType = node.getAttributeValue("type")
							if presenceType == "unavailable":
								self.signalInterface.send("presence_unavailable", (jid,))
							elif presenceType is None or presenceType == "available":
								self.signalInterface.send("presence_available", (jid,))

						elif xmlns == "w" and jid is not None:
							status = node.getAttributeValue("status")

							if status == "dirty":
								#categories = self.parseCategories(node); #@@TODO, send along with signal
								self._d("WILL SEND DIRTY")
								self.signalInterface.send("status_dirty")
								self._d("SENT DIRTY")

					elif ProtocolTreeNode.tagEquals(node,"message"):
						self.parseMessage(node)
					

		self._d("Reader thread terminating now!")