Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
-
0c33075e
by Philipp Hörist at 2019-08-15T17:43:16Z
-
18c9fd5a
by Philipp Hörist at 2019-08-16T15:39:56Z
-
2f4a79e0
by Philipp Hörist at 2019-08-16T15:40:04Z
-
d56945cc
by Philipp Hörist at 2019-08-17T10:46:28Z
6 changed files:
- nbxmpp/const.py
- nbxmpp/modules/discovery.py
- nbxmpp/modules/iq.py
- nbxmpp/modules/message.py
- nbxmpp/modules/presence.py
- nbxmpp/structs.py
Changes:
| ... | ... | @@ -255,36 +255,6 @@ class Role(Enum): |
| 255 | 255 |
return self == Role.NONE
|
| 256 | 256 |
|
| 257 | 257 |
|
| 258 |
-class Error(Enum):
|
|
| 259 |
- BAD_REQUEST = 'bad-request'
|
|
| 260 |
- CONFLICT = 'conflict'
|
|
| 261 |
- FEATURE_NOT_IMPLEMENTED = 'feature-not-implemented'
|
|
| 262 |
- FORBIDDEN = 'forbidden'
|
|
| 263 |
- GONE = 'gone'
|
|
| 264 |
- INTERNAL_SERVER_ERROR = 'internal-server-error'
|
|
| 265 |
- ITEM_NOT_FOUND = 'item-not-found'
|
|
| 266 |
- JID_MALFORMED = 'jid-malformed'
|
|
| 267 |
- NOT_ACCEPTABLE = 'not-acceptable'
|
|
| 268 |
- NOT_ALLOWED = 'not-allowed'
|
|
| 269 |
- NOT_AUTHORIZED = 'not-authorized'
|
|
| 270 |
- PAYMENT_REQUIRED = 'payment-required'
|
|
| 271 |
- RECIPIENT_UNAVAILABLE = 'recipient-unavailable'
|
|
| 272 |
- REDIRECT = 'redirect'
|
|
| 273 |
- REGISTRATION_REQUIRED = 'registration-required'
|
|
| 274 |
- REMOTE_SERVER_NOT_FOUND = 'remote-server-not-found'
|
|
| 275 |
- REMOTE_SERVER_TIMEOUT = 'remote-server-timeout'
|
|
| 276 |
- RESOURCE_CONSTRAINT = 'resource-constraint'
|
|
| 277 |
- SERVICE_UNAVAILABLE = 'service-unavailable'
|
|
| 278 |
- SUBSCRIPTION_REQUIRED = 'subscription-required'
|
|
| 279 |
- UNDEFINED_CONDITION = 'undefined-condition'
|
|
| 280 |
- UNEXPECTED_REQUEST = 'unexpected-request'
|
|
| 281 |
- POLICY_VIOLATION = 'policy-violation'
|
|
| 282 |
- UNKNOWN_ERROR = 'unknown-error'
|
|
| 283 |
- |
|
| 284 |
- def __str__(self):
|
|
| 285 |
- return self.value
|
|
| 286 |
- |
|
| 287 |
- |
|
| 288 | 258 |
class BookmarkStoreType(Enum):
|
| 289 | 259 |
PUBSUB = 'pubsub'
|
| 290 | 260 |
PRIVATE = 'private'
|
| ... | ... | @@ -15,6 +15,7 @@ |
| 15 | 15 |
# You should have received a copy of the GNU General Public License
|
| 16 | 16 |
# along with this program; If not, see <http://www.gnu.org/licenses/>.
|
| 17 | 17 |
|
| 18 |
+import time
|
|
| 18 | 19 |
import logging
|
| 19 | 20 |
|
| 20 | 21 |
from nbxmpp.protocol import Iq
|
| ... | ... | @@ -63,11 +64,14 @@ class Discovery: |
| 63 | 64 |
return parse_disco_items(stanza)
|
| 64 | 65 |
|
| 65 | 66 |
|
| 66 |
-def parse_disco_info(stanza):
|
|
| 67 |
+def parse_disco_info(stanza, timestamp=None):
|
|
| 67 | 68 |
idenities = []
|
| 68 | 69 |
features = []
|
| 69 | 70 |
dataforms = []
|
| 70 | 71 |
|
| 72 |
+ if timestamp is None:
|
|
| 73 |
+ timestamp = time.time()
|
|
| 74 |
+ |
|
| 71 | 75 |
query = stanza.getQuery()
|
| 72 | 76 |
for node in query.getTags('identity'):
|
| 73 | 77 |
attrs = node.getAttrs()
|
| ... | ... | @@ -89,11 +93,11 @@ def parse_disco_info(stanza): |
| 89 | 93 |
for node in query.getTags('x', namespace=NS_DATA):
|
| 90 | 94 |
dataforms.append(extend_form(node))
|
| 91 | 95 |
|
| 92 |
- return DiscoInfo(jid=stanza.getFrom(),
|
|
| 93 |
- node=query.getAttr('node'),
|
|
| 96 |
+ return DiscoInfo(stanza=stanza,
|
|
| 94 | 97 |
identities=idenities,
|
| 95 | 98 |
features=features,
|
| 96 |
- dataforms=dataforms)
|
|
| 99 |
+ dataforms=dataforms,
|
|
| 100 |
+ timestamp=timestamp)
|
|
| 97 | 101 |
|
| 98 | 102 |
|
| 99 | 103 |
def parse_disco_items(stanza):
|
| ... | ... | @@ -21,7 +21,7 @@ from nbxmpp.protocol import Error as ErrorStanza |
| 21 | 21 |
from nbxmpp.protocol import ERR_BAD_REQUEST
|
| 22 | 22 |
from nbxmpp.protocol import NodeProcessed
|
| 23 | 23 |
from nbxmpp.structs import StanzaHandler
|
| 24 |
-from nbxmpp.structs import ErrorProperties
|
|
| 24 |
+from nbxmpp.util import error_factory
|
|
| 25 | 25 |
from nbxmpp.const import IqType
|
| 26 | 26 |
|
| 27 | 27 |
log = logging.getLogger('nbxmpp.m.iq')
|
| ... | ... | @@ -57,4 +57,4 @@ class BaseIq: |
| 57 | 57 |
properties.query = stanza.getQuery()
|
| 58 | 58 |
|
| 59 | 59 |
if properties.type.is_error:
|
| 60 |
- properties.error = ErrorProperties(stanza)
|
|
| 60 |
+ properties.error = error_factory(stanza)
|
| ... | ... | @@ -19,8 +19,8 @@ import logging |
| 19 | 19 |
|
| 20 | 20 |
from nbxmpp.protocol import NodeProcessed
|
| 21 | 21 |
from nbxmpp.structs import StanzaHandler
|
| 22 |
-from nbxmpp.structs import ErrorProperties
|
|
| 23 | 22 |
from nbxmpp.structs import StanzaIDData
|
| 23 |
+from nbxmpp.util import error_factory
|
|
| 24 | 24 |
from nbxmpp.const import MessageType
|
| 25 | 25 |
|
| 26 | 26 |
log = logging.getLogger('nbxmpp.m.message')
|
| ... | ... | @@ -50,7 +50,7 @@ class BaseMessage: |
| 50 | 50 |
properties.stanza_id = StanzaIDData(id=id_, by=by)
|
| 51 | 51 |
|
| 52 | 52 |
if properties.type.is_error:
|
| 53 |
- properties.error = ErrorProperties(stanza)
|
|
| 53 |
+ properties.error = error_factory(stanza)
|
|
| 54 | 54 |
|
| 55 | 55 |
@staticmethod
|
| 56 | 56 |
def _process_message_after_base(_con, stanza, properties):
|
| ... | ... | @@ -21,7 +21,7 @@ from nbxmpp.protocol import Error as ErrorStanza |
| 21 | 21 |
from nbxmpp.protocol import ERR_BAD_REQUEST
|
| 22 | 22 |
from nbxmpp.protocol import NodeProcessed
|
| 23 | 23 |
from nbxmpp.structs import StanzaHandler
|
| 24 |
-from nbxmpp.structs import ErrorProperties
|
|
| 24 |
+from nbxmpp.util import error_factory
|
|
| 25 | 25 |
from nbxmpp.const import PresenceType
|
| 26 | 26 |
from nbxmpp.const import PresenceShow
|
| 27 | 27 |
|
| ... | ... | @@ -46,7 +46,7 @@ class BasePresence: |
| 46 | 46 |
properties.status = stanza.getStatus()
|
| 47 | 47 |
|
| 48 | 48 |
if properties.type.is_error:
|
| 49 |
- properties.error = ErrorProperties(stanza)
|
|
| 49 |
+ properties.error = error_factory(stanza)
|
|
| 50 | 50 |
|
| 51 | 51 |
own_jid = self._client.get_bound_jid()
|
| 52 | 52 |
properties.self_presence = own_jid == properties.jid
|
| ... | ... | @@ -29,7 +29,6 @@ from nbxmpp.const import MessageType |
| 29 | 29 |
from nbxmpp.const import AvatarState
|
| 30 | 30 |
from nbxmpp.const import StatusCode
|
| 31 | 31 |
from nbxmpp.const import PresenceType
|
| 32 |
-from nbxmpp.const import Error
|
|
| 33 | 32 |
from nbxmpp.const import LOCATION_DATA
|
| 34 | 33 |
from nbxmpp.const import AdHocStatus
|
| 35 | 34 |
|
| ... | ... | @@ -119,13 +118,13 @@ DiscoItem = namedtuple('DiscoItem', 'jid name node') |
| 119 | 118 |
DiscoItem.__new__.__defaults__ = (None, None)
|
| 120 | 119 |
|
| 121 | 120 |
|
| 122 |
-class DiscoInfo(namedtuple('DiscoInfo', 'jid node identities features dataforms')):
|
|
| 121 |
+class DiscoInfo(namedtuple('DiscoInfo', 'stanza identities features dataforms timestamp')):
|
|
| 123 | 122 |
|
| 124 | 123 |
__slots__ = []
|
| 125 | 124 |
|
| 126 |
- def __new__(cls, jid, node, identities, features, dataforms):
|
|
| 127 |
- return super(DiscoInfo, cls).__new__(cls, jid, node, identities,
|
|
| 128 |
- features, dataforms)
|
|
| 125 |
+ def __new__(cls, stanza, identities, features, dataforms, timestamp=None):
|
|
| 126 |
+ return super(DiscoInfo, cls).__new__(cls, stanza, identities,
|
|
| 127 |
+ features, dataforms, timestamp)
|
|
| 129 | 128 |
|
| 130 | 129 |
def get_caps_hash(self):
|
| 131 | 130 |
try:
|
| ... | ... | @@ -150,6 +149,29 @@ class DiscoInfo(namedtuple('DiscoInfo', 'jid node identities features dataforms' |
| 150 | 149 |
def supports(self, feature):
|
| 151 | 150 |
return feature in self.features
|
| 152 | 151 |
|
| 152 |
+ def serialize(self):
|
|
| 153 |
+ if self.stanza is None:
|
|
| 154 |
+ raise ValueError('Unable to serialize DiscoInfo, no stanza found')
|
|
| 155 |
+ return str(self.stanza)
|
|
| 156 |
+ |
|
| 157 |
+ @property
|
|
| 158 |
+ def node(self):
|
|
| 159 |
+ try:
|
|
| 160 |
+ query = self.stanza.getQuery()
|
|
| 161 |
+ except Exception:
|
|
| 162 |
+ return None
|
|
| 163 |
+ |
|
| 164 |
+ if query is not None:
|
|
| 165 |
+ return query.getAttr('node')
|
|
| 166 |
+ return None
|
|
| 167 |
+ |
|
| 168 |
+ @property
|
|
| 169 |
+ def jid(self):
|
|
| 170 |
+ try:
|
|
| 171 |
+ return self.stanza.getFrom()
|
|
| 172 |
+ except Exception:
|
|
| 173 |
+ return None
|
|
| 174 |
+ |
|
| 153 | 175 |
@property
|
| 154 | 176 |
def mam_namespace(self):
|
| 155 | 177 |
if NS_MAM_2 in self.features:
|
| ... | ... | @@ -185,7 +207,7 @@ class DiscoInfo(namedtuple('DiscoInfo', 'jid node identities features dataforms' |
| 185 | 207 |
|
| 186 | 208 |
@property
|
| 187 | 209 |
def muc_room_name(self):
|
| 188 |
- return self._get_form_value(NS_MUC_INFO, 'muc#roomconfig_roomname')
|
|
| 210 |
+ return self._get_form_value(NS_MUC_INFO, 'muc#roomconfig_roomname')
|
|
| 189 | 211 |
|
| 190 | 212 |
@property
|
| 191 | 213 |
def muc_description(self):
|
| ... | ... | @@ -625,20 +647,3 @@ class PresenceProperties: |
| 625 | 647 |
return self.muc_user.role
|
| 626 | 648 |
except Exception:
|
| 627 | 649 |
return None
|
| 628 |
- |
|
| 629 |
- |
|
| 630 |
-class ErrorProperties:
|
|
| 631 |
- def __init__(self, stanza):
|
|
| 632 |
- for child in stanza.getTag('error').getChildren():
|
|
| 633 |
- if child.getNamespace() == NS_STANZAS:
|
|
| 634 |
- try:
|
|
| 635 |
- self.type = Error(child.name)
|
|
| 636 |
- except ValueError:
|
|
| 637 |
- self.type = Error('unknown-error')
|
|
| 638 |
- break
|
|
| 639 |
- self.legacy_code = stanza.getErrorCode()
|
|
| 640 |
- self.legacy_type = stanza.getErrorType()
|
|
| 641 |
- self.message = stanza.getErrorMsg()
|
|
| 642 |
- |
|
| 643 |
- def __str__(self):
|
|
| 644 |
- return '%s %s' % (self.type, self.message)
|