| OLD | NEW |
| (Empty) | |
| 1 # Copyright (C) 2006, 2007, 2009 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 |
| OLD | NEW |