1
# -*- test-case-name: twisted.words.test.test_jabberjid -*-
3
# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
4
# See LICENSE for details.
7
Jabber Identifier support.
9
This module provides an object to represent Jabber Identifiers (JIDs) and
10
parse string representations into them with proper checking for illegal
11
characters, case folding and canonicalisation through L{stringprep<twisted.words.protocols.jabber.xmpp_stringprep>}.
14
from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep, resourceprep, nameprep
16
class InvalidFormat(Exception):
18
The given string could not be parsed into a valid Jabber Identifier (JID).
23
Parse given JID string into its respective parts and apply stringprep.
25
@param jidstring: string representation of a JID.
26
@type jidstring: C{unicode}
27
@return: tuple of (user, host, resource), each of type C{unicode} as
28
the parsed and stringprep'd parts of the given JID. If the
29
given string did not have a user or resource part, the respective
30
field in the tuple will hold C{None}.
37
# Search for delimiters
38
user_sep = jidstring.find("@")
39
res_sep = jidstring.find("/")
47
host = jidstring[0:res_sep]
48
resource = jidstring[res_sep + 1:] or None
52
user = jidstring[0:user_sep] or None
53
host = jidstring[user_sep + 1:]
55
if user_sep < res_sep:
57
user = jidstring[0:user_sep] or None
58
host = jidstring[user_sep + 1:user_sep + (res_sep - user_sep)]
59
resource = jidstring[res_sep + 1:] or None
61
# host/resource (with an @ in resource)
62
host = jidstring[0:res_sep]
63
resource = jidstring[res_sep + 1:] or None
65
return prep(user, host, resource)
67
def prep(user, host, resource):
69
Perform stringprep on all JID fragments.
71
@param user: The user part of the JID.
72
@type user: C{unicode}
73
@param host: The host part of the JID.
74
@type host: C{unicode}
75
@param resource: The resource part of the JID.
76
@type resource: C{unicode}
77
@return: The given parts with stringprep applied.
83
user = nodeprep.prepare(unicode(user))
85
raise InvalidFormat, "Invalid character in username"
90
raise InvalidFormat, "Server address required."
93
host = nameprep.prepare(unicode(host))
95
raise InvalidFormat, "Invalid character in hostname"
99
resource = resourceprep.prepare(unicode(resource))
101
raise InvalidFormat, "Invalid character in resource"
105
return (user, host, resource)
109
def internJID(jidstring):
116
if jidstring in __internJIDs:
117
return __internJIDs[jidstring]
120
__internJIDs[jidstring] = j
125
Represents a stringprep'd Jabber ID.
127
JID objects are hashable so they can be used in sets and as keys in
131
def __init__(self, str=None, tuple=None):
132
if not (str or tuple):
133
raise RuntimeError("You must provide a value for either 'str' or "
134
"'tuple' arguments.")
137
user, host, res = parse(str)
139
user, host, res = prep(*tuple)
147
Extract the bare JID as a unicode string.
149
A bare JID does not have a resource part, so this returns either
150
C{user@host} or just C{host}.
155
return u"%s@%s" % (self.user, self.host)
159
def userhostJID(self):
161
Extract the bare JID.
163
A bare JID does not have a resource part, so this returns a
164
L{JID} object representing either C{user@host} or just C{host}.
166
If the object this method is called upon doesn't have a resource
167
set, it will return itself. Otherwise, the bare JID object will
168
be created, interned using L{internJID}.
173
return internJID(self.userhost())
179
Return the string representation of this JID.
185
return u"%s@%s/%s" % (self.user, self.host, self.resource)
187
return u"%s@%s" % (self.user, self.host)
190
return u"%s/%s" % (self.host, self.resource)
194
def __eq__(self, other):
198
L{JID}s compare equal if their user, host and resource parts all
199
compare equal. When comparing against instances of other types, it
200
uses the default comparison.
202
if isinstance(other, JID):
203
return (self.user == other.user and
204
self.host == other.host and
205
self.resource == other.resource)
207
return NotImplemented
209
def __ne__(self, other):
211
Inequality comparison.
213
This negates L{__eq__} for comparison with JIDs and uses the default
214
comparison for other types.
216
result = self.__eq__(other)
217
if result is NotImplemented:
226
L{JID}s with identical constituent user, host and resource parts have
227
equal hash values. In combination with the comparison defined on JIDs,
228
this allows for using L{JID}s in sets and as dictionary keys.
230
return hash((self.user, self.host, self.resource))
232
def __unicode__(self):
234
Get unicode representation.
236
Return the string representation of this JID as a unicode string.
244
Get object representation.
246
Returns a string that would create a new JID object that compares equal
249
return 'JID(%r)' % self.full()