canonical-emails 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ pkg
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,6 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - jruby-19mode
6
+ - rbx-19mode
@@ -0,0 +1,3 @@
1
+ ### 0.1.0 (6/22/2013)
2
+
3
+ * Initial public release, written on a plane from NYC to SF - [@dblock](https://github.com/dblock).
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rspec"
6
+ gem "rake"
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2013 Daniel Doubrovkine.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,100 @@
1
+ CanonicalEmails
2
+ ==============
3
+
4
+ [![Build Status](https://travis-ci.org/dblock/canonical-emails.png)](https://travis-ci.org/dblock/canonical-emails)
5
+
6
+ Combine email validation and transformations to produce canonical email addresses. For example, parse and transform `Donald Duck <donald.duck@gmail.com>` into `donaldduck@gmail.com`, for `@gmail.com` addresses only. Patches instances of `Mail::Address`.
7
+
8
+ ### Install
9
+
10
+ Add `canonical-emails` to your Gemfile.
11
+
12
+ ```
13
+ gem 'canonical-emails'
14
+ ```
15
+
16
+ ### Use
17
+
18
+ ``` ruby
19
+ class User
20
+ include CanonicalEmails::Extensions
21
+
22
+ attr_accessor :email
23
+ canonical_email :email, CanonicalEmails::GMail
24
+ end
25
+
26
+ user = User.new
27
+ user.email = "Donald Duck <Donald.Duck@gmail.com>"
28
+ user.canonical_email.class # Mail::Address
29
+ user.canonical_email.to_s # "Donald Duck <donaldduck@gmail.com>"
30
+ user.canonical_email.address # "donaldduck@gmail.com"
31
+ ```
32
+
33
+ ### Transform
34
+
35
+ #### CanonicalEmails::Downcase
36
+
37
+ Replaces the address and domain portion of the email by its lowercase equivalent.
38
+
39
+ ``` ruby
40
+ email = CanonicalEmails::Downcase.transform("Donald Duck <DoNaLD.DuCK@eXaMPLe.CoM>")
41
+ email.to_s # "Donald Duck <donald.duck@example.com>"
42
+ email.address # "donald.duck@example.com"
43
+ ```
44
+
45
+ #### CanonicalEmails::GMail
46
+
47
+ Gmail.com e-mail addresses ignore periods and aren't case-sensitive. The canonical version removes them and changes the address portion to lowercase.
48
+
49
+ ``` ruby
50
+ email = CanonicalEmails::GMail.transform("Donald Duck <donald.duck@gmail.com>")
51
+ email.to_s # "Donald Duck <donaldduck@gmail.com>"
52
+ email.local # "donaldduck"
53
+ email.address # "donaldduck@gmail.com"
54
+ ```
55
+
56
+ ### Multiple Transformations
57
+
58
+ Combine multiple transformations, executed from left to right.
59
+
60
+ ```
61
+ canonical_email :email, CanonicalEmails::GMail, CanonicalEmails::...
62
+ ```
63
+
64
+ ### Custom Transformations
65
+
66
+ A transformation is a module that has a single `transform` method that returns a `Mail::Address` instance. This library patches internal methods of the `Mail::Address` class.
67
+
68
+ ``` ruby
69
+ module CanonicalEmails
70
+ module ReverseName
71
+ def self.transform(value)
72
+ Mail::Address.new(value).tap do |email|
73
+ email.instance_eval do
74
+ def name
75
+ super.reverse
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ email = CanonicalEmails::ReverseName.transform("Donald Duck <donald@example.org>")
84
+ email.name # "kcuD dlanoD"
85
+ ```
86
+
87
+ ### Contribute
88
+
89
+ You're encouraged to contribute to this gem.
90
+
91
+ * Fork this project.
92
+ * Make changes, write tests.
93
+ * Updated CHANGELOG.
94
+ * Make a pull request, bonus points for topic branches.
95
+
96
+ ### Copyright and License
97
+
98
+ Copyright Daniel Doubrovkine and Contributors, Artsy Inc., 2013
99
+
100
+ [MIT License](LICENSE.md)
@@ -0,0 +1,13 @@
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+
4
+ Bundler.setup :default, :development
5
+
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ RSpec::Core::RakeTask.new(:spec) do |spec|
10
+ spec.pattern = FileList["spec/**/*_spec.rb"]
11
+ end
12
+
13
+ task :default => :spec
@@ -0,0 +1,18 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'canonical-emails/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "canonical-emails"
6
+ s.version = CanonicalEmails::VERSION
7
+ s.authors = [ "Daniel Doubrovkine" ]
8
+ s.email = "dblock@dblock.org"
9
+ s.platform = Gem::Platform::RUBY
10
+ s.required_rubygems_version = '>= 1.3.6'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_paths = [ "lib" ]
13
+ s.homepage = "http://github.com/dblock/canonical-emails"
14
+ s.licenses = [ "MIT" ]
15
+ s.summary = "Combine email validation and transformations to produce canonical email addresses."
16
+ s.add_dependency "mail"
17
+ s.add_dependency "activesupport"
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'mail'
2
+ require 'active_support'
3
+
4
+ require 'canonical-emails/version'
5
+ require 'canonical-emails/downcase'
6
+ require 'canonical-emails/gmail'
7
+ require 'canonical-emails/extensions'
@@ -0,0 +1,20 @@
1
+ module CanonicalEmails
2
+ module Downcase
3
+
4
+ def self.transform(value)
5
+ Mail::Address.new(value).tap do |email|
6
+ email.instance_eval do
7
+ def get_local
8
+ value = super
9
+ value.downcase if value
10
+ end
11
+ def domain
12
+ value = super
13
+ value.downcase if value
14
+ end
15
+ end
16
+ end if value
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module CanonicalEmails
2
+ module Extensions
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def canonical_email(field, *parsers)
7
+ define_method "canonical_#{field}" do
8
+ value = send(field)
9
+ Array(parsers).each do |parser|
10
+ value = parser.transform(value.to_s)
11
+ end
12
+ value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module CanonicalEmails
2
+ module GMail
3
+
4
+ def self.transform(value)
5
+ Mail::Address.new(value).tap do |email|
6
+ if email.domain && [ "gmail.com" ].include?(email.domain.downcase)
7
+ email.instance_eval do
8
+ def get_local
9
+ value = super
10
+ value.gsub(".", "").downcase if value
11
+ end
12
+ def domain
13
+ value = super
14
+ value.downcase if value
15
+ end
16
+ end
17
+ end if value
18
+ end
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module CanonicalEmails
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1 @@
1
+ require 'canonical-emails'
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanonicalEmails::Downcase do
4
+ it_behaves_like 'transform fixture_examples'
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanonicalEmails::Extensions do
4
+ it_behaves_like 'extension fixture_examples'
5
+ end
@@ -0,0 +1,30 @@
1
+ -
2
+ source: Donald <donald@example.org>
3
+ name: Donald
4
+ local: donald
5
+ domain: example.org
6
+ -
7
+ source: Donald < donald@example.org >
8
+ name: Donald
9
+ local: donald
10
+ domain: example.org
11
+ -
12
+ source: donald@example.org
13
+ local: donald
14
+ domain: example.org
15
+ -
16
+ source: ! ' donald@example.org'
17
+ local: donald
18
+ domain: example.org
19
+ -
20
+ source: donald@eXaMPLe.org
21
+ local: donald
22
+ domain: example.org
23
+ -
24
+ source: DONALD@eXaMPLe.org
25
+ local: donald
26
+ domain: example.org
27
+ -
28
+ source: DoNaLD@example.org
29
+ local: donald
30
+ domain: example.org
@@ -0,0 +1,16 @@
1
+ -
2
+ email: Donald Duck <DoNaLD.DuCK@GMaiL.CoM>
3
+ transforms:
4
+ - CanonicalEmails::Downcase
5
+ canonical_email: Donald Duck <donald.duck@gmail.com>
6
+ -
7
+ email: Donald Duck <DoNaLD.DuCK@GMaiL.CoM>
8
+ transforms:
9
+ - CanonicalEmails::GMail
10
+ canonical_email: Donald Duck <donaldduck@gmail.com>
11
+ -
12
+ email: Donald Duck <DoNaLD.DuCK@GMaiL.CoM>
13
+ transforms:
14
+ - CanonicalEmails::GMail
15
+ - CanonicalEmails::Reverse
16
+ canonical_email: Donald Duck <kcuddlanod@moc.liamg>
@@ -0,0 +1,29 @@
1
+ -
2
+ source: Donald Duck <example@example.org>
3
+ name: Donald Duck
4
+ local: example
5
+ domain: example.org
6
+ -
7
+ source: donald@example.org
8
+ local: donald
9
+ domain: example.org
10
+ -
11
+ source: donald@eXaMPLe.org
12
+ local: donald
13
+ domain: eXaMPLe.org
14
+ -
15
+ source: donald.duck@gmail.com
16
+ local: donaldduck
17
+ domain: gmail.com
18
+ -
19
+ source: donaldduck@gmail.com
20
+ local: donaldduck
21
+ domain: gmail.com
22
+ -
23
+ source: donald.duck@gMaiL.com
24
+ local: donaldduck
25
+ domain: gmail.com
26
+ -
27
+ source: donald.duck@google.com
28
+ local: donald.duck
29
+ domain: google.com
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanonicalEmails::GMail do
4
+ it_behaves_like 'transform fixture_examples'
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe CanonicalEmails do
4
+ it "has a version" do
5
+ CanonicalEmails::VERSION.should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ shared_examples 'extension fixture_examples' do
2
+ yml_examples.each do |example|
3
+ it "#{example['transforms'].join(', ')}" do
4
+ klass = Class.new do
5
+ include CanonicalEmails::Extensions
6
+ attr_accessor :email
7
+ canonical_email :email, * example['transforms'].map(&:constantize)
8
+ end
9
+ user = klass.new
10
+ user.email = example['email']
11
+ user.canonical_email.to_s.should == example['canonical_email']
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ shared_examples 'transform fixture_examples' do
2
+ yml_examples.each do |example|
3
+ it "transforms '#{example['source']}'" do
4
+ subject.transform(example['source']).tap do |email|
5
+ email.local.should == example['local']
6
+ email.domain.should == example['domain']
7
+ email.name.should == example['name']
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+
3
+ require 'rubygems'
4
+ require 'rspec'
5
+ require 'canonical-emails'
6
+ require 'yaml'
7
+
8
+ [ "support", "shared" ].each do |path|
9
+ Dir["#{File.dirname(__FILE__)}/#{path}/**/*.rb"].each do |f|
10
+ require f
11
+ end
12
+ end
@@ -0,0 +1,18 @@
1
+ module CanonicalEmails
2
+ module Reverse
3
+
4
+ def self.transform(value)
5
+ Mail::Address.new(value).tap do |email|
6
+ email.instance_eval do
7
+ def get_local
8
+ super.reverse
9
+ end
10
+ def domain
11
+ super.reverse
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+ def yml_examples
2
+ caller.each do |c|
3
+ c =~ /(.*):(\d+)/
4
+ dir_name = File.dirname($1)
5
+ file_name = File.basename($1)
6
+ next unless file_name.end_with?("_spec.rb")
7
+ fixture_file = "#{file_name.split('_spec').first}.yml"
8
+ return YAML::load(File.open([ dir_name, 'fixtures', fixture_file ].join('/')))
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: canonical-emails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Daniel Doubrovkine
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mail
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description:
47
+ email: dblock@dblock.org
48
+ executables: []
49
+ extensions: []
50
+ extra_rdoc_files: []
51
+ files:
52
+ - .gitignore
53
+ - .rspec
54
+ - .travis.yml
55
+ - CHANGELOG.md
56
+ - Gemfile
57
+ - LICENSE.md
58
+ - README.md
59
+ - Rakefile
60
+ - canonical-emails.gemspec
61
+ - lib/canonical-emails.rb
62
+ - lib/canonical-emails/downcase.rb
63
+ - lib/canonical-emails/extensions.rb
64
+ - lib/canonical-emails/gmail.rb
65
+ - lib/canonical-emails/version.rb
66
+ - lib/canonical_emails.rb
67
+ - spec/canonical-emails/downcase_spec.rb
68
+ - spec/canonical-emails/extensions_spec.rb
69
+ - spec/canonical-emails/fixtures/downcase.yml
70
+ - spec/canonical-emails/fixtures/extensions.yml
71
+ - spec/canonical-emails/fixtures/gmail.yml
72
+ - spec/canonical-emails/gmail_spec.rb
73
+ - spec/canonical-emails/version_spec.rb
74
+ - spec/shared/extension_examples.rb
75
+ - spec/shared/transform_examples.rb
76
+ - spec/spec_helper.rb
77
+ - spec/support/reverse.rb
78
+ - spec/support/yml_examples.rb
79
+ homepage: http://github.com/dblock/canonical-emails
80
+ licenses:
81
+ - MIT
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ segments:
93
+ - 0
94
+ hash: 247467439
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: 1.3.6
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.24
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Combine email validation and transformations to produce canonical email addresses.
107
+ test_files: []