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