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]
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)
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)
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)
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)
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)
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)
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
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)
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)
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",))
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)
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
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
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)
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)))
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)
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");
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])
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 = []
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")
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")
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)
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)
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)
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
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;
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)
def sendFeatures(self): toWrite = ProtocolTreeNode("stream:features", None) self.conn.writer.write(toWrite)
def sendVCard(self, jid, data, name): cardNode = ProtocolTreeNode("vcard",{"name":name},None,data); return ProtocolTreeNode("media", {"xmlns":"urn:xmpp:whatsapp:mms","type":"vcard"},[cardNode])
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);
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!")
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