def __init__(self, cache_path=None, tld_cache_path=None): self.cache_path = None if cache_path is not None: self.cache_path = os.path.expandvars(os.path.expanduser(cache_path)) else: for f in CACHE_FILES: if os.path.isfile(f) and os.access(f, os.W_OK): self.cache_path = f break fdir = os.path.dirname(f) if not os.path.isdir(fdir): try: os.makedirs(os.path.dirname(f)) except IOError: continue except OSError: continue if not os.path.isfile(f): try: open(f, 'w').write('\n') os.unlink(f) self.cache_path = f break except IOError: continue except OSError: continue if self.cache_path is None: raise WhoisError('ERROR: No whois cache path defined') try: self.tlds = TLDCache(tld_cache_path) if not self.tlds.is_downloaded: self.tlds.download() except DNSCacheError as e: raise WhoisEror(e) if os.path.isfile(self.cache_path): self.load()
class WhoisServerCache(dict): def __init__(self, cache_path=None, tld_cache_path=None): self.cache_path = None if cache_path is not None: self.cache_path = os.path.expandvars(os.path.expanduser(cache_path)) else: for f in CACHE_FILES: if os.path.isfile(f) and os.access(f, os.W_OK): self.cache_path = f break fdir = os.path.dirname(f) if not os.path.isdir(fdir): try: os.makedirs(os.path.dirname(f)) except IOError: continue except OSError: continue if not os.path.isfile(f): try: open(f, 'w').write('\n') os.unlink(f) self.cache_path = f break except IOError: continue except OSError: continue if self.cache_path is None: raise WhoisError('ERROR: No whois cache path defined') try: self.tlds = TLDCache(tld_cache_path) if not self.tlds.is_downloaded: self.tlds.download() except DNSCacheError as e: raise WhoisEror(e) if os.path.isfile(self.cache_path): self.load() def load(self): if not os.path.isfile(self.cache_path): raise WhoisError('No such file: %s' % self.cache_path) try: cache = ConfigParser.ConfigParser() cache.read(self.cache_path) except OSError as e: raise WhoisError(e) except IOError as e: raise WhoisError(e) for tld in cache.sections(): try: ipv4_addresses = [] ipv6_addresses = [] if cache.has_option(tld, 'ipv4_addresses') and cache.get(tld, 'ipv4_addresses'): ipv4_addresses.extend(cache.get(tld, 'ipv4_addresses').split(',')) if cache.has_option(tld, 'ipv6_addresses') and cache.get(tld, 'ipv6_addresses'): ipv6_addresses.extend(cache.get(tld, 'ipv6_addresses').split(',')) entry = TLDWhoisServerList(tld, ipv4_addresses, ipv6_addresses) self[tld] = entry except ConfigParser.NoOptionError: logger.debug('Invalid cache entry for %s' % tld) def save(self): if len(self) == 0: return cache_dir = os.path.dirname(self.cache_path) if not os.path.isdir(cache_dir): try: os.makedirs(cache_dir) except IOError as e: raise WhoisError('Error creating cache directory %s: %s' % (cache_dir, e)) except OSError as e: raise WhoisError('Error creating cache directory %s: %s' % (cache_dir, e)) try: cache = ConfigParser.ConfigParser() for entry in self.values(): section = cache.add_section(entry.tld) cache.set(entry.tld, 'ipv4_addresses', ','.join(x.ipaddress for x in entry.ipv4_addresses)) cache.set(entry.tld, 'ipv6_addresses', ','.join(x.address for x in entry.ipv6_addresses)) cache.write(open(self.cache_path, 'w')) except OSError as e: raise WhoisError('Error updating cache %s: %s' % (self.cache_path, e)) except IOError as e: raise WhoisError('Error updating cache %s: %s' % (self.cache_path, e)) def get(self, tld, timeout=WHOIS_SERVER_TIMEOUT): try: timeout = int(timeout) except ValueError: raise WhoisError('Invalid timeout value: %s' % timeout) if tld not in self.tlds: raise WhoisError('Invalid TLD name: %s' % tld) if tld not in self: details = {} name = '.'.join([tld, SEARCH_DOMAIN]) try: socket.setdefaulttimeout(timeout) name, aliases, addresses = socket.gethostbyname_ex(name) entry = TLDWhoisServerList(tld, addresses) self[tld] = entry except socket.timeout: raise WhoisError('Timeout resolving whois server %s' % name) except socket.gaierror as e: raise WhoisError(e) except ValueError as e: raise WhoisError(e) return self[tld] def query(self, name): try: tld = name.rstrip('.').split('.')[-1] except ValueError: raise WhoisError('Error parsing TLD from %s' % name) tldservers = self.get(tld) return tldservers.query(name)