Пример #1
0
class Subscription(VElement):
    elementName = 'subscription'

    node = fields.StringAttr('node', required=False)
    jid = fields.JidAttr('jid')
    subscription = fields.JidAttr('subscription')
    subid = fields.StringAttr('subid', required=False)
Пример #2
0
class SIRequest(SIElement):
    result_class = SIResponse
    # TODO: error_class

    mime_type = fields.StringAttr('mime-type', required=False)
    id_ = fields.StringAttr('id')
    profile = fields.StringAttr('profile')

    def make_reply(self, si):
        meta = {}
        streams = si.streams
        allowed = None
        for method in self.feature.methods.stream_method.options:
            if method.value in streams.keys():
                allowed = method.value
                break
        if not allowed:
            # TODO: application specific error
            raise errors.BadRequestException
        reply_form = self.feature.methods.make_submit_form()
        reply_form.stream_method.value = allowed
        feature = Feature(methods=reply_form)
        reply = self.result_class(feature=feature, parent=self.iq.makeResult())
        si.receive(allowed, self.id_, self.iq.from_, meta)
        sid = self.id_

        def canceller(_):
            stream = si.streams[allowed]
            stream.unregisterSession(sid=sid)

        deferred = defer.Deferred(canceller)
        return reply, deferred, meta
Пример #3
0
class FileRequest(File):
    name_ = fields.StringAttr('name')
    size = fields.IntegerAttr('size')
    hash_ = fields.StringAttr('hash', required=False)
    date = fields.DateTimeAttr('date', required=False)
    description = fields.StringNode('desc', required=False)
    range_ = fields.ElementNode(Range, required=False)
Пример #4
0
class Items(VElement):
    elementName = 'items'

    items = fields.ElementNode(Item, listed=True, required=False)
    node = fields.StringAttr('node')
    max_items = fields.StringAttr('max_items', required=False)
    retracts = fields.ElementNode(Retract, listed=True, required=False)
Пример #5
0
class Iq(Stanza):
    """
    Stanza-inheritor class that implements an answer-query type mechanism.
    """
    elementName = 'iq'

    type_ = fields.StringAttr('type')
    id = fields.StringAttr('id')

    def __init__(self, **kwargs):
        """
        Constructor controls for valid value of id,
        calls superclass-constructor and sets deferred 
        attribute for set/get - type queries
        
        """
        if 'id' not in kwargs:
            kwargs['id'] = uuid.uuid4()
        super(Iq, self).__init__(**kwargs)
        if not self.type_ in ('result', 'error') and \
            not kwargs.get('dont_defer', False):
            self.deferred = Deferred()

    def clean_type_(self, value):
        """
        Filters stanzas by type. 
        Used for validation of type\_ field.
        Raises exception for invalid stanzas.
        
        :raises: ElementParseError
        
        """
        if value not in ('set', 'get', 'result', 'error'):
            raise ElementParseError, 'Wrong Iq Type %s' % value
        return value

    def clean_id(self, value):
        """
        Set correct value if id was not found.
        Used for validation of id.    
        """
        if value is None:
            self.addUniqueId()
            return self.id
        return value

    def makeResult(self):
        """Returns result-type Iq stanza"""
        return Iq(to=self.from_,
                  from_=self.to,
                  id=self.id,
                  type_='result',
                  uri=self.uri)
Пример #6
0
class StreamHost(VElement):
    elementName = 'streamhost'

    rhost = fields.StringAttr('host')
    jid = fields.JidAttr('jid')
    port = fields.StringAttr('port')

    def clean_port(self, value):
        try:
            value = int(value)
            assert value < 65536
        except (ValueError, TypeError, AssertionError):
            raise NotAcceptableException
        return value
Пример #7
0
class DataElement(VElement):
    elementName = 'data'
    elementUri = IBB_NS

    seq = fields.StringAttr('seq')
    sid = fields.StringAttr('sid')

    def clean_seq(self, value):
        try:
            value = int(value)
        except (ValueError, TypeError, AssertionError):
            raise errors.BadRequestException
        value = value % 65536
        return value
Пример #8
0
class UserItemInfo(VElement):
    """
    VElement-inheritor class for user info from xml stanzas.
    Used in multi-user chat presences and also in administrator's queries.

    """
    elementName = 'item'
    elementUri = 'http://jabber.org/protocol/muc#user'

    affiliation = fields.StringAttr('affiliation', required=False)
    role = fields.StringAttr('role', required=False)
    nick = fields.StringAttr('nick', required=False)
    jid = fields.JidAttr('jid', required=False)
    
    reason = fields.StringNode('reason', required=False)
Пример #9
0
class Subscriptions(VElement):
    elementName = 'subscriptions'

    node = fields.StringAttr('node', required=False)
    subscriptions = fields.ElementNode(Subscription,
                                       listed=True,
                                       required=False)
Пример #10
0
class Error(VElement):
    """
    Extends VElement from twilix.base.
    Contains fields corresponding to the rfc 3920. 
    
    Attributes:
        type\_ -- string attribute 'type'
        
        condition -- condition node with Condition
        
        text -- string node 'text'
        
    """
    elementName = 'error'

    type_ = fields.StringAttr('type')
    condition = ConditionNode(Condition)
    text = fields.StringNode('text',
                             required=False,
                             uri='urn:ietf:params:xml:ns:xmpp-stanzas')

    def clean_type_(self, value):
        """
        Cut off errors with wrong type.
        Used for validaion.
        
        :returns: value if it has correct type.
        
        :raises: ElementParseError if value has a wrong type.
        
        """
        if value not in ('cancel', 'continue', 'modify', 'auth', 'wait'):
            raise ElementParseError, 'Wrong Error Type %s' % value
        return value
Пример #11
0
class Field(VElement):
    elementName = 'field'
    fieldType = None  # To be redefined in derived classes

    type_ = fields.StringAttr('type')
    label = fields.StringAttr('label', required=False)
    var = fields.StringAttr('var')

    required = fields.FlagNode('required', default=False, required=False)
    values = fields.StringNode('value', listed=True, required=False)
    options = fields.ElementNode(Option, listed=True, required=False)

    def __init__(self, value=None, *args, **kwargs):
        self.kwargs = kwargs
        super(Field, self).__init__(*args, **kwargs)
        self.type_ = self.fieldType
        self.value = value

    def prepare_to_submit(self):
        self.label = None
        self.options = ()
        self.required = None

    def restore_for_validation(self, kwargs):
        self.options = kwargs.get('options')

    def clean_type_(self, value):
        if value == self.fieldType:
            return value
        raise WrongElement

    def fclean(self, values):
        if self.kwargs.get('required') and not values:
            raise ElementParseError, "Form field %s %s is required" % \
                    (self.var, self.type_)
        return values

    def _get_value(self):
        return self.values

    def _set_value(self, value):
        self.values = value

    def _del_value(self, value):
        self.values = ()

    value = property(_get_value, _set_value, _del_value)
Пример #12
0
class HtmlHead(VElement):
    """
    Extends VElement class from twilix.base
    Realize head tag of html.
    """
    elementName = 'head'

    profile = fields.StringAttr('profile', required=False)
    title = fields.StringNode('title')
Пример #13
0
class RosterItem(VElement):
    """
    Class for xml roster item node. Inheritor of VElement.
    
    Attributes:
        jid -- jid attribute 'jid'
        
        subscription -- string attribute 'subscription'
        
        ask -- string attribute 'ask'
        
        nick -- string attribute 'name'
        
        groups -- string attribute 'group'
    
    """
    elementName = 'item'
    elementUri = 'jabber:iq:roster'

    jid = fields.JidAttr('jid')
    subscription = fields.StringAttr('subscription', required=False)
    ask = fields.StringAttr('ask', required=False)
    nick = fields.StringAttr('name', required=False)

    groups = fields.StringNode('group',
                               required=False,
                               listed=True,
                               unique=True)

    def __init__(self, **kwargs):
        super(RosterItem, self).__init__(**kwargs)
        self.presences = {}

    def is_online(self):
        return bool(self.presences)

    def __unicode__(self):
        """Unicode converter."""
        return '<RosterItem %s %s, subscription %s>' % \
               (self.jid, self.nick, self.subscription)

    def __repr__(self):
        return self.__unicode__()
Пример #14
0
class DiscoItem(VElement):
    """
    Extends VElement.
    Describe base discovery item element with fields that corresponds 
    to the protocol.
    
    Attributes:
        jid -- jid attribute
        
        iname -- string attribute contains human readable name
        
        node -- string attribute
                 
    """
    elementName = 'item'

    jid = fields.JidAttr('jid')
    iname = fields.StringAttr('name', required=False)
    node = fields.StringAttr('node', required=False)
Пример #15
0
class OpenQuery(IbbQuery):
    elementName = 'open'

    block_size = fields.StringAttr('block-size')
    sid = fields.StringAttr('sid')
    stanza_type = fields.StringAttr('stanza', required=False)

    def clean_block_size(self, value):
        try:
            value = int(value)
            assert value <= 65535
        except (ValueError, TypeError, AssertionError):
            raise errors.BadRequestException
        return value

    def clean_stanza(self, value):
        if value not in ('iq', 'message'):
            raise errors.BadRequestException
        return value
Пример #16
0
class CapsElement(VElement):  #XXX: invate automatize caps calculation
    """
    Extends VElement. 
    Describe node for entity capabilities with fields that corresponds 
    to the protocol.
    
    Attributes:
        hash\_ - string attribute contains features hash type
        
        node -- string attribute contains caps node
        
        ver -- string attribute contains features hash
       
    """
    elementName = 'c'
    elementUri = 'http://jabber.org/protocol/caps'

    hash_ = fields.StringAttr('hash')
    node = fields.StringAttr('node')
    ver = fields.StringAttr('ver')
Пример #17
0
class Identity(VElement):
    """
    Extends VElement. 
    Describe node for identity with fields that corresponds to the
    protocol.
    
    Attributes:
        category -- string attribute
        
        type\_ -- string attribute
        
        iname -- string attribute contains human readable name

    See: http://xmpp.org/registrar/disco-categories.html
            
    """
    elementName = 'identity'

    category = fields.StringAttr('category')
    type_ = fields.StringAttr('type')
    iname = fields.StringAttr('name', required=False)
Пример #18
0
class Feature(VElement):
    """
    Extends VElement. 
    Describes node for feature with field that corresponds to the
    protocol.
    
    Attributes:
        var -- string attribute with a feature namespace
                 
    """
    elementName = 'feature'

    var = fields.StringAttr('var')
Пример #19
0
class Query(VElement):
    """
    VElement-inheritor class. Base for other query-type classes. 
    There is a query part of query-answer mechanism.
    Contains fields corresponding to the protocol.
    
    Attributes:
        node -- string attribute 'node'
        
    """
    elementName = 'query'
    parentClass = Iq

    node = fields.StringAttr('node', required=False)
Пример #20
0
class Form(VElement):
    elementName = 'x'
    elementUri = 'jabber:x:data'

    type_ = f.StringAttr('type')
    title = f.StringNode('title', required=False)
    instructions = f.StringNode('instructions', required=False)

    def clean_type_(self, value):
        if value not in ('form', 'submit', 'cancel', 'result'):
            raise ElementParseError
        return value

    def clean(self):
        if self.type_ != 'submit':
            return
        for fname in self.fields:
            field = getattr(self, fname)
            value = field.fclean(field.value)
            field.value = value

    @property
    def fields(self):
        fields = []
        for name, attr in self.nodesProps.items():
            if isinstance(attr, FormField):
                fields.append(name)
        return fields

    def make_submit_form(self):
        assert self.type_ == 'form'
        sform = copy.deepcopy(self)
        fields = sform.fields
        for name in fields:
            field = getattr(sform, name)
            field.prepare_to_submit()
            setattr(sform, name, field)
        sform.type_ = 'submit'
        sform.title = None
        sform.instructions = None
        return sform

    def make_cancel_form(self):
        assert self.type_ == 'form'
        sform = copy.deepcopy(self)
        sform.children = []
        sform.type_ = 'cancel'
        return sform
Пример #21
0
class DiscoInfoQuery(Query):
    """
    Extends Query class.
    Contains information about features and identities.
    """
    elementUri = 'http://jabber.org/protocol/disco#info'

    identities = fields.ElementNode(Identity,
                                    required=False,
                                    listed=True,
                                    unique=True)
    features = fields.ElementNode(Feature,
                                  required=False,
                                  listed=True,
                                  unique=True)
    node = fields.StringAttr('node', required=False)
Пример #22
0
class DiscoItemsQuery(Query):
    """
    Extends Query class.
    
    Attibutes:
        items -- element node with DiscoItem
        
        node -- string attribute 'node'
            
    """
    elementUri = 'http://jabber.org/protocol/disco#items'

    items = fields.ElementNode(DiscoItem,
                               required=False,
                               listed=True,
                               unique=True)
    node = fields.StringAttr('node', required=False)
Пример #23
0
class Stanza(VElement):
    """
    Extends VElement class from twilix.base.
    Contains fields corresponding to the protocol.

    Base class for all base XMPP Stanzas (iq, message, presence).
    
    Attributes:
        to -- jid attribue 'to'
        
        from\_  -- jid attribue 'from'
        
        type  -- string attribue 'type'
        
        id  -- string attribue 'id'
        
        lang  -- string attribue 'xml:lang'
        
    """
    elementUri = (
        'jabber:client',
        'jabber:server',
        'jabber:component:accept',
        None,
    )

    to = fields.JidAttr('to', required=False)
    from_ = fields.JidAttr('from', required=False)
    type_ = fields.StringAttr('type', required=False)
    id = fields.StringAttr('id', required=False)
    lang = fields.StringAttr('xml:lang', required=False)

    def __init__(self, *args, **kwargs):
        """
        Makes a superclass intialization and set 
        attributes for deferred-style stanzas.
        """
        super(Stanza, self).__init__(*args, **kwargs)
        if 'result_class' in kwargs:
            self._result_class = kwargs['result_class']
        if 'error_class' in kwargs:
            self._error_class = kwargs['error_class']

    def __unicode__(self):
        """Overrrides unicode converter."""
        return self.toXml()

    def __repr__(self):
        """Makes avaliable to show stanza in xml format."""
        return self.toXml()

    def makeError(self, content):
        """
        Creates ErrorStanza from self and then returns it.
        Used to make Error Stanza as reply on any Stanza.
        
        :param content: Error element.
        
        :returns: Error Stanza with Error element.
                
        """
        res = ErrorStanza(to=self.from_,
                          from_=self.to,
                          type_='error',
                          el_name=self.elementName,
                          id=self.id,
                          error=content)
        res.children = self.children + res.children
        return res

    def get_reply(self):
        """
        Creates the reply stanza. 
        There is REPLY_CLASS (if defined) or self-type stanza's class.        
        """
        cls = getattr(self, 'REPLY_CLASS', None) or self.__class__
        return cls(to=self.from_, from_=self.to, type_=self.type_, id=self.id)
Пример #24
0
class DeleteNodeElement(VElement):
    elementName = 'delete'

    node = fields.StringAttr('node')
Пример #25
0
class ConfigureNode(VElement):
    elementName = 'configure'

    node = fields.StringAttr('node')
Пример #26
0
class Retract(VElement):
    elementName = 'retract'

    node = fields.StringAttr('node')
    items = fields.ElementNode(Item, listed=True)
Пример #27
0
class CreateNodeElement(VElement):
    elementName = 'create'

    node = fields.StringAttr('node')
Пример #28
0
class SubscribeElement(VElement):
    elementName = 'subscribe'

    node = fields.StringAttr('node')
    jid = fields.JidAttr('jid')
Пример #29
0
class Retract(VElement):
    elementName = 'retract'

    id_ = fields.StringAttr('id', required=True)
Пример #30
0
class UnsubscribeElement(SubscribeElement):
    elementName = 'unsubscribe'

    subid = fields.StringAttr('subid', required=False)