1 # This file is part of python-rwhoisd
3 # Copyright (C) 2003, David E. Blacka
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 # This modules contains classes that are fairly general to RWhois
23 class RwhoisError(Exception):
26 # The RWhois error codes. Most of these won't ever be used.
27 error_codes = { 120 : "Registration Deferred",
28 130 : "Object Not Authoritative",
29 230 : "No Objects Found",
30 320 : "Invalid Attribute",
31 321 : "Invalid Attribute Syntax",
32 322 : "Required Attribute Missing",
33 323 : "Object Reference Not Found",
34 324 : "Primary Key Not Unique",
35 325 : "Failed to Update Stale Object",
36 330 : "Exceeded Response Limit",
37 331 : "Invalid Limit",
38 332 : "Nothing To Transfer",
39 333 : "Not Master for Authority Area",
40 336 : "Object Not Found",
41 338 : "Invalid Directive Syntax",
42 340 : "Invalid Authority Area",
43 341 : "Invalid Class",
44 342 : "Invalid Host/Port",
45 350 : "Invalid Query Syntax",
46 351 : "Query Too Complex",
47 352 : "Invalid Security Method",
48 353 : "Authentication Failed",
49 354 : "Encryption Failed",
50 360 : "Corrupt Data. Keyadd Failed",
51 400 : "Directive Not Available",
52 401 : "Not Authorized For Directive",
53 402 : "Unidentified Error",
54 420 : "Registration Not Authorized",
55 436 : "Invalid Display Format",
56 500 : "Memory Allocation Problem",
57 501 : "Service Not Available",
58 502 : "Unrecoverable Error",
59 503 : "Idle Time Exceeded",
63 def error_message(value):
67 except (TypeError, ValueError):
75 return "%%error %d %s: %s\r\n" % \
76 (code, error_codes.get(code, 402), msg)
78 return "%%error %d %s\r\n" % (code, error_codes.get(code, 402))
84 """This is the standard class for RWhois data objects."""
90 def get_attr(self, attr, default=None):
91 """This returns a list of values associated with a particular
92 attribute. The default value, if supplied, must be a single
93 (non-sequence) value."""
96 return self.data.get(attr.strip().lower(), [default])
97 return self.data.get(attr.strip().lower(), [])
99 def get_attr_value(self, attr, default=None):
100 """This returns a single value associated with the attribute.
101 If the attribute has multiple values, the first is
104 return self.data.get(attr.strip().lower(), [default])[0]
106 def has_attr(self, attr):
107 return self.data.has_key(attr.strip().lower())
110 """Return the RWhois ID of this object."""
112 return self.get_attr_value("id")
114 def add_attr(self, attr, value):
115 """Adds an attribute to the object."""
117 attr = attr.strip().lower()
118 if self.data.has_key(attr): self.data[attr].append(value)
120 self.attr_order.append(attr)
121 self.data.setdefault(attr, []).append(value)
123 def add_attrs(self, attr_list):
124 """Adds a list of (attribute, value) tuples to the object."""
125 for attr, value in attr_list:
126 self.add_attr(attr, value)
129 """Returns the list of (attribute, value) tuples (actually 2
130 elements lists). Attributes with multiple values produce
131 multiple tuples. The items are returned in the same order
132 they were added to the object."""
134 return [ [x, y] for x in self.attr_order for y in self.data[x] ]
137 """Return the list of values in this object."""
139 return [ x for y in self.data.values() for x in y ]
142 """A convenient string representation of this object"""
143 return '\n'.join([':'.join(x) for x in self.items()])
146 return "<rwhoisobject: " + self.getid() + ">"
148 def attrs_to_wire_str(self, attrs, prefix=None):
149 """Return specific attributes in a response formatted string
150 (classname:attr:value)"""
152 cn = self.get_attr_value("class-name", "unknown-class")
153 items = [ [cn, x, y] for x in attrs for y in self.data[x] ]
156 res = '\r\n'.join([ prefix + ':'.join(x) for x in items ])
158 res = '\r\n'.join([ ':'.join(x) for x in items ])
160 if not res.endswith("\r\n"):
165 def to_wire_str(self, prefix=None):
166 """Return the response formatted string (classname:attr:value)"""
168 return self.attrs_to_wire_str(self.attr_order, prefix)
172 ## A basic test driver
173 if __name__ == '__main__':
176 obj.add_attr('id', '001')
177 obj.add_attr("class-name", 'contact')
178 obj.add_attr("class-name", "foo")
179 obj.add_attr('name', 'Aiden Quinn')
180 obj.add_attr('email', 'aquin@yahoo.com')
181 obj.add_attr('org-name', 'YoYoDyne Inc.')
182 obj.add_attr('email', 'aq@aol.net')
183 obj.add_attr('First-Name', 'Aiden ')
186 print "wire:\n", obj.to_wire_str()