def test_mx_lookup_metrics(): with patch.object(validate, 'mail_exchanger_lookup') as mock_method: mock_method.side_effect = mock_exchanger_lookup a, metrics = validate.mail_exchanger_lookup('example.com', metrics=True) assert_equal(metrics['mx_lookup'], 10) assert_equal(metrics['dns_lookup'], 20) assert_equal(metrics['mx_conn'], 30) # ensure values are unpacked correctly a = validate.mail_exchanger_lookup('example.com', metrics=False) a = validate.mail_exchanger_lookup('example.com', metrics=False)
def test_mx_lookup_metrics(): with patch.object(validate, 'mail_exchanger_lookup') as mock_method: mock_method.side_effect = mock_exchanger_lookup a, metrics = validate.mail_exchanger_lookup('example.com', metrics=True) assert_equal(metrics['mx_lookup'], 10) assert_equal(metrics['dns_lookup'], 20) assert_equal(metrics['mx_conn'], 30) # ensure values are unpacked correctly a = validate.mail_exchanger_lookup('example.com', metrics=False) a = validate.mail_exchanger_lookup('example.com', metrics=False)
def test_mx_lookup_metrics(): with patch.object(validate, "mail_exchanger_lookup") as mock_method: mock_method.side_effect = mock_exchanger_lookup a, b, metrics = validate.mail_exchanger_lookup("example.com", metrics=True) assert_equal(metrics["mx_lookup"], 10) assert_equal(metrics["dns_lookup"], 20) assert_equal(metrics["mx_conn"], 30) # ensure values are unpacked correctly a, b = validate.mail_exchanger_lookup("example.com", metrics=False) a, b = validate.mail_exchanger_lookup("example.com", metrics=False)
def validate_list(addr_list, as_tuple=False, metrics=False): """ Validates an address list, and returns a tuple of parsed and unparsed portions. Returns results as a list or tuple consisting of the parsed addresses and unparsable protions. If requested, will also return parisng time metrics. Examples: >>> address.validate_address_list('[email protected], [email protected]') [[email protected], [email protected]] >>> address.validate_address_list('[email protected], [email protected]') [[email protected]] >>> address.validate_address_list('a@b, c@d, [email protected]', as_tuple=True) ([[email protected], [email protected]], ['*****@*****.**']) """ mtimes = { 'parsing': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn': 0, 'custom_grammar': 0 } if not addr_list: return AddressList(), mtimes # parse addresses bstart = time() parsed_addresses, unparseable = parse_list(addr_list, strict=True, as_tuple=True) mtimes['parsing'] = time() - bstart plist = AddressList() ulist = [] # make sure parsed list pass dns and esp grammar for paddr in parsed_addresses: # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(paddr.hostname, metrics=True) mtimes['mx_lookup'] += mx_metrics['mx_lookup'] mtimes['dns_lookup'] += mx_metrics['dns_lookup'] mtimes['mx_conn'] += mx_metrics['mx_conn'] if exchanger is None: ulist.append(paddr.full_spec()) continue # lookup custom local-part grammar if it exists plugin = plugin_for_esp(exchanger) bstart = time() if plugin and plugin.validate(paddr.mailbox) is False: ulist.append(paddr.full_spec()) continue mtimes['custom_grammar'] = time() - bstart plist.append(paddr) # loop over unparsable list and check if any can be fixed with # preparsing cleanup and if so, run full validator for unpar in unparseable: paddr, metrics = validate_address(unpar, metrics=True) if paddr: plist.append(paddr) else: ulist.append(unpar) # update all the metrics for k, v in metrics.iteritems(): metrics[k] += v if as_tuple: return plist, ulist, mtimes return plist, mtimes
def validate_address(addr_spec, metrics=False): """ Given an addr-spec, runs the pre-parser, the parser, DNS MX checks, MX existence checks, and if available, ESP specific grammar for the local part. In the case of a valid address returns an EmailAddress object, otherwise returns None. If requested, will also return the parsing time metrics. Examples: >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') [email protected] """ mtimes = { 'parsing': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn': 0, 'custom_grammar': 0 } # sanity check if addr_spec is None: return None, mtimes # preparse address into its parts and perform any ESP specific pre-parsing addr_parts = preparse_address(addr_spec) if addr_parts is None: _log.warning('failed preparse check for %s', addr_spec) return None, mtimes # run parser against address bstart = time() paddr = parse('@'.join(addr_parts), addr_spec_only=True, strict=True) mtimes['parsing'] = time() - bstart if paddr is None: _log.warning('failed parse check for %s', addr_spec) return None, mtimes # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(addr_parts[-1], metrics=True) mtimes['mx_lookup'] = mx_metrics['mx_lookup'] mtimes['dns_lookup'] = mx_metrics['dns_lookup'] mtimes['mx_conn'] = mx_metrics['mx_conn'] if exchanger is None: _log.warning('failed mx check for %s', addr_spec) return None, mtimes # lookup custom local-part grammar if it exists bstart = time() plugin = plugin_for_esp(exchanger) mtimes['custom_grammar'] = time() - bstart if plugin and plugin.validate(addr_parts[0]) is False: _log.warning('failed custom grammer check for %s/%s', addr_spec, plugin.__name__) return None, mtimes return paddr, mtimes
def validate_address(addr_spec, metrics=False, skip_remote_checks=False): """ Given an addr-spec, runs the pre-parser, the parser, DNS MX checks, MX existence checks, and if available, ESP specific grammar for the local part. In the case of a valid address returns an EmailAddress object, otherwise returns None. If requested, will also return the parsing time metrics. Examples: >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') [email protected] """ mtimes = { 'parsing': 0, 'tld_lookup': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn': 0, 'custom_grammar': 0 } # sanity check if addr_spec is None: return None, mtimes if '@' not in addr_spec: return None, mtimes # run parser against address bstart = time() paddr = parse(addr_spec, addr_spec_only=True, strict=True) mtimes['parsing'] = time() - bstart if paddr is None: _log.debug('failed parse check for %s', addr_spec) return None, mtimes # lookup the TLD bstart = time() tld = get_tld(paddr.hostname, fail_silently=True, fix_protocol=True) mtimes['tld_lookup'] = time() - bstart if tld is None: _log.debug('failed tld check for %s', addr_spec) return None, mtimes if skip_remote_checks: return paddr, mtimes # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(paddr.hostname, metrics=True) mtimes['mx_lookup'] = mx_metrics['mx_lookup'] mtimes['dns_lookup'] = mx_metrics['dns_lookup'] mtimes['mx_conn'] = mx_metrics['mx_conn'] if exchanger is None: _log.debug('failed mx check for %s', addr_spec) return None, mtimes # lookup custom local-part grammar if it exists bstart = time() plugin = plugin_for_esp(exchanger) mtimes['custom_grammar'] = time() - bstart if plugin and plugin.validate(paddr) is False: _log.debug('failed custom grammer check for %s/%s', addr_spec, plugin.__name__) return None, mtimes return paddr, mtimes
def validate_address(addr_spec, metrics=False, skip_remote_checks=False): """ Given an addr-spec, runs the pre-parser, the parser, DNS MX checks, MX existence checks, and if available, ESP specific grammar for the local part. In the case of a valid address returns an EmailAddress object, otherwise returns None. If requested, will also return the parsing time metrics. Examples: >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') [email protected] """ mtimes = {'parsing': 0, 'tld_lookup': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn':0 , 'custom_grammar':0} # sanity check if addr_spec is None: return None, mtimes if '@' not in addr_spec: return None, mtimes # run parser against address bstart = time() paddr = parse(addr_spec, addr_spec_only=True, strict=True) mtimes['parsing'] = time() - bstart if paddr is None: _log.debug('failed parse check for %s', addr_spec) return None, mtimes # lookup the TLD bstart = time() tld = get_tld(paddr.hostname, fail_silently=True, fix_protocol=True) mtimes['tld_lookup'] = time() - bstart if tld is None: _log.debug('failed tld check for %s', addr_spec) return None, mtimes if skip_remote_checks: return paddr, mtimes # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(paddr.hostname, metrics=True) mtimes['mx_lookup'] = mx_metrics['mx_lookup'] mtimes['dns_lookup'] = mx_metrics['dns_lookup'] mtimes['mx_conn'] = mx_metrics['mx_conn'] if exchanger is None: _log.debug('failed mx check for %s', addr_spec) return None, mtimes # lookup custom local-part grammar if it exists bstart = time() plugin = plugin_for_esp(exchanger) mtimes['custom_grammar'] = time() - bstart if plugin and plugin.validate(paddr) is False: _log.debug('failed custom grammer check for %s/%s', addr_spec, plugin.__name__) return None, mtimes return paddr, mtimes
def validate_list(addr_list, as_tuple=False, metrics=False): """ Validates an address list, and returns a tuple of parsed and unparsed portions. Returns results as a list or tuple consisting of the parsed addresses and unparsable protions. If requested, will also return parisng time metrics. Examples: >>> address.validate_address_list('[email protected], [email protected]') [[email protected], [email protected]] >>> address.validate_address_list('[email protected], [email protected]') [[email protected]] >>> address.validate_address_list('a@b, c@d, [email protected]', as_tuple=True) ([[email protected], [email protected]], ['*****@*****.**']) """ mtimes = {'parsing': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn':0 , 'custom_grammar':0} if not addr_list: return AddressList(), mtimes # parse addresses bstart = time() parsed_addresses, unparseable = parse_list(addr_list, strict=True, as_tuple=True) mtimes['parsing'] = time() - bstart plist = AddressList() ulist = [] # make sure parsed list pass dns and esp grammar for paddr in parsed_addresses: # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(paddr.hostname, metrics=True) mtimes['mx_lookup'] += mx_metrics['mx_lookup'] mtimes['dns_lookup'] += mx_metrics['dns_lookup'] mtimes['mx_conn'] += mx_metrics['mx_conn'] if exchanger is None: ulist.append(paddr.full_spec()) continue # lookup custom local-part grammar if it exists plugin = plugin_for_esp(exchanger) bstart = time() if plugin and plugin.validate(paddr.mailbox) is False: ulist.append(paddr.full_spec()) continue mtimes['custom_grammar'] = time() - bstart plist.append(paddr) # loop over unparsable list and check if any can be fixed with # preparsing cleanup and if so, run full validator for unpar in unparseable: paddr, metrics = validate_address(unpar, metrics=True) if paddr: plist.append(paddr) else: ulist.append(unpar) # update all the metrics for k, v in metrics.iteritems(): metrics[k] += v if as_tuple: return plist, ulist, mtimes return plist, mtimes
def validate_address(addr_spec, metrics=False): """ Given an addr-spec, runs the pre-parser, the parser, DNS MX checks, MX existence checks, and if available, ESP specific grammar for the local part. In the case of a valid address returns an EmailAddress object, otherwise returns None. If requested, will also return the parsing time metrics. Examples: >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') None >>> address.validate_address('*****@*****.**') [email protected] """ mtimes = {'parsing': 0, 'mx_lookup': 0, 'dns_lookup': 0, 'mx_conn':0 , 'custom_grammar':0} # sanity check if addr_spec is None: return None, mtimes # preparse address into its parts and perform any ESP specific pre-parsing addr_parts = preparse_address(addr_spec) if addr_parts is None: _log.warning('failed preparse check for %s', addr_spec) return None, mtimes # run parser against address bstart = time() paddr = parse('@'.join(addr_parts), addr_spec_only=True, strict=True) mtimes['parsing'] = time() - bstart if paddr is None: _log.warning('failed parse check for %s', addr_spec) return None, mtimes # lookup if this domain has a mail exchanger exchanger, mx_metrics = mail_exchanger_lookup(addr_parts[-1], metrics=True) mtimes['mx_lookup'] = mx_metrics['mx_lookup'] mtimes['dns_lookup'] = mx_metrics['dns_lookup'] mtimes['mx_conn'] = mx_metrics['mx_conn'] if exchanger is None: _log.warning('failed mx check for %s', addr_spec) return None, mtimes # lookup custom local-part grammar if it exists bstart = time() plugin = plugin_for_esp(exchanger) mtimes['custom_grammar'] = time() - bstart if plugin and plugin.validate(addr_parts[0]) is False: _log.warning('failed custom grammer check for %s/%s', addr_spec, plugin.__name__) return None, mtimes return paddr, mtimes