email_address 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.md +99 -32
  4. data/email_address.gemspec +2 -1
  5. data/lib/email_address.rb +14 -142
  6. data/lib/email_address/address.rb +70 -0
  7. data/lib/email_address/config.rb +75 -0
  8. data/lib/email_address/domain_matcher.rb +90 -0
  9. data/lib/email_address/domain_parser.rb +71 -0
  10. data/lib/email_address/exchanger.rb +67 -0
  11. data/lib/email_address/host.rb +71 -1
  12. data/lib/email_address/local.rb +97 -0
  13. data/lib/email_address/validator.rb +135 -0
  14. data/lib/email_address/version.rb +1 -1
  15. data/test/email_address/test_address.rb +30 -0
  16. data/test/email_address/test_config.rb +13 -0
  17. data/test/email_address/test_domain_matcher.rb +15 -0
  18. data/test/email_address/test_domain_parser.rb +29 -0
  19. data/test/email_address/test_exchanger.rb +19 -0
  20. data/test/email_address/test_host.rb +43 -0
  21. data/test/email_address/test_local.rb +27 -0
  22. data/test/email_address/test_validator.rb +16 -0
  23. data/test/test_email_address.rb +12 -0
  24. metadata +40 -27
  25. data/lib/email_address/esp.rb +0 -4
  26. data/lib/email_address/providers/default.rb +0 -8
  27. data/lib/email_address/providers/google.rb +0 -8
  28. data/lib/email_providers/address.rb +0 -102
  29. data/lib/email_providers/config.rb +0 -36
  30. data/lib/email_providers/factory.rb +0 -17
  31. data/lib/email_providers/host.rb +0 -87
  32. data/lib/email_providers/mail_exchanger.rb +0 -60
  33. data/lib/email_providers/mailbox.rb +0 -44
  34. data/lib/email_providers/providers/default.rb +0 -55
  35. data/lib/email_providers/providers/google.rb +0 -27
  36. data/lib/email_providers/version.rb +0 -3
  37. data/test/email_address.rb +0 -52
  38. data/test/email_address/address.rb +0 -16
  39. data/test/email_address/config.rb +0 -13
  40. data/test/email_address/host.rb +0 -29
  41. data/test/email_address/mail_exchanger.rb +0 -9
@@ -1,36 +0,0 @@
1
- module EmailAddress
2
- class Config
3
-
4
- # EmailAddress::Config.add_provider(:google, domain_names:["gmail.com", "googlemail.com", "google.com"])
5
- def self.add_provider(provider, matches={})
6
- @pmatch ||= []
7
- @pmatch << matches
8
- end
9
-
10
- # EmailAddress::Config.config do .... end
11
- def self.setup(&block)
12
- @config = Config::DSL.new(&block)
13
- @config.instance_eval(&block)
14
- end
15
-
16
- def self.get
17
- @config
18
- end
19
-
20
- class DSL
21
- attr_accessor :provider_matching_rules
22
- def add_provider(provider, matches={})
23
- puts provider, matches
24
- @provider_matching_rules ||= []
25
- @provider_matching_rules << {provider:provider, matches:matches}
26
- end
27
- end
28
- end
29
- end
30
-
31
-
32
- #EmailAddress::Config.setup do
33
- # add_provider :google, domain_names:["gmail.com", "googlemail.com", "google.com"]
34
- #end
35
-
36
- #puts EmailAddress::Config.provider_matching_rules
@@ -1,17 +0,0 @@
1
- module EmailAddress
2
-
3
- # EmailAddress::Address - Inspects a Email Address.
4
- #
5
- # Format: mailbox@hostname
6
- #
7
- class Factory
8
- attr_reader :mailbox, :host
9
-
10
- def address(address)
11
- (@mailbox, host) = address.strip.split(/\@/)
12
- return unless host
13
- @host = EmailAddress::Host.new(host)
14
- @mailbox = @host.provider_address(@mailbox)
15
- end
16
- end
17
- end
@@ -1,87 +0,0 @@
1
- # EmailAddress::Address
2
- # EmailAddress::Host
3
- # EmailAddress::MailExchanger
4
- # EmailAddress::Config
5
- # EmailAddress::EspMapping
6
- # EmailAddress::Esp::Base, Yahoo, Msn, ...
7
-
8
- require 'simpleidn'
9
-
10
- module EmailAddress
11
-
12
- # EmailAddress::Host handles mail host properties of an email address
13
- # The host is typically the data to the right of the @ in the address
14
- # and consists of:
15
- #
16
- # * hostname - full name of DNS host with the MX record.
17
- # * domain_name - generally, the name and TLD without subdomain
18
- # * base_domain - the identity name of the domain name, without the tld
19
- # * tld (top-level-domain), like .com, .co.jp, .com.xx, etc.
20
- # * subdomain - optional name of server/service under the domain
21
- # * esp (email service provider) a name of the provider: yahoo, msn, etc.
22
- # * dns_hostname - Converted hostname Unicode to Punycode
23
-
24
- class Host
25
- attr_reader :host, :domain_name, :tld, :base_domain, :subdomains, :dns_hostname
26
-
27
- def initialize(host)
28
- host.gsub!(/\A.*@/, '')
29
- host.downcase!
30
- self.host = host
31
- end
32
-
33
- def address(mailbox)
34
- # Determine EmailAddress::Provider::Xxxx
35
- EmailAddress::Address.new(mailbox, self)
36
- end
37
-
38
- def host=(host)
39
- @host = host
40
- # Patterns: *.com, *.xx.cc, *.cc
41
- if @host =~ /(.+)\.(\w{3,10})\z/ || @host =~ /(.+)\.(\w{1,3}\.\w\w)\z/ || @host =~ /(.+)\.(\w\w)\z/
42
- @tld = $2;
43
- sld = $1 # Second level domain
44
- if @sld =~ /(.+)\.(.+)$/ # is subdomain?
45
- @subdomains = $1
46
- @base_domain = $2
47
- else
48
- @subdomains = ""
49
- @base_domain = sld
50
- end
51
- @domain_name = @base_domain + '.' + @tld
52
- @dns_hostname = SimpleIDN.to_ascii(@host)
53
- @host
54
- end
55
- end
56
-
57
- # Resets the host to the domain name, dropping any subdomain
58
- def drop_subdomain!
59
- self.hostname = domain_name
60
- end
61
-
62
- def valid?
63
- return false unless valid_format?
64
- return false unless valid_mx?
65
- true
66
- end
67
-
68
- def valid_format?
69
- Host.valid_format?(@host)
70
- end
71
-
72
- def self.valid_format?(host)
73
- return false unless host.match(/\A([0-9a-z\-]{1,63}\.)+[a-z0-9\-]{2,15}\z/)
74
- return false unless host.length <= 253
75
- true
76
- end
77
-
78
- def valid_mx?
79
- Host.valid_mx?(@host)
80
- end
81
-
82
- def self.valid_mx?(host)
83
- true
84
- end
85
-
86
- end
87
- end
@@ -1,60 +0,0 @@
1
- require 'resolv'
2
- require 'netaddr'
3
- require 'socket'
4
-
5
- class MailExchanger
6
- cattr_accessor :domains, :lookups
7
-
8
- def self.valid_mx?(domain)
9
- dns_a_record_exists?(domain) || mxers(domain).size > 0
10
- end
11
-
12
- def self.dns_a_record_exists?(domain)
13
- @dns_a_record ||= {}
14
- @dns_a_record[domain] = false
15
- if Socket.gethostbyname(domain)
16
- return @dns_a_record[domain] = true
17
- end
18
- rescue SocketError # not found
19
- @dns_a_record[domain] = false
20
- end
21
-
22
- # Returns DNS A record results for the domain as: [[domain, ip, 0],...]
23
- def self.domain_hosts(domain)
24
- @domain_hosts ||= {}
25
- @domain_hosts[domain] = []
26
- res = TCPSocket.gethostbyname(domain)
27
- res = res.slice(3, res.size)
28
- res.each { |r| @domain_hosts[domain] << [domain, r, 0] }
29
- @domain_hosts[domain]
30
-
31
- rescue SocketError
32
- return []
33
- end
34
-
35
- # Returns: [["mta7.am0.yahoodns.net", "66.94.237.139", 1], ["mta5.am0.yahoodns.net", "67.195.168.230", 1], ["mta6.am0.yahoodns.net", "98.139.54.60", 1]]
36
- # If not found, returns []
37
- def self.mxers(domain)
38
- @domains ||= {}
39
- return @domains[domain] if @domains.key?(domain)
40
- @lookups = @lookups ? @lookups + 1 : 1
41
- mx = nil
42
- mxs = Resolv::DNS.open do |dns|
43
- ress = dns.getresources domain, Resolv::DNS::Resource::IN::MX
44
- ress.map { |r| [r.exchange.to_s, IPSocket::getaddress(r.exchange.to_s), r.preference] }
45
- end
46
- @domains[domain] = mxs
47
- end
48
-
49
- # Returns an array of MX IP address (String) for the given email domain
50
- def self.mx_ips(domain)
51
- mxers(domain).map {|m| m[1] }
52
- end
53
-
54
- # Given a cidr (ip/bits) and ip address, returns true on match. Caches cidr object.
55
- def self.in_cidr?(cidr, ip)
56
- @cidrs ||= {}
57
- @cidrs[cidr] ||= NetAddr::CIDR.create(cidr)
58
- @cidrs[cidr].matches?(ip)
59
- end
60
- end
@@ -1,44 +0,0 @@
1
- module EmailAddress
2
-
3
- # EmailAddress::Mailbox - Left side of the @
4
- #
5
- # * mailbox - Everything to the left of the @
6
- # * account - part of the mailbox typically sent to a user
7
- # * tags - Address tags appended to the account for tracking
8
- #
9
- class Mailbox
10
- attr_reader :mailbox, :account, :tags, :provider
11
-
12
- def initialize(mailbox, mail_provider=nil)
13
- @provider = mail_provider
14
- @mailbox = mailbox
15
- end
16
-
17
- def to_s
18
- @mailbox
19
- end
20
-
21
- def mailbox=(mailbox)
22
- @mailbox = mailbox.strip.downcase
23
- (@account, @tags) = @mailbox.split(@provider.tag_separator)
24
- @mailbox
25
- end
26
-
27
- def valid?
28
- return false unless provider.valid?(mailbox)
29
- true
30
- end
31
-
32
- def valid_format?
33
- return false unless provider.valid_format?(mailbox)
34
- #return false unless @mailbox =~ /\A\w[\w\.\-\+\']*\z/
35
- true
36
- end
37
-
38
- # Returns true if the email account is a standard reserved address
39
- def reserved?
40
- %Q(postmaster abuse).include?(account)
41
- end
42
-
43
- end
44
- end
@@ -1,55 +0,0 @@
1
- module EmailAddress
2
- module Providers
3
- class Default
4
- def initialize(address)
5
- @mailbox = mailbox
6
- end
7
-
8
- def account(mailbox)
9
- mailbox
10
- end
11
-
12
- def provider
13
- 'default'
14
- end
15
-
16
- def tag_separator
17
- '+'
18
- end
19
-
20
- def case_sensitive_mailbox
21
- false
22
- end
23
-
24
- def max_domain_length
25
- 253
26
- end
27
-
28
- def max_email_length
29
- 254
30
- end
31
-
32
- # Letters, numbers, period (no start) 6-30chars
33
- def max_mailbox_length
34
- 64
35
- end
36
-
37
- # Letters, numbers, period (no start) 6-30chars
38
- def user_pattern
39
- /\A[a-z0-9][\.\'a-z0-9]{5,29}\z/i
40
- end
41
-
42
- def valid?
43
- return false unless valid_format?
44
- end
45
-
46
- def valid_format?
47
- return false if mailbox.length > max_mailbox_length
48
- return false if address.length > max_email_length
49
- return false unless mailbox.to_s.match(user_pattern)
50
- true
51
- end
52
-
53
- end
54
- end
55
- end
@@ -1,27 +0,0 @@
1
- module EmailAddress
2
- module Providers
3
- class Google < Default
4
- def account
5
- account.gsub(/\./. '')
6
- end
7
-
8
- def provider
9
- 'google'
10
- end
11
-
12
- def tag_separator
13
- '+'
14
- end
15
-
16
- def case_sensitive_mailbox
17
- false
18
- end
19
-
20
- # Letters, numbers, period (no start) 6-30chars
21
- def user_pattern
22
- /\A[a-z0-9][\.a-z0-9]{5,29}\z/i
23
- end
24
-
25
- end
26
- end
27
- end
@@ -1,3 +0,0 @@
1
- module EmailAddress
2
- VERSION = "0.0.1"
3
- end
@@ -1,52 +0,0 @@
1
- # encoding: UTF-8
2
- require_relative 'test_helper'
3
-
4
- class TestEmailAddress < MiniTest::Unit::TestCase
5
- def test_address
6
- a = EmailAddress.new('user@example.com')
7
- assert_equal a.local, 'user'
8
- assert_equal a.tag, ''
9
- assert_equal a.comment, ''
10
- assert_equal a.domain, 'example.com'
11
- assert_equal a.subdomains, ''
12
- assert_equal a.base_domain, 'example'
13
- assert_equal a.dns_hostname, 'example.com'
14
- assert_equal a.top_level_domain, 'com'
15
- assert_equal a.to_s, 'user@example.com'
16
- end
17
-
18
- def test_foreign_address
19
- a = EmailAddress.new("user@sub.example.co.jp")
20
- assert_equal a.domain, "sub.example.co.jp"
21
- assert_equal a.subdomains, "sub"
22
- assert_equal a.domain_name, "example.co.jp"
23
- assert_equal a.base_domain, "example"
24
- assert_equal a.top_level_domain, "co.jp"
25
- end
26
-
27
- def test_address_tag
28
- a = EmailAddress.new('user+etc@example.com')
29
- assert_equal a.account, 'user'
30
- assert_equal a.tag, 'etc'
31
- assert_equal a.unique_address, 'user@example.com'
32
- end
33
-
34
- def test_address_comment
35
- a = EmailAddress.new('(comment)user@example.com')
36
- assert_equal a.comment, 'comment'
37
- assert_equal a.account, 'user'
38
- assert_equal a.unique_address, 'user@example.com'
39
- end
40
-
41
- def test_user_validation
42
- a = EmailAddress.new("user@example.co.jp")
43
- assert a.valid? == true
44
- end
45
-
46
- def test_unicode_domain
47
- a = EmailAddress.new("User@København.eu")
48
- assert_equal a.dns_hostname, 'xn--kbenhavn-54a.eu'
49
- assert_equal a.unique_address, 'user@xn--kbenhavn-54a.eu'
50
- end
51
-
52
- end
@@ -1,16 +0,0 @@
1
- #encoding: utf-8
2
- require_relative '../test_helper'
3
-
4
- class TestAddress < MiniTest::Unit::TestCase
5
- def test_address
6
- a = EmailAddress.new("User+tag@example.com")
7
- assert_equal "user", a.account
8
- assert_equal "user+tag", a.local
9
- assert_equal "user@example.com", a.unique_address
10
- end
11
-
12
- def test_unicode_user
13
- a = EmailAddress.new("å@example.com")
14
- assert_equal false, a.valid_format?
15
- end
16
- end
@@ -1,13 +0,0 @@
1
- #encoding: utf-8
2
- require_relative '../test_helper'
3
- #require 'minitest/autorun'
4
-
5
- class TestConfig < MiniTest::Unit::TestCase
6
- def test_config
7
- EmailAddress::Config.setup do
8
- add_provider :google, domain_names: %w(gmail.com googlemail.com google.com)
9
- end
10
- assert_equal EmailAddress::Config.get.provider_matching_rules.first[:provider], :google
11
- end
12
-
13
- end
@@ -1,29 +0,0 @@
1
- # encoding: UTF-8
2
- require_relative '../test_helper'
3
-
4
-
5
- class TestHost < MiniTest::Unit::TestCase
6
- def test_host
7
- a = EmailAddress::Host.new("example.com")
8
- assert_equal "example.com", a.host
9
- assert_equal "example.com", a.domain_name
10
- assert_equal "example", a.base_domain
11
- assert_equal ".com", a.tld
12
- assert_equal "", a.subdomains
13
- end
14
-
15
- def test_foreign_host
16
- a = EmailAddress::Host.new("yahoo.co.jp")
17
- assert_equal "yahoo.co.jp", a.host
18
- assert_equal "yahoo.co.jp", a.domain_name
19
- assert_equal "yahoo", a.base_domain
20
- assert_equal "co.jp", a.tld
21
- assert_equal "", a.subdomains
22
- end
23
-
24
- def test_unicode_host
25
- a = EmailAddress::Host.new("å.com")
26
- assert_equal "xn--5ca.com", a.dns_hostname
27
- end
28
-
29
- end