caller_id 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in caller_id.gemspec
4
+ gemspec
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ caller_id (0.0.1)
5
+ json
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ addressable (2.2.8)
11
+ crack (0.3.1)
12
+ diff-lcs (1.1.3)
13
+ json (1.6.1)
14
+ rspec (2.10.0)
15
+ rspec-core (~> 2.10.0)
16
+ rspec-expectations (~> 2.10.0)
17
+ rspec-mocks (~> 2.10.0)
18
+ rspec-core (2.10.1)
19
+ rspec-expectations (2.10.0)
20
+ diff-lcs (~> 1.1.3)
21
+ rspec-mocks (2.10.1)
22
+ timecop (0.3.5)
23
+ vcr (2.2.2)
24
+ webmock (1.8.6)
25
+ addressable (>= 2.2.7)
26
+ crack (>= 0.1.7)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ bundler (>= 1.0.0)
33
+ caller_id!
34
+ rspec (~> 2.6)
35
+ timecop (~> 0.3)
36
+ vcr (~> 2.1)
37
+ webmock (= 1.8.6)
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ben Ellis
2
+
3
+ MIT License
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,54 @@
1
+ # CallerId
2
+
3
+ A ruby wrapper around OpenCNAM api. Lookup cell phone caller ID in supported countries. See http://docs.opencnam.com/#what-s-our-coverage
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'caller_id'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install caller_id
18
+
19
+ ## Usage
20
+
21
+ c = CallerId::ReversePhoneLookup "+1 (202) 456-1414", open_cnam_username, open_cnam_api_key
22
+ # Username and key are optional. Sign up at http://opencnam.com to get them.
23
+ c.lookup
24
+ # {:cnam => "WHITE HOUSE SWI", :number => "2024561414"}
25
+
26
+ Note: if a number has not yet been mapped by OpenCNAM, you'll get a response containing :retry => true (see the spec).
27
+
28
+ In that case you should wait a few seconds and then try the call again. You may want to do this in a background queue.
29
+
30
+ Also note, the "cnam" value returned by a successful lookup is just a caller id string, all caps, with varying semantics.
31
+
32
+ I've seen:
33
+ * [first last]
34
+ * [last first]
35
+ * [last, first middle]
36
+
37
+ If you do need to parse it into first and last name, be aware that the string format varies wildly. One possible
38
+ approach would be to do this:
39
+
40
+ first_and_maybe_middle_initial, last = result[:cname].split(",",2).reverse.join(" ").split(" ",2)
41
+
42
+ But be warned that this will not always parse them correctly, and that in some cases the string returned might not even be a name
43
+ (see the White House example). You might want to treat it as a "best guess" that should then be confirmed via other sources.
44
+
45
+ If you do not sign up for a username and API key with OpenCNAM, be aware that they currently throttle free requests to 60 per hour.
46
+ Also note the username and API keys will soon be associated with a price plan.
47
+
48
+ ## Contributing
49
+
50
+ 1. Fork it
51
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
52
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
53
+ 4. Push to the branch (`git push origin my-new-feature`)
54
+ 5. Create new Pull Request
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ task :default => :spec
7
+
8
+
9
+ desc "Run specs"
10
+ RSpec::Core::RakeTask.new do |t|
11
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
12
+ # Put spec opts in a file named .rspec in root
13
+ end
14
+
15
+ desc "Generate code coverage"
16
+ RSpec::Core::RakeTask.new(:coverage) do |t|
17
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
18
+ t.rcov = true
19
+ t.rcov_opts = ['--exclude', 'spec']
20
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/caller_id/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Ben Ellis"]
6
+ gem.email = ["bellis@on-site.com"]
7
+ gem.description = %q{Ruby wrapper for OpenCNAM}
8
+ gem.summary = %q{Do reverse phone lookups via OpenCNAM ( http://www.opencnam.com/ )}
9
+ gem.homepage = "https://github.com/on-site/caller_id"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "caller_id"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = CallerId::VERSION
17
+
18
+ gem.add_development_dependency "bundler", ">= 1.0.0"
19
+ gem.add_development_dependency "rspec", "~> 2.6"
20
+ gem.add_development_dependency "vcr", "~> 2.1"
21
+ gem.add_development_dependency "webmock", "1.8.6"
22
+ gem.add_development_dependency "timecop", "~> 0.3"
23
+
24
+ gem.add_dependency "json"
25
+
26
+ end
@@ -0,0 +1,38 @@
1
+ require "caller_id/version"
2
+ require "json"
3
+ require "open-uri"
4
+
5
+ module CallerId
6
+ # This class leverages the OpenCNAM service to lookup names from phone numbers.
7
+ # http://docs.opencnam.com/guide.html
8
+ class ReversePhoneLookup
9
+ def initialize number, user = nil, key = nil
10
+ @phone_number = number.to_s.gsub(/\D/,'').gsub(/\A1/,'') # strip spaces, punctuation, and leading 1s.
11
+ # TODO: consider raising a specific Exception here.
12
+ raise "invalid format" if @phone_number.nil? || @phone_number.strip.empty? || @phone_number.length != 10
13
+ if user && key
14
+ @api_user = user
15
+ @api_key = key
16
+ end
17
+ end
18
+ # Derived from https://github.com/EricR/sinatra-cnam-lookup/blob/master/cnam_checker.rb
19
+ def lookup
20
+ begin
21
+ response = open(get_url)
22
+ rescue OpenURI::HTTPError
23
+ return {:not_found => true}
24
+ end
25
+ return {:retry => true, :now => Time.now} if response.status[0] == "202"
26
+ return if response.status[0] != "200"
27
+ json_response = response.read
28
+ results = JSON.parse(json_response)
29
+ {:cnam => results["cnam"].strip, :number => results["number"]}
30
+ end
31
+ private
32
+ def get_url
33
+ url = "https://api.opencnam.com/v1/phone/#{@phone_number}?format=json"
34
+ url += "&username=#{@api_user}&api_key=#{@api_key}" if @api_user && @api_key
35
+ url
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module CallerId
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'caller_id'
3
+
4
+ describe CallerId do
5
+ let(:white_house_num) { "2024561414" }
6
+ let(:white_house_lookup_response) { {:cnam => "WHITE HOUSE SWI", :number => white_house_num} }
7
+ let(:kevin_brower) { "(510) 883-1085"}
8
+ let(:not_found) { "5034871414" }
9
+ let(:now) { Time.now }
10
+ describe "#lookup" do
11
+ use_vcr_cassette
12
+ it "returns name" do
13
+ CallerId::ReversePhoneLookup.new(white_house_num).lookup.should == white_house_lookup_response
14
+ end
15
+ it "ignores leading 1" do
16
+ CallerId::ReversePhoneLookup.new("1#{white_house_num}").lookup.should == white_house_lookup_response
17
+ end
18
+ it "ignores anything other than numbers" do
19
+ CallerId::ReversePhoneLookup.new("+1(#{white_house_num})...").lookup.should == white_house_lookup_response
20
+ end
21
+ end
22
+ describe "#lookup uncached number" do
23
+ use_vcr_cassette
24
+ it "returns retry" do
25
+ Timecop.freeze(now) do
26
+ CallerId::ReversePhoneLookup.new(kevin_brower).lookup.should == {:retry => true, :now => now}
27
+ end
28
+ end
29
+ end
30
+ describe "#lookup unlisted number" do
31
+ use_vcr_cassette
32
+ it "returns not found" do
33
+ CallerId::ReversePhoneLookup.new(not_found).lookup.should == {:not_found => true}
34
+ end
35
+ end
36
+ describe "#lookup invalid number" do
37
+ it "raises an error before even trying the lookup" do
38
+ expect { CallerId::ReversePhoneLookup.new("foo") }.to raise_error
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.opencnam.com/v1/phone/2024561414?format=json
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ""
9
+ headers:
10
+ Accept:
11
+ - "*/*"
12
+ User-Agent:
13
+ - Ruby
14
+ response:
15
+ status:
16
+ code: 200
17
+ message: OK
18
+ headers:
19
+ Content-Type:
20
+ - application/json; charset=utf-8
21
+ Date:
22
+ - Mon, 18 Jun 2012 10:19:24 GMT
23
+ Server:
24
+ - gunicorn/0.14.2
25
+ Content-Length:
26
+ - "51"
27
+ Connection:
28
+ - keep-alive
29
+ body:
30
+ encoding: US-ASCII
31
+ string: "{\"cnam\": \"WHITE HOUSE SWI\", \"number\": \"2024561414\"}"
32
+ http_version:
33
+ recorded_at: Mon, 18 Jun 2012 10:19:25 GMT
34
+ recorded_with: VCR 2.2.2
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.opencnam.com/v1/phone/5108831085?format=json
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ""
9
+ headers:
10
+ Accept:
11
+ - "*/*"
12
+ User-Agent:
13
+ - Ruby
14
+ response:
15
+ status:
16
+ code: 202
17
+ message: ACCEPTED
18
+ headers:
19
+ Content-Type:
20
+ - text/html; charset=utf-8
21
+ Date:
22
+ - Fri, 15 Jun 2012 15:09:25 GMT
23
+ Server:
24
+ - gunicorn/0.14.2
25
+ Content-Length:
26
+ - '86'
27
+ Connection:
28
+ - keep-alive
29
+ body:
30
+ encoding: US-ASCII
31
+ string: Currently running a lookup for phone '5108831085'. Please check back in a few seconds.
32
+ http_version:
33
+ recorded_at: Fri, 15 Jun 2012 15:09:25 GMT
34
+ recorded_with: VCR 2.2.2
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.opencnam.com/v1/phone/5034871414?format=json
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ""
9
+ headers:
10
+ Accept:
11
+ - "*/*"
12
+ User-Agent:
13
+ - Ruby
14
+ response:
15
+ status:
16
+ code: 404
17
+ message: NOT FOUND
18
+ headers:
19
+ Content-Type:
20
+ - text/html; charset=utf-8
21
+ Date:
22
+ - Mon, 18 Jun 2012 10:19:27 GMT
23
+ Server:
24
+ - gunicorn/0.14.2
25
+ Content-Length:
26
+ - "0"
27
+ Connection:
28
+ - keep-alive
29
+ body:
30
+ encoding: US-ASCII
31
+ string: ""
32
+ http_version:
33
+ recorded_at: Mon, 18 Jun 2012 10:19:28 GMT
34
+ recorded_with: VCR 2.2.2
@@ -0,0 +1,12 @@
1
+ require 'timecop'
2
+ require 'vcr'
3
+
4
+ VCR.configure do |c|
5
+ c.cassette_library_dir = 'spec/cassettes'
6
+
7
+ c.hook_into :webmock
8
+ end
9
+
10
+ RSpec.configure do |config|
11
+ config.extend VCR::RSpec::Macros
12
+ end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caller_id
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ben Ellis
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-18 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: &2153249760 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.0.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2153249760
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &2153249140 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: '2.6'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2153249140
36
+ - !ruby/object:Gem::Dependency
37
+ name: vcr
38
+ requirement: &2153248560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '2.1'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2153248560
47
+ - !ruby/object:Gem::Dependency
48
+ name: webmock
49
+ requirement: &2153247980 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - =
53
+ - !ruby/object:Gem::Version
54
+ version: 1.8.6
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2153247980
58
+ - !ruby/object:Gem::Dependency
59
+ name: timecop
60
+ requirement: &2153247400 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: '0.3'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2153247400
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: &2153246920 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *2153246920
80
+ description: Ruby wrapper for OpenCNAM
81
+ email:
82
+ - bellis@on-site.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - Gemfile
88
+ - Gemfile.lock
89
+ - LICENSE
90
+ - README.md
91
+ - Rakefile
92
+ - caller_id.gemspec
93
+ - lib/caller_id.rb
94
+ - lib/caller_id/version.rb
95
+ - spec/caller_id_spec.rb
96
+ - spec/cassettes/CallerId/_lookup.yml
97
+ - spec/cassettes/CallerId/_lookup_uncached_number.yml
98
+ - spec/cassettes/CallerId/_lookup_unlisted_number.yml
99
+ - spec/spec_helper.rb
100
+ homepage: https://github.com/on-site/caller_id
101
+ licenses: []
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 1.8.11
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: Do reverse phone lookups via OpenCNAM ( http://www.opencnam.com/ )
124
+ test_files:
125
+ - spec/caller_id_spec.rb
126
+ - spec/cassettes/CallerId/_lookup.yml
127
+ - spec/cassettes/CallerId/_lookup_uncached_number.yml
128
+ - spec/cassettes/CallerId/_lookup_unlisted_number.yml
129
+ - spec/spec_helper.rb