def readFeaturesAndChallenge(self): server_supports_receipt_acks = True; 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 data; raise Exception("fell out of loop in readFeaturesAndChallenge");
def readFeaturesAndChallenge(self): server_supports_receipt_acks = True 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 data raise Exception("fell out of loop in readFeaturesAndChallenge")
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 readSuccess(self): node = self.conn.reader.nextTree() self._d("Login Status: %s" % (node.tag)) if ProtocolTreeNode.tagEquals(node, "failure"): self.authObject.authenticationFailed() 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 = [] self.authObject.authenticationComplete()
def readSuccess(self): node = self.conn.reader.nextTree(); self._d("Login Status: %s"%(node.tag)); if ProtocolTreeNode.tagEquals(node,"failure"): self.authObject.authenticationFailed() 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 = []; self.authObject.authenticationComplete()
def parseMessage(self,messageNode): bodyNode = messageNode.getChild("body"); newSubject = "" if bodyNode is None else bodyNode.data; msgData = None timestamp = long(time.time()*1000) isGroup = 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": bodyNode = messageNode.getChild("notification").getChild("set") or messageNode.getChild("notification").getChild("delete") 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 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,"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 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)) elif mediaType == "video": mediaPreview = messageNode.getChild("media").data if encoding == "raw" and mediaPreview: mediaPreview = base64.b64encode(mediaPreview) 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)) 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)) elif mediaType == "location": mlatitude = messageNode.getChild("media").getAttributeValue("latitude") mlongitude = messageNode.getChild("media").getAttributeValue("longitude") name = messageNode.getChild("media").getAttributeValue("name") mediaPreview = messageNode.getChild("media").data if encoding == "raw" and mediaPreview: mediaPreview = base64.b64encode(mediaPreview) 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)) 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 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)) 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: 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: if isGroup: self.signalInterface.send("group_messageReceived", (msgId, fromAttribute, author, msgData, timestamp, wantsReceipt)) else: self.signalInterface.send("message_received", (msgId, fromAttribute, msgData, timestamp, wantsReceipt)) ##@@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
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 == 210 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 self.requests.has_key(idx): 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 self.requests.has_key(idx): 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 jid 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!")