canonical-emails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []