Пример #1
0
Файл: command.py Проект: dax/jmc
 def execute_retrieve_attachment_1(self, info_query, session_context,
                                   command_node, lang_class):
     self.__logger.debug("Executing command 'retrieve-attachment' step 1")
     self.add_actions(command_node, [command.ACTION_NEXT])
     bare_from_jid = info_query.get_from().bare()
     account_name = info_query.get_to().node
     _account = account.get_account(bare_from_jid, account_name,
                                    MailAccount)
     if _account is not None:
         result_form = Form(xmlnode_or_type="form",
                            title="TITLE",
                            instructions="INS")
         field = result_form.add_field(name="attachments",
                                       field_type="list-multi",
                                       label="select attachments")
         field.add_option(label="Next",
                          value="-1")
         for (mail_id, mail_title) in _account.get_mail_with_attachment_list():
             field.add_option(label=mail_title,
                              value=mail_id)
         result_form.as_xml(command_node)
         return (result_form, [])
     else:
         # ERROR
         return (None, [])
Пример #2
0
Файл: command.py Проект: dax/jmc
 def execute_get_email_last(self, info_query, session_context,
                            command_node, lang_class):
     self.__logger.debug("Executing command 'get-email' last step")
     result = []
     mail_sender = MailSender(self.component)
     bare_from_jid = info_query.get_from().bare()
     account_name = info_query.get_to().node
     _account = account.get_account(bare_from_jid, account_name)
     if _account is not None:
         _account.connect()
         for email_index in session_context["emails"]:
             (email_body, email_from) = _account.get_mail(email_index)
             result.append(\
                 mail_sender.create_full_email_message(\
                     email_from,
                     lang_class.mail_subject % (email_from),
                     email_body,
                     _account))
         _account.disconnect()
         result_form = Form(\
             xmlnode_or_type="form",
             title=lang_class.command_get_email,
             instructions=lang_class.command_get_email_2_description \
                 % (len(session_context["emails"])))
         result_form.as_xml(command_node)
     command_node.setProp("status", command.STATUS_COMPLETED)
     return (None, result)
Пример #3
0
Файл: command.py Проект: dax/jmc
 def execute_get_email(self, info_query, session_context,
                       command_node, lang_class):
     self.__logger.debug("Executing command 'get-email' step 1")
     if "fetch_more" in session_context \
             and session_context["fetch_more"][-1] == "0":
         return self.execute_get_email_last(info_query, session_context,
                                            command_node, lang_class)
     else:
         self.add_actions(command_node, [command.ACTION_COMPLETE])
         bare_from_jid = info_query.get_from().bare()
         account_name = info_query.get_to().node
         _account = account.get_account(bare_from_jid, account_name)
         if _account is not None:
             result_form = Form(\
                 xmlnode_or_type="form",
                 title=lang_class.command_get_email,
                 instructions=lang_class.command_get_email_1_description)
             if not "start_index" in session_context:
                 session_context["start_index"] = 1
             self.__logger.debug("Checking email list summary from index "
                                 + str(session_context["start_index"]) + " to "
                                 + str(session_context["start_index"] + 10))
             _account.connect()
             email_list = _account.get_mail_list_summary(\
                 start_index=session_context["start_index"],
                 end_index=session_context["start_index"] + 9)
             _account.disconnect()
             session_context["start_index"] += 10
             field = result_form.add_field(name="emails",
                                           field_type="list-multi",
                                           label=lang_class.field_email_subject)
             for (email_index, email_subject) in email_list:
                 field.add_option(label=email_subject, value=email_index)
             if len(email_list) == 10:
                 result_form.add_field(name="fetch_more",
                                       field_type="boolean",
                                       label=lang_class.field_select_more_emails)
             else:
                 session_context["fetch_more"] = ["0"]
             result_form.as_xml(command_node)
             return (result_form, [])
         else:
             raise CommandError("item-not-found")
Пример #4
0
    def complete_xml_element(self, xmlnode, _unused):
        """Complete the XML node with `self` content.

        Should be overriden in classes derived from `StanzaPayloadObject`.

        :Parameters:
            - `xmlnode`: XML node with the element being built. It has already
              right name and namespace, but no attributes or content.
            - `_unused`: document to which the element belongs.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
            - `_unused`: `libxml2.xmlDoc`"""
        if self.possible_streams:
            field = dataforms.Field(name='stream-method', field_type='list-single',
                                    options=[dataforms.Option(n)
                                             for n in self.possible_streams])
            f = dataforms.Form(xmlnode_or_type='form', fields=[field])
        else:
            f = Form(xmlnode_or_type="submit")
            f.add_field(name='stream-method', value=self.selected_stream)
        f.as_xml(xmlnode, _unused)
Пример #5
0
    def complete_xml_element(self, xmlnode, _unused):
        """Complete the XML node with `self` content.

        Should be overriden in classes derived from `StanzaPayloadObject`.

        :Parameters:
            - `xmlnode`: XML node with the element being built. It has already
              right name and namespace, but no attributes or content.
            - `_unused`: document to which the element belongs.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
            - `_unused`: `libxml2.xmlDoc`"""
        if self.possible_streams:
            field = dataforms.Field(
                name='stream-method',
                field_type='list-single',
                options=[dataforms.Option(n) for n in self.possible_streams])
            f = dataforms.Form(xmlnode_or_type='form', fields=[field])
        else:
            f = Form(xmlnode_or_type="submit")
            f.add_field(name='stream-method', value=self.selected_stream)
        f.as_xml(xmlnode, _unused)
Пример #6
0
class Register(StanzaPayloadObject):
    """
    Delayed delivery tag.

    Represents 'jabber:iq:register' (JEP-0077) element of a Jabber <iq/> stanza.

    Please note that it is recommended to use `get_form` and `submit_form` records
    instead of accessing the `form` and legacy fields directly. This way both
    legacy and Data Forms registration would work transparently to the application.

    :Ivariables:
        - `form`: registration form (when available)
        - `registered`: `True` if entity is already registered
        - `instrutions`: Registration instructions (legacy protocol)
        - `username`: Username field (legacy protocol)
        - `nick`: Nickname (legacy protocol)
        - `password`: Password (legacy protocol)
        - `name`: Name field (legacy protocol)
        - `first`: First name field (legacy protocol)
        - `last`: Last name field (legacy protocol)
        - `email`: E-mail field (legacy protocol)
        - `address`: Address field (legacy protocol)
        - `city`: City field (legacy protocol)
        - `state`: State field (legacy protocol)
        - `zip`: ZIP code field (legacy protocol)
        - `phone`: Phone field (legacy protocol)
        - `url`: URL field (legacy protocol)
        - `date`: Date field (legacy protocol)
        - `misc`: Misc field (legacy protocol, obsolete)
        - `text`: Text field (legacy protocol, obsolete)
        - `key`: Key field (legacy protocol, obsolete)
        - `remove`: `True` when the account should be removed
    :Types:
        - `form`: `pyxmpp.jabber.dataforms.Form`
        - `registered`: `bool`
        - `instrutions`: `unicode`
        - `username`: `unicode`
        - `nick`: `unicode`
        - `password`: `unicode`
        - `name`: `unicode`
        - `first`: `unicode`
        - `last`: `unicode`
        - `email`: `unicode`
        - `address`: `unicode`
        - `city`: `unicode`
        - `state`: `unicode`
        - `zip`: `unicode`
        - `phone`: `unicode`
        - `url`: `unicode`
        - `date`: `unicode`
        - `misc`: `unicode`
        - `text`: `unicode`
        - `key`: `unicode`
        - `remove`: `True` when the account should be removed
    """

    xml_element_name = "query"
    xml_element_namespace = REGISTER_NS

    def __init__(self, xmlnode=None):
        """
        Initialize the `Register` object.

        :Parameters:
            - `xmlnode`: an optional XML node to parse.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
        """
        self.__logger = logging.getLogger("pyxmpp.jabber.Register")
        self.form = None
        self.registered = False
        self.instructions = None
        self.remove = False
        for f in legacy_fields:
            setattr(self, f, None)
        if isinstance(xmlnode, libxml2.xmlNode):
            self.__from_xml(xmlnode)

    def __from_xml(self, xmlnode):
        """Initialize `Register` from an XML node.

        :Parameters:
            - `xmlnode`: the jabber:x:register XML element.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`"""

        self.__logger.debug("Converting jabber:iq:register element from XML")
        if xmlnode.type != "element":
            raise ValueError, "XML node is not a jabber:iq:register element (not an element)"
        ns = get_node_ns_uri(xmlnode)
        if ns and ns != REGISTER_NS or xmlnode.name != "query":
            raise ValueError, "XML node is not a jabber:iq:register element"

        for element in xml_element_iter(xmlnode.children):
            ns = get_node_ns_uri(element)
            if ns == DATAFORM_NS and element.name == "x" and not self.form:
                self.form = Form(element)
            elif ns != REGISTER_NS:
                continue
            name = element.name
            if name == "instructions" and not self.instructions:
                self.instructions = from_utf8(element.getContent())
            elif name == "registered":
                self.registered = True
            elif name == "remove":
                self.remove = True
            elif name in legacy_fields and not getattr(self, name):
                value = from_utf8(element.getContent())
                if value is None:
                    value = u""
                self.__logger.debug(u"Setting legacy field %r to %r" %
                                    (name, value))
                setattr(self, name, value)

    def complete_xml_element(self, xmlnode, doc):
        """Complete the XML node with `self` content.

        :Parameters:
            - `xmlnode`: XML node with the element being built. It has already
              right name and namespace, but no attributes or content.
            - `doc`: document to which the element belongs.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
            - `doc`: `libxml2.xmlDoc`"""
        ns = xmlnode.ns()
        if self.instructions is not None:
            xmlnode.newTextChild(ns, "instructions",
                                 to_utf8(self.instructions))
        if self.form:
            self.form.as_xml(xmlnode, doc)
        if self.remove:
            xmlnode.newChild(ns, "remove", None)
        else:
            if self.registered:
                xmlnode.newChild(ns, "registered", None)
            for field in legacy_fields:
                value = getattr(self, field)
                if value is not None:
                    xmlnode.newTextChild(ns, field, to_utf8(value))

    def get_form(self, form_type="form"):
        """Return Data Form for the `Register` object.

        Convert legacy fields to a data form if `self.form` is `None`, return `self.form` otherwise.

        :Parameters:
            - `form_type`: If "form", then a form to fill-in should be
              returned. If "sumbit", then a form with submitted data.
        :Types:
            - `form_type`: `unicode`

        :return: `self.form` or a form created from the legacy fields
        :returntype: `pyxmpp.jabber.dataforms.Form`"""

        if self.form:
            if self.form.type != form_type:
                raise ValueError, "Bad form type in the jabber:iq:register element"
            return self.form

        form = Form(form_type, instructions=self.instructions)
        form.add_field("FORM_TYPE", [u"jabber:iq:register"], "hidden")
        for field in legacy_fields:
            field_type, field_label = legacy_fields[field]
            value = getattr(self, field)
            if value is None:
                continue
            if form_type == "form":
                if not value:
                    value = None
                form.add_field(name=field,
                               field_type=field_type,
                               label=field_label,
                               value=value,
                               required=True)
            else:
                form.add_field(name=field, value=value)
        return form

    def submit_form(self, form):
        """Make `Register` object for submitting the registration form.

        Convert form data to legacy fields if `self.form` is `None`.

        :Parameters:
            - `form`: The form to submit. Its type doesn't have to be "submit"
              (a "submit" form will be created here), so it could be the form
              obtained from `get_form` just with the data entered.

        :return: new registration element
        :returntype: `Register`"""

        result = Register()
        if self.form:
            result.form = form.make_submit()
            return result

        if "FORM_TYPE" not in form or "jabber:iq:register" not in form[
                "FORM_TYPE"].values:
            raise ValueError, "FORM_TYPE is not jabber:iq:register"

        for field in legacy_fields:
            self.__logger.debug(u"submitted field %r" % (field, ))
            value = getattr(self, field)
            try:
                form_value = form[field].value
            except KeyError:
                if value:
                    raise ValueError, "Required field with no value!"
                continue
            setattr(result, field, form_value)

        return result
Пример #7
0
class Register(StanzaPayloadObject):
    """
    Delayed delivery tag.

    Represents 'jabber:iq:register' (JEP-0077) element of a Jabber <iq/> stanza.

    Please note that it is recommended to use `get_form` and `submit_form` records
    instead of accessing the `form` and legacy fields directly. This way both
    legacy and Data Forms registration would work transparently to the application.

    :Ivariables:
        - `form`: registration form (when available)
        - `registered`: `True` if entity is already registered
        - `instrutions`: Registration instructions (legacy protocol)
        - `username`: Username field (legacy protocol)
        - `nick`: Nickname (legacy protocol)
        - `password`: Password (legacy protocol)
        - `name`: Name field (legacy protocol)
        - `first`: First name field (legacy protocol)
        - `last`: Last name field (legacy protocol)
        - `email`: E-mail field (legacy protocol)
        - `address`: Address field (legacy protocol)
        - `city`: City field (legacy protocol)
        - `state`: State field (legacy protocol)
        - `zip`: ZIP code field (legacy protocol)
        - `phone`: Phone field (legacy protocol)
        - `url`: URL field (legacy protocol)
        - `date`: Date field (legacy protocol)
        - `misc`: Misc field (legacy protocol, obsolete)
        - `text`: Text field (legacy protocol, obsolete)
        - `key`: Key field (legacy protocol, obsolete)
        - `remove`: `True` when the account should be removed
    :Types:
        - `form`: `pyxmpp.jabber.dataforms.Form`
        - `registered`: `bool`
        - `instrutions`: `unicode`
        - `username`: `unicode`
        - `nick`: `unicode`
        - `password`: `unicode`
        - `name`: `unicode`
        - `first`: `unicode`
        - `last`: `unicode`
        - `email`: `unicode`
        - `address`: `unicode`
        - `city`: `unicode`
        - `state`: `unicode`
        - `zip`: `unicode`
        - `phone`: `unicode`
        - `url`: `unicode`
        - `date`: `unicode`
        - `misc`: `unicode`
        - `text`: `unicode`
        - `key`: `unicode`
        - `remove`: `True` when the account should be removed
    """

    xml_element_name = "query"
    xml_element_namespace = REGISTER_NS

    def __init__(self, xmlnode=None):
        """
        Initialize the `Register` object.

        :Parameters:
            - `xmlnode`: an optional XML node to parse.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
        """
        self.__logger = logging.getLogger("pyxmpp.jabber.Register")
        self.form = None
        self.registered = False
        self.instructions = None
        self.remove = False
        for f in legacy_fields:
            setattr(self, f, None)
        if isinstance(xmlnode, libxml2.xmlNode):
            self.__from_xml(xmlnode)

    def __from_xml(self, xmlnode):
        """Initialize `Register` from an XML node.

        :Parameters:
            - `xmlnode`: the jabber:x:register XML element.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`"""

        self.__logger.debug("Converting jabber:iq:register element from XML")
        if xmlnode.type != "element":
            raise ValueError, "XML node is not a jabber:iq:register element (not an element)"
        ns = get_node_ns_uri(xmlnode)
        if ns and ns != REGISTER_NS or xmlnode.name != "query":
            raise ValueError, "XML node is not a jabber:iq:register element"

        for element in xml_element_iter(xmlnode.children):
            ns = get_node_ns_uri(element)
            if ns == DATAFORM_NS and element.name == "x" and not self.form:
                self.form = Form(element)
            elif ns != REGISTER_NS:
                continue
            name = element.name
            if name == "instructions" and not self.instructions:
                self.instructions = from_utf8(element.getContent())
            elif name == "registered":
                self.registered = True
            elif name == "remove":
                self.remove = True
            elif name in legacy_fields and not getattr(self, name):
                value = from_utf8(element.getContent())
                if value is None:
                    value = u""
                self.__logger.debug(u"Setting legacy field %r to %r" % (name, value))
                setattr(self, name, value)

    def complete_xml_element(self, xmlnode, doc):
        """Complete the XML node with `self` content.

        :Parameters:
            - `xmlnode`: XML node with the element being built. It has already
              right name and namespace, but no attributes or content.
            - `doc`: document to which the element belongs.
        :Types:
            - `xmlnode`: `libxml2.xmlNode`
            - `doc`: `libxml2.xmlDoc`"""
        ns = xmlnode.ns()
        if self.instructions is not None:
            xmlnode.newTextChild(ns, "instructions", to_utf8(self.instructions))
        if self.form:
            self.form.as_xml(xmlnode, doc)
        if self.remove:
            xmlnode.newChild(ns, "remove", None)
        else:
            if self.registered:
                xmlnode.newChild(ns, "registered", None)
            for field in legacy_fields:
                value = getattr(self, field)
                if value is not None:
                    xmlnode.newTextChild(ns, field, to_utf8(value))

    def get_form(self, form_type="form"):
        """Return Data Form for the `Register` object.

        Convert legacy fields to a data form if `self.form` is `None`, return `self.form` otherwise.

        :Parameters:
            - `form_type`: If "form", then a form to fill-in should be
              returned. If "sumbit", then a form with submitted data.
        :Types:
            - `form_type`: `unicode`

        :return: `self.form` or a form created from the legacy fields
        :returntype: `pyxmpp.jabber.dataforms.Form`"""

        if self.form:
            if self.form.type != form_type:
                raise ValueError, "Bad form type in the jabber:iq:register element"
            return self.form

        form = Form(form_type, instructions=self.instructions)
        form.add_field("FORM_TYPE", [u"jabber:iq:register"], "hidden")
        for field in legacy_fields:
            field_type, field_label = legacy_fields[field]
            value = getattr(self, field)
            if value is None:
                continue
            if form_type == "form":
                if not value:
                    value = None
                form.add_field(name=field, field_type=field_type, label=field_label, value=value, required=True)
            else:
                form.add_field(name=field, value=value)
        return form

    def submit_form(self, form):
        """Make `Register` object for submitting the registration form.

        Convert form data to legacy fields if `self.form` is `None`.

        :Parameters:
            - `form`: The form to submit. Its type doesn't have to be "submit"
              (a "submit" form will be created here), so it could be the form
              obtained from `get_form` just with the data entered.

        :return: new registration element
        :returntype: `Register`"""

        result = Register()
        if self.form:
            result.form = form.make_submit()
            return result

        if "FORM_TYPE" not in form or "jabber:iq:register" not in form["FORM_TYPE"].values:
            raise ValueError, "FORM_TYPE is not jabber:iq:register"

        for field in legacy_fields:
            self.__logger.debug(u"submitted field %r" % (field,))
            value = getattr(self, field)
            try:
                form_value = form[field].value
            except KeyError:
                if value:
                    raise ValueError, "Required field with no value!"
                continue
            setattr(result, field, form_value)

        return result