def buildDataForm(form=None, type="form", fields=[], title=None, data=[]): """ Provides easier method to build data forms using dict for each form object Parameters: form: xmpp.DataForm object type: form type fields: list of form objects represented as dict, e.g. [{"var": "cool", "type": "text-single", "desc": "my cool description", "value": "cool"}] title: form title data: advanced data for form. e.g. instructions (if string in the list), look at xmpp/protocol.py:1326 """ if title and form: form.setTitle(title) form = form or xmpp.DataForm(type, data, title) for key in fields: field = form.setField(key["var"], key.get("value"), key.get("type"), key.get("desc"), key.get("options")) if key.get("payload"): field.setPayload(key["payload"]) if key.get("label"): field.setLabel(key["label"]) if key.get("requred"): field.setRequired() return form
def create_room(room_name): """Create and configure a room. Documentation to create and configure a room: https://xmpp.org/extensions/xep-0045.html#createroom Parameters ---------- room_name: string The name of the room you want to create. """ client = _connect() client.send( xmpp.Presence( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}/admin", payload=[xmpp.Node(tag="x", attrs={"xmlns": xmpp.NS_MUC})], ) ) client.send( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="set", queryNS=xmpp.NS_MUC_OWNER, payload=[ xmpp.DataForm( typ="submit", data=[ xmpp.DataField( typ="hidden", name="FORM_TYPE", value=xmpp.NS_MUC_ROOMCONFIG ), # Make Room Persistent? xmpp.DataField( typ="boolean", name="muc#roomconfig_persistentroom", value=1 ), # Make room publicly searchable? xmpp.DataField( typ="boolean", name="muc#roomconfig_publicroom", value=0 ), # Nobody can send private message xmpp.DataField( typ="list-single", name="muc#roomconfig_allowpm", value="none", ), # Nobody can send private message xmpp.DataField( typ="boolean", name="muc#roomconfig_allowinvites", value=0 ), # Nobody can change the subject xmpp.DataField( typ="boolean", name="muc#roomconfig_changesubject", value=0 ), ], ) ], ) )
def calcDataFormAccept(self, conn, request): """ Load the calcType form filled in by requester, then reply with the result. """ # get the session data sessionid = request.getTagAttr('command', 'sessionid') session = self.sessions[sessionid] # load the form node = request.getTag(name='command').getTag(name='x', namespace=NS_DATA) form = xmpp.DataForm(node=node) # retrieve the data; if the entered value is not a number, return to second stage try: value = float(form.getField('radius').getValue()) except: self.calcDataForm(conn, request, notavalue=True) # calculate the answer from math import pi if session['data']['type'] == 'circlearea': result = (value**2) * pi else: result = 2 * value * pi # build the result form form = xmpp.DataForm( typ='result', data=[xmpp.DataField(desc='result', name='result', value=result)]) # build the reply stanza reply = request.buildReply('result') reply.addChild(name='command', namespace=NS_COMMANDS, attrs={ 'node': request.getTagAttr('command', 'node'), 'sessionid': sessionid, 'status': 'completed' }, payload=[form]) self._owner.send(reply) # erase the data about session del self.sessions[sessionid] raise xmpp.NodeProcessed
def calcTypeForm(self, conn, request): """ Send first form to the requesting user. """ # get the session data sessionid = request.getTagAttr('command','sessionid') session = self.sessions[sessionid] # What to do when a user sends us a response? Note, that we should always # include 'execute', as it is a default action when requester does not send # exact action to do (should be set to the same as 'next' or 'complete' fields) session['actions'] = { 'cancel': self.cancel, 'next': self.calcTypeFormAccept, 'execute': self.calcTypeFormAccept, } # The form to send calctypefield = xmpp.DataField( name='calctype', desc='Calculation Type', value=session['data']['type'], options=[ ['Calculate the diameter of a circle','circlediameter'], ['Calculate the area of a circle','circlearea'] ], typ='list-single', required=1) # We set label attribute... seems that the xmpppy.DataField cannot do that calctypefield.setAttr('label', 'Calculation Type') form = xmpp.DataForm( title='Select type of operation', data=[ 'Use the combobox to select the type of calculation you would like'\ 'to do, then click Next.', calctypefield]) # Build a reply with the form reply = request.buildReply('result') replypayload = [ xmpp.Node('actions', attrs={'execute':'next'}, payload=[xmpp.Node('next')]), form] reply.addChild( name='command', namespace=NS_COMMANDS, attrs={ 'node':request.getTagAttr('command','node'), 'sessionid':sessionid, 'status':'executing'}, payload=replypayload) self._owner.send(reply) # Question: self._owner or conn? raise xmpp.NodeProcessed
def calcDataForm(self, conn, request, notavalue=None): """ Send a form asking for diameter. """ # get the session data sessionid = request.getTagAttr('command', 'sessionid') session = self.sessions[sessionid] # set the actions taken on requester's response session['actions'] = { 'cancel': self.cancel, 'prev': self.calcTypeForm, 'next': self.calcDataFormAccept, 'execute': self.calcDataFormAccept } # create a form radiusfield = xmpp.DataField(desc='Radius', name='radius', typ='text-single') radiusfield.setAttr('label', 'Radius') form = xmpp.DataForm( title='Enter the radius', data=[ 'Enter the radius of the circle (numbers only)', radiusfield ]) # build a reply stanza reply = request.buildReply('result') replypayload = [ xmpp.Node('actions', attrs={'execute': 'complete'}, payload=[xmpp.Node('complete'), xmpp.Node('prev')]), form ] if notavalue: replypayload.append( xmpp.Node('note', attrs={'type': 'warn'}, payload=['You have to enter valid number.'])) reply.addChild(name='command', namespace=NS_COMMANDS, attrs={ 'node': request.getTagAttr('command', 'node'), 'sessionid': request.getTagAttr('command', 'sessionid'), 'status': 'executing' }, payload=replypayload) self._owner.send(reply) raise xmpp.NodeProcessed
def captchaChallenge(self): if self.engine.captcha: logger.debug("VKLogin: sending message with captcha to %s" % self.jidFrom) body = _("WARNING: VK sent captcha to you." " Please, go to %s and enter text from image to chat." " Example: !captcha my_captcha_key. Tnx" ) % self.engine.captcha["img"] msg = xmpp.Message(self.jidFrom, body, "chat", frm=TransportID) xTag = msg.setTag("x", {}, xmpp.NS_OOB) xTag.setTagData("url", self.engine.captcha["img"]) cTag = msg.setTag("captcha", {}, xmpp.NS_CAPTCHA) imgData = vCardGetPhoto(self.engine.captcha["img"], False) if imgData: imgHash = sha1(imgData).hexdigest() imgEncoded = imgData.encode("base64") form = xmpp.DataForm("form") form.setField("FORM_TYPE", xmpp.NS_CAPTCHA, "hidden") form.setField("from", TransportID, "hidden") field = form.setField("ocr") field.setLabel(_("Enter shown text")) field.delAttr("type") field.setPayload([ xmpp.Node("required"), xmpp.Node("media", {"xmlns": xmpp.NS_MEDIA}, [ xmpp.Node("uri", {"type": "image/jpg"}, ["cid:sha1+%[email protected]" % imgHash]) ]) ]) cTag.addChild(node=form) obTag = msg.setTag( "data", { "cid": "*****@*****.**" % imgHash, "type": "image/jpg", "max-age": "0" }, xmpp.NS_URN_OOB) obTag.setData(imgEncoded) else: logger.critical( "VKLogin: can't add captcha image to message url:%s" % self.engine.captcha["img"]) Sender(Component, msg) Presence = xmpp.protocol.Presence(self.jidFrom, frm=TransportID) Presence.setStatus(body) Presence.setShow("xa") Sender(Component, Presence) else: logger.error( "VKLogin: captchaChallenge called without captcha for user %s" % self.jidFrom)
def calcTypeFormAccept(self, conn, request): """ Load the calcType form filled in by requester, then reply with the second form. """ # get the session data sessionid = request.getTagAttr('command','sessionid') session = self.sessions[sessionid] # load the form node = request.getTag(name='command').getTag(name='x',namespace=NS_DATA) form = xmpp.DataForm(node=node) # retrieve the data session['data']['type'] = form.getField('calctype').getValue() # send second form return self.calcDataForm(conn, request)
def close_room(room_name): """Close a room to anonymous users. members only documentation: https://xmpp.org/extensions/xep-0045.html#enter-members Parameters ---------- room_name: string The name of the room you want to destroy. """ client = _connect() client.send( xmpp.Presence( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}/admin", payload=[xmpp.Node(tag="x", attrs={"xmlns": xmpp.NS_MUC})], ) ) client.send( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="set", queryNS=xmpp.NS_MUC_OWNER, payload=[ xmpp.DataForm( typ="submit", data=[ xmpp.DataField( typ="hidden", name="FORM_TYPE", value=xmpp.NS_MUC_ROOMCONFIG ), xmpp.DataField( typ="boolean", name="muc#roomconfig_membersonly", value=1 ), ], ) ], ) )
def create_room(room_name): """Create and configure a room. Documentation to create and configure a room: https://xmpp.org/extensions/xep-0045.html#createroom-reserved Parameters ---------- room_name: string The name of the room you want to create. """ client = _connect() client.send( xmpp.Presence( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}/admin", payload=[xmpp.Node(tag="x", attrs={"xmlns": xmpp.NS_MUC})], ) ) # request the default config when a room is created default_config_iq = client.SendAndWaitForResponse( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="get", queryNS=xmpp.NS_MUC_OWNER, ) ) data = [] fileds_to_exclude = [ "muc#roomconfig_persistentroom", "muc#roomconfig_publicroom", "muc#roomconfig_allowpm", "muc#roomconfig_allowinvites", "muc#roomconfig_changesubject", "muc#roomconfig_membersonly", ] # Remove config we want to modify for children in default_config_iq.getQueryPayload()[0].getChildren(): if ( children.getName() == "field" and children.getAttr("var") not in fileds_to_exclude ): data.append(children) # Add our own config data = data + [ # Room is persistent xmpp.DataField(typ="boolean", name="muc#roomconfig_persistentroom", value=1), # Room is not publicly searchable xmpp.DataField(typ="boolean", name="muc#roomconfig_publicroom", value=0), # Nobody can send private message xmpp.DataField( typ="list-single", name="muc#roomconfig_allowpm", value="none", ), # Room invitations are disabled xmpp.DataField(typ="boolean", name="muc#roomconfig_allowinvites", value=0), # Nobody can change the subject xmpp.DataField(typ="boolean", name="muc#roomconfig_changesubject", value=0), xmpp.DataField(typ="boolean", name="muc#roomconfig_membersonly", value=0), ] client.send( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="set", queryNS=xmpp.NS_MUC_OWNER, payload=[ xmpp.DataForm( typ="submit", data=data, ) ], ) )
def close_room(room_name): """Close a room to anonymous users. members only documentation: https://xmpp.org/extensions/xep-0045.html#enter-members Parameters ---------- room_name: string The name of the room you want to destroy. """ client = _connect() client.send( xmpp.Presence( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}/admin", payload=[xmpp.Node(tag="x", attrs={"xmlns": xmpp.NS_MUC})], ) ) # request the current room config default_config_iq = client.SendAndWaitForResponse( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="get", queryNS=xmpp.NS_MUC_OWNER, ) ) data = [] fileds_to_exclude = [ "muc#roomconfig_membersonly", ] # Remove config we want to modify for children in default_config_iq.getQueryPayload()[0].getChildren(): if ( children.getName() == "field" and children.getAttr("var") not in fileds_to_exclude ): data.append(children) # Add our own config data = data + [ xmpp.DataField(typ="boolean", name="muc#roomconfig_membersonly", value=1), ] client.send( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="set", queryNS=xmpp.NS_MUC_OWNER, payload=[ xmpp.DataForm( typ="submit", data=data, ) ], ) )