]> code.delx.au - pymsnt/blob - src/tlib/jabber/jid.py
dccc7b6bf24320f9a79cf03e430817cbc3c11a8c
[pymsnt] / src / tlib / jabber / jid.py
1 # -*- test-case-name: twisted.test.test_jabberjid -*-
2 #
3 # Twisted, the Framework of Your Internet
4 # Copyright (C) 2001 Matthew W. Lefkowitz
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of version 2.1 of the GNU Lesser General Public
8 # License as published by the Free Software Foundation.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 from twisted.internet import reactor, protocol, defer
20 from tlib import domish
21 from tlib.jabber.xmpp_stringprep import nodeprep, resourceprep, nameprep
22
23 class InvalidFormat(Exception):
24 pass
25
26 def parse(jidstring):
27 user = None
28 server = None
29 resource = None
30
31 # Search for delimiters
32 user_sep = jidstring.find("@")
33 res_sep = jidstring.find("/")
34
35 if user_sep == -1:
36 if res_sep == -1:
37 # host
38 server = jidstring
39 else:
40 # host/resource
41 server = jidstring[0:res_sep]
42 resource = jidstring[res_sep + 1:] or None
43 else:
44 if res_sep == -1:
45 # user@host
46 user = jidstring[0:user_sep] or None
47 server = jidstring[user_sep + 1:]
48 else:
49 if user_sep < res_sep:
50 # user@host/resource
51 user = jidstring[0:user_sep] or None
52 server = jidstring[user_sep + 1:user_sep + (res_sep - user_sep)]
53 resource = jidstring[res_sep + 1:] or None
54 else:
55 # server/resource (with an @ in resource)
56 server = jidstring[0:res_sep]
57 resource = jidstring[res_sep + 1:] or None
58
59 # Return the tuple
60 return prep(user, server, resource)
61
62
63 def prep(user, server, resource):
64 """ Stringprep, backported from Twisted 2.0 """
65
66 if user:
67 try:
68 user = nodeprep.prepare(unicode(user))
69 except UnicodeError:
70 raise InvalidFormat, "Invalid character in username"
71 else:
72 user = None
73
74 if not server:
75 raise InvalidFormat, "Server address required."
76 else:
77 try:
78 server = nameprep.prepare(unicode(server))
79 except UnicodeError:
80 raise InvalidFormat, "Invalid character in resource"
81
82 if resource:
83 try:
84 resource = resourceprep.prepare(unicode(resource))
85 except UnicodeError:
86 raise InvalidFormat, "Invalid character in resource"
87 else:
88 resource = None
89
90 return (user, server, resource)
91
92
93
94 __internJIDs = {}
95
96 def intern(str):
97 # XXX: Ensure that stringprep'd jids map to same JID
98 if str in __internJIDs:
99 return __internJIDs[str]
100 else:
101 j = JID(str)
102 __internJIDs[str] = j
103 return j
104
105 class JID:
106 def __init__(self, str = None, tuple = None):
107 assert (str or tuple)
108
109 if str:
110 user, host, res = parse(str)
111 else:
112 user, host, res = tuple
113
114 self.host = host
115 self.user = user
116 self.resource = res
117
118 def userhost(self):
119 if self.user:
120 return "%s@%s" % (self.user, self.host)
121 else:
122 return self.host
123
124 def userhostJID(self):
125 if self.resource:
126 if "_uhjid" not in self.__dict__:
127 self._uhjid = jid.intern(self.userhost())
128 return self._uhjid
129 else:
130 return self
131
132 def full(self):
133 if self.user:
134 if self.resource:
135 return "%s@%s/%s" % (self.user, self.host, self.resource)
136 else:
137 return "%s@%s" % (self.user, self.host)
138 else:
139 if self.resource:
140 return "%s/%s" % (self.host, self.resource)
141 else:
142 return self.host
143
144 def __eq__(self, other):
145 return (self.user == other.user and
146 self.host == other.host and
147 self.resource == other.resource)
148
149 def __ne__(self, other):
150 return not (self.user == other.user and
151 self.host == other.host and
152 self.resource == other.resource)