Move dnspython to third_party.
[bbaumbach/samba-autobuild/.git] / third_party / dnspython / dns / e164.py
1 # Copyright (C) 2006, 2007, 2009, 2011 Nominum, Inc.
2 #
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
7 #
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16 """DNS E.164 helpers
17
18 @var public_enum_domain: The DNS public ENUM domain, e164.arpa.
19 @type public_enum_domain: dns.name.Name object
20 """
21
22 import dns.exception
23 import dns.name
24 import dns.resolver
25
26 public_enum_domain = dns.name.from_text('e164.arpa.')
27
28 def from_e164(text, origin=public_enum_domain):
29     """Convert an E.164 number in textual form into a Name object whose
30     value is the ENUM domain name for that number.
31     @param text: an E.164 number in textual form.
32     @type text: str
33     @param origin: The domain in which the number should be constructed.
34     The default is e164.arpa.
35     @type: dns.name.Name object or None
36     @rtype: dns.name.Name object
37     """
38     parts = [d for d in text if d.isdigit()]
39     parts.reverse()
40     return dns.name.from_text('.'.join(parts), origin=origin)
41
42 def to_e164(name, origin=public_enum_domain, want_plus_prefix=True):
43     """Convert an ENUM domain name into an E.164 number.
44     @param name: the ENUM domain name.
45     @type name: dns.name.Name object.
46     @param origin: A domain containing the ENUM domain name.  The
47     name is relativized to this domain before being converted to text.
48     @type: dns.name.Name object or None
49     @param want_plus_prefix: if True, add a '+' to the beginning of the
50     returned number.
51     @rtype: str
52     """
53     if not origin is None:
54         name = name.relativize(origin)
55     dlabels = [d for d in name.labels if (d.isdigit() and len(d) == 1)]
56     if len(dlabels) != len(name.labels):
57         raise dns.exception.SyntaxError('non-digit labels in ENUM domain name')
58     dlabels.reverse()
59     text = ''.join(dlabels)
60     if want_plus_prefix:
61         text = '+' + text
62     return text
63
64 def query(number, domains, resolver=None):
65     """Look for NAPTR RRs for the specified number in the specified domains.
66
67     e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
68     """
69     if resolver is None:
70         resolver = dns.resolver.get_default_resolver()
71     for domain in domains:
72         if isinstance(domain, (str, unicode)):
73             domain = dns.name.from_text(domain)
74         qname = dns.e164.from_e164(number, domain)
75         try:
76             return resolver.query(qname, 'NAPTR')
77         except dns.resolver.NXDOMAIN:
78             pass
79     raise dns.resolver.NXDOMAIN