Philipp Hörist pushed to branch master at gajim / python-nbxmpp

Commits:

1 changed file:

Changes:

  • nbxmpp/modules/mam.py
    ... ... @@ -18,19 +18,18 @@
    18 18
     
    
    19 19
     from nbxmpp.protocol import JID
    
    20 20
     from nbxmpp.protocol import Iq
    
    21
    -from nbxmpp.protocol import isResultNode
    
    22 21
     from nbxmpp.protocol import Node
    
    23 22
     from nbxmpp.namespaces import Namespace
    
    24 23
     from nbxmpp.structs import MAMQueryData
    
    25 24
     from nbxmpp.structs import MAMPreferencesData
    
    26
    -from nbxmpp.structs import CommonResult
    
    27
    -from nbxmpp.util import call_on_response
    
    28
    -from nbxmpp.util import callback
    
    29
    -from nbxmpp.util import raise_error
    
    25
    +from nbxmpp.task import iq_request_task
    
    26
    +from nbxmpp.errors import StanzaError
    
    27
    +from nbxmpp.errors import MalformedStanzaError
    
    28
    +from nbxmpp.modules.base import BaseModule
    
    30 29
     from nbxmpp.modules.rsm import parse_rsm
    
    31 30
     from nbxmpp.modules.dataforms import SimpleDataForm
    
    32 31
     from nbxmpp.modules.dataforms import create_field
    
    33
    -from nbxmpp.modules.base import BaseModule
    
    32
    +from nbxmpp.modules.util import process_response
    
    34 33
     
    
    35 34
     
    
    36 35
     class MAM(BaseModule):
    
    ... ... @@ -40,7 +39,7 @@ class MAM(BaseModule):
    40 39
             self._client = client
    
    41 40
             self.handlers = []
    
    42 41
     
    
    43
    -    @call_on_response('_query_result')
    
    42
    +    @iq_request_task
    
    44 43
         def make_query(self,
    
    45 44
                        jid,
    
    46 45
                        queryid=None,
    
    ... ... @@ -50,166 +49,155 @@ class MAM(BaseModule):
    50 49
                        after=None,
    
    51 50
                        max_=70):
    
    52 51
     
    
    53
    -        iq = Iq(typ='set', to=jid, queryNS=Namespace.MAM_2)
    
    54
    -        if queryid is not None:
    
    55
    -            iq.getQuery().setAttr('queryid', queryid)
    
    56
    -
    
    57
    -        payload = [
    
    58
    -            self._make_query_form(start, end, with_),
    
    59
    -            self._make_rsm_query(max_, after)
    
    60
    -        ]
    
    61
    -
    
    62
    -        iq.setQueryPayload(payload)
    
    63
    -        return iq
    
    64
    -
    
    65
    -    @staticmethod
    
    66
    -    def _make_query_form(start, end, with_):
    
    67
    -        fields = [
    
    68
    -            create_field(typ='hidden', var='FORM_TYPE', value=Namespace.MAM_2)
    
    69
    -        ]
    
    70
    -
    
    71
    -        if start:
    
    72
    -            fields.append(create_field(
    
    73
    -                typ='text-single',
    
    74
    -                var='start',
    
    75
    -                value=start.strftime('%Y-%m-%dT%H:%M:%SZ')))
    
    76
    -
    
    77
    -        if end:
    
    78
    -            fields.append(create_field(
    
    79
    -                typ='text-single',
    
    80
    -                var='end',
    
    81
    -                value=end.strftime('%Y-%m-%dT%H:%M:%SZ')))
    
    82
    -
    
    83
    -        if with_:
    
    84
    -            fields.append(create_field(
    
    85
    -                typ='jid-single',
    
    86
    -                var='with',
    
    87
    -                value=with_))
    
    88
    -
    
    89
    -        return SimpleDataForm(type_='submit', fields=fields)
    
    90
    -
    
    91
    -    @staticmethod
    
    92
    -    def _make_rsm_query(max_, after):
    
    93
    -        rsm_set = Node('set', attrs={'xmlns': Namespace.RSM})
    
    94
    -        if max_ is not None:
    
    95
    -            rsm_set.setTagData('max', max_)
    
    96
    -        if after is not None:
    
    97
    -            rsm_set.setTagData('after', after)
    
    98
    -        return rsm_set
    
    99
    -
    
    100
    -    @callback
    
    101
    -    def _query_result(self, stanza):
    
    102
    -        if not isResultNode(stanza):
    
    103
    -            return raise_error(self._log.info, stanza)
    
    104
    -
    
    105
    -        jid = stanza.getFrom()
    
    106
    -        fin = stanza.getTag('fin', namespace=Namespace.MAM_2)
    
    52
    +        _task = yield
    
    53
    +
    
    54
    +        response = yield _make_request(jid, queryid,
    
    55
    +                                       start, end, with_, after, max_)
    
    56
    +        if response.isError():
    
    57
    +            raise StanzaError(response)
    
    58
    +
    
    59
    +        jid = response.getFrom()
    
    60
    +        fin = response.getTag('fin', namespace=Namespace.MAM_2)
    
    107 61
             if fin is None:
    
    108
    -            return raise_error(self._log.warning,
    
    109
    -                               stanza,
    
    110
    -                               'stanza-malformed',
    
    111
    -                               'No fin node found')
    
    62
    +            raise MalformedStanzaError('fin node missing', response)
    
    112 63
     
    
    113 64
             rsm = parse_rsm(fin)
    
    114 65
             if rsm is None:
    
    115
    -            return raise_error(self._log.warning,
    
    116
    -                               stanza,
    
    117
    -                               'stanza-malformed',
    
    118
    -                               'rsm set missing')
    
    66
    +            raise MalformedStanzaError('rsm set missing', response)
    
    119 67
     
    
    120 68
             complete = fin.getAttr('complete') == 'true'
    
    121 69
             if not complete:
    
    122 70
                 if rsm.first is None or rsm.last is None:
    
    123
    -                return raise_error(self._log.warning,
    
    124
    -                                   stanza,
    
    125
    -                                   'stanza-malformed',
    
    126
    -                                   'missing first or last element')
    
    71
    +                raise MalformedStanzaError('first or last element missing',
    
    72
    +                                           response)
    
    127 73
     
    
    128
    -        return MAMQueryData(jid=jid,
    
    129
    -                            complete=complete,
    
    130
    -                            rsm=rsm)
    
    74
    +        yield MAMQueryData(jid=jid,
    
    75
    +                           complete=complete,
    
    76
    +                           rsm=rsm)
    
    131 77
     
    
    132
    -    @call_on_response('_preferences_result')
    
    78
    +    @iq_request_task
    
    133 79
         def request_preferences(self):
    
    134
    -        iq = Iq('get', queryNS=Namespace.MAM_2)
    
    135
    -        iq.setQuery('prefs')
    
    136
    -        return iq
    
    80
    +        _task = yield
    
    137 81
     
    
    138
    -    @callback
    
    139
    -    def _preferences_result(self, stanza):
    
    140
    -        if not isResultNode(stanza):
    
    141
    -            return raise_error(self._log.info, stanza)
    
    82
    +        response = yield _make_pref_request()
    
    83
    +        if response.isError():
    
    84
    +            raise StanzaError(response)
    
    142 85
     
    
    143
    -        prefs = stanza.getTag('prefs', namespace=Namespace.MAM_2)
    
    86
    +        prefs = response.getTag('prefs', namespace=Namespace.MAM_2)
    
    144 87
             if prefs is None:
    
    145
    -            return raise_error(self._log.warning,
    
    146
    -                               stanza,
    
    147
    -                               'stanza-malformed',
    
    148
    -                               'No prefs node found')
    
    88
    +            raise MalformedStanzaError('prefs node missing', response)
    
    149 89
     
    
    150 90
             default = prefs.getAttr('default')
    
    151 91
             if default is None:
    
    152
    -            return raise_error(self._log.warning,
    
    153
    -                               stanza,
    
    154
    -                               'stanza-malformed',
    
    155
    -                               'No default attr found')
    
    92
    +            raise MalformedStanzaError('default attr missing', response)
    
    156 93
     
    
    157 94
             always_node = prefs.getTag('always')
    
    158 95
             if always_node is None:
    
    159
    -            return raise_error(self._log.warning,
    
    160
    -                               stanza,
    
    161
    -                               'stanza-malformed',
    
    162
    -                               'No always node found')
    
    96
    +            raise MalformedStanzaError('always node missing', response)
    
    163 97
     
    
    164
    -        always = self._get_preference_jids(always_node)
    
    98
    +        always = _get_preference_jids(always_node)
    
    165 99
     
    
    166 100
             never_node = prefs.getTag('never')
    
    167 101
             if never_node is None:
    
    168
    -            return raise_error(self._log.warning,
    
    169
    -                               stanza,
    
    170
    -                               'stanza-malformed',
    
    171
    -                               'No never node found')
    
    172
    -
    
    173
    -        never = self._get_preference_jids(never_node)
    
    174
    -        return MAMPreferencesData(default=default,
    
    175
    -                                  always=always,
    
    176
    -                                  never=never)
    
    177
    -
    
    178
    -    def _get_preference_jids(self, node):
    
    179
    -        jids = []
    
    180
    -        for item in node.getTags('jid'):
    
    181
    -            jid = item.getData()
    
    182
    -            if not jid:
    
    183
    -                continue
    
    184
    -
    
    185
    -            try:
    
    186
    -                jid = JID.from_string(jid)
    
    187
    -            except Exception:
    
    188
    -                self._log.warning('Invalid jid found in preferences: %s',
    
    189
    -                                  jid)
    
    190
    -            jids.append(jid)
    
    191
    -        return jids
    
    192
    -
    
    193
    -    @call_on_response('_default_response')
    
    102
    +            raise MalformedStanzaError('never node missing', response)
    
    103
    +
    
    104
    +        never = _get_preference_jids(never_node)
    
    105
    +        yield MAMPreferencesData(default=default,
    
    106
    +                                 always=always,
    
    107
    +                                 never=never)
    
    108
    +
    
    109
    +    @iq_request_task
    
    194 110
         def set_preferences(self, default, always, never):
    
    111
    +        _task = yield
    
    112
    +
    
    195 113
             if default not in ('always', 'never', 'roster'):
    
    196 114
                 raise ValueError('Wrong default preferences type')
    
    197 115
     
    
    198
    -        iq = Iq(typ='set')
    
    199
    -        prefs = iq.addChild(name='prefs',
    
    200
    -                            namespace=Namespace.MAM_2,
    
    201
    -                            attrs={'default': default})
    
    202
    -        always_node = prefs.addChild(name='always')
    
    203
    -        never_node = prefs.addChild(name='never')
    
    204
    -        for jid in always:
    
    205
    -            always_node.addChild(name='jid').setData(jid)
    
    206
    -
    
    207
    -        for jid in never:
    
    208
    -            never_node.addChild(name='jid').setData(jid)
    
    209
    -        return iq
    
    210
    -
    
    211
    -    @callback
    
    212
    -    def _default_response(self, stanza):
    
    213
    -        if not isResultNode(stanza):
    
    214
    -            return raise_error(self._log.info, stanza)
    
    215
    -        return CommonResult(jid=stanza.getFrom())
    116
    +        response = yield _make_set_pref_request(default, always, never)
    
    117
    +        yield process_response(response)
    
    118
    +
    
    119
    +
    
    120
    +def _make_query_form(start, end, with_):
    
    121
    +    fields = [
    
    122
    +        create_field(typ='hidden', var='FORM_TYPE', value=Namespace.MAM_2)
    
    123
    +    ]
    
    124
    +
    
    125
    +    if start:
    
    126
    +        fields.append(create_field(
    
    127
    +            typ='text-single',
    
    128
    +            var='start',
    
    129
    +            value=start.strftime('%Y-%m-%dT%H:%M:%SZ')))
    
    130
    +
    
    131
    +    if end:
    
    132
    +        fields.append(create_field(
    
    133
    +            typ='text-single',
    
    134
    +            var='end',
    
    135
    +            value=end.strftime('%Y-%m-%dT%H:%M:%SZ')))
    
    136
    +
    
    137
    +    if with_:
    
    138
    +        fields.append(create_field(
    
    139
    +            typ='jid-single',
    
    140
    +            var='with',
    
    141
    +            value=with_))
    
    142
    +
    
    143
    +    return SimpleDataForm(type_='submit', fields=fields)
    
    144
    +
    
    145
    +
    
    146
    +def _make_rsm_query(max_, after):
    
    147
    +    rsm_set = Node('set', attrs={'xmlns': Namespace.RSM})
    
    148
    +    if max_ is not None:
    
    149
    +        rsm_set.setTagData('max', max_)
    
    150
    +    if after is not None:
    
    151
    +        rsm_set.setTagData('after', after)
    
    152
    +    return rsm_set
    
    153
    +
    
    154
    +
    
    155
    +def _make_request(jid, queryid, start, end, with_, after, max_):
    
    156
    +    iq = Iq(typ='set', to=jid, queryNS=Namespace.MAM_2)
    
    157
    +    if queryid is not None:
    
    158
    +        iq.getQuery().setAttr('queryid', queryid)
    
    159
    +
    
    160
    +    payload = [
    
    161
    +        _make_query_form(start, end, with_),
    
    162
    +        _make_rsm_query(max_, after)
    
    163
    +    ]
    
    164
    +
    
    165
    +    iq.setQueryPayload(payload)
    
    166
    +    return iq
    
    167
    +
    
    168
    +
    
    169
    +def _make_pref_request():
    
    170
    +    iq = Iq('get', queryNS=Namespace.MAM_2)
    
    171
    +    iq.setQuery('prefs')
    
    172
    +    return iq
    
    173
    +
    
    174
    +
    
    175
    +def _get_preference_jids(node):
    
    176
    +    jids = []
    
    177
    +    for item in node.getTags('jid'):
    
    178
    +        jid = item.getData()
    
    179
    +        if not jid:
    
    180
    +            continue
    
    181
    +
    
    182
    +        try:
    
    183
    +            jid = JID.from_string(jid)
    
    184
    +        except Exception:
    
    185
    +            continue
    
    186
    +
    
    187
    +        jids.append(jid)
    
    188
    +    return jids
    
    189
    +
    
    190
    +
    
    191
    +def _make_set_pref_request(default, always, never):
    
    192
    +    iq = Iq(typ='set')
    
    193
    +    prefs = iq.addChild(name='prefs',
    
    194
    +                        namespace=Namespace.MAM_2,
    
    195
    +                        attrs={'default': default})
    
    196
    +    always_node = prefs.addChild(name='always')
    
    197
    +    never_node = prefs.addChild(name='never')
    
    198
    +    for jid in always:
    
    199
    +        always_node.addChild(name='jid').setData(jid)
    
    200
    +
    
    201
    +    for jid in never:
    
    202
    +        never_node.addChild(name='jid').setData(jid)
    
    203
    +    return iq