kickboxer 0.0.1

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,231 @@
1
+ {
2
+ "status": 200,
3
+ "contactInfo": {
4
+ "familyName": "Lorang",
5
+ "givenName": "Bart",
6
+ "fullName": "Bart Lorang",
7
+ "websites":
8
+ [
9
+ {
10
+ "url": "http://blog.fullcontact.com"
11
+ },
12
+ {
13
+ "url": "http://fullcontact.com"
14
+ }
15
+ ]
16
+ },
17
+ "photos":
18
+ [
19
+ {
20
+ "typeName": "Twitter",
21
+ "type": "twitter",
22
+ "typeId": "twitter",
23
+ "url": "http://a0.twimg.com/profile_images/1364842224/Bart_Profile_1_normal.jpg"
24
+ },
25
+ {
26
+ "url": "http://social.sxsw.com//system/badge_photos/46809/thumb/photo.jpg",
27
+ "type": "sxsw",
28
+ "typeId": "sxsw",
29
+ "typeName": "SxSW"
30
+ },
31
+ {
32
+ "typeName": "Facebook",
33
+ "type": "facebook",
34
+ "typeId": "facebook",
35
+ "url": "http://profile.ak.fbcdn.net/hprofile-ak-snc4/161274_651620441_7937905_n.jpg",
36
+ "isPrimary": true
37
+ },
38
+ {
39
+ "typeName": "Quora",
40
+ "type": "quora",
41
+ "typeId": "quora",
42
+ "url": "http://qph.cf.quoracdn.net/main-thumb-235179-50-jKTxWZQMbAl9MrGaLTDAs19WUiZoCuPW.jpeg"
43
+ },
44
+ {
45
+ "typeName": "Linkedin",
46
+ "type": "linkedin",
47
+ "typeId": "linkedin",
48
+ "url": "http://media.linkedin.com/mpr/pub/image-24YYLlk7VOVyx4vHbB2m_YZnM8tEVXNxn4NgrixwM2axoWjK24YgfwS7MnuP13NJifCJ/bart-lorang.jpg"
49
+ },
50
+ {
51
+ "url": "http://qph.cf.quoracdn.net/main-thumb-235179-200-jKTxWZQMbAl9MrGaLTDAs19WUiZoCuPW.jpeg",
52
+ "type": "quora",
53
+ "typeId": "quora",
54
+ "typeName": "Quora"
55
+ },
56
+ {
57
+ "url": "http://media.linkedin.com/mpr/pub/image-8kD9yK95845PPSkQ3U3ryL0B2bTfOSKQ2EBfy9Si3h5FEh6_/bart-lorang.jpg",
58
+ "type": "linkedin",
59
+ "typeId": "linkedin",
60
+ "typeName": "Linkedin"
61
+ }
62
+ ],
63
+ "demographics": {
64
+ "locationGeneral": "Boulder, Colorado",
65
+ "gender": "male"
66
+ },
67
+ "digitalFootprint": {
68
+ "topics":
69
+ [
70
+ {
71
+ "value": "angel investing",
72
+ "provider": "klout"
73
+ },
74
+ {
75
+ "value": "technology",
76
+ "provider": "klout"
77
+ },
78
+ {
79
+ "value": "denver broncos",
80
+ "provider": "klout"
81
+ },
82
+ {
83
+ "value": "tim tebow",
84
+ "provider": "klout"
85
+ },
86
+ {
87
+ "value": "sxsw",
88
+ "provider": "klout"
89
+ }
90
+ ],
91
+ "scores":
92
+ [
93
+ {
94
+ "value": 48.41,
95
+ "provider": "klout",
96
+ "type": "general"
97
+ },
98
+ {
99
+ "value": 31.4,
100
+ "provider": "klout",
101
+ "type": "network"
102
+ },
103
+ {
104
+ "value": 978,
105
+ "provider": "klout",
106
+ "type": "reach"
107
+ },
108
+ {
109
+ "value": 21,
110
+ "provider": "klout",
111
+ "type": "amplification"
112
+ }
113
+ ]
114
+ },
115
+ "socialProfiles":
116
+ [
117
+ {
118
+ "id": 5998422,
119
+ "typeName": "Twitter",
120
+ "following": 507,
121
+ "followers": 750,
122
+ "username": "lorangb",
123
+ "bio": "CEO & Co-Founder of @FullContactApp and @FullContactAPI - Tech Entrepreneur and Angel Investor.",
124
+ "type": "twitter",
125
+ "typeId": "twitter",
126
+ "url": "http://www.twitter.com/lorangb",
127
+ "rss": "http://twitter.com/statuses/user_timeline/lorangb.rss"
128
+ },
129
+ {
130
+ "type": "sxsw",
131
+ "url": "http://social.sxsw.com/users/46809",
132
+ "id": 46809,
133
+ "typeId": "sxsw",
134
+ "typeName": "SxSW"
135
+ },
136
+ {
137
+ "typeName": "Klout",
138
+ "username": "lorangb",
139
+ "type": "klout",
140
+ "typeId": "klout",
141
+ "url": "http://www.klout.com/lorangb"
142
+ },
143
+ {
144
+ "url": "http://www.myspace.com/137200880",
145
+ "type": "myspace",
146
+ "typeId": "myspace",
147
+ "typeName": "Myspace"
148
+ },
149
+ {
150
+ "url": "http://www.facebook.com/bartlorang",
151
+ "username": "bartlorang",
152
+ "type": "facebook",
153
+ "typeId": "facebook",
154
+ "typeName": "Facebook",
155
+ "id": "651620441"
156
+ },
157
+ {
158
+ "typeName": "About Me",
159
+ "username": "lorangb",
160
+ "type": "aboutme",
161
+ "typeId": "aboutme",
162
+ "url": "http://about.me/lorangb"
163
+ },
164
+ {
165
+ "typeName": "Flickr",
166
+ "id": "39267654@N00",
167
+ "rss": "http://api.flickr.com/services/feeds/photos_public.gne?id=39267654@N00&lang=en-us&format=rss_200",
168
+ "type": "flickr",
169
+ "typeId": "flickr",
170
+ "url": "http://www.flickr.com/photos/39267654@N00/"
171
+ },
172
+ {
173
+ "typeName": "Quora",
174
+ "username": "bart-lorang",
175
+ "type": "quora",
176
+ "typeId": "quora",
177
+ "url": "http://www.quora.com/bart-lorang"
178
+ },
179
+ {
180
+ "typeName": "Linkedin",
181
+ "username": "bartlorang",
182
+ "type": "linkedin",
183
+ "typeId": "linkedin",
184
+ "url": "http://www.linkedin.com/in/bartlorang"
185
+ },
186
+ {
187
+ "typeName": "Foursquare",
188
+ "username": "lorangb",
189
+ "type": "foursquare",
190
+ "typeId": "foursquare",
191
+ "url": "http://foursquare.com/lorangb"
192
+ },
193
+ {
194
+ "typeName": "Google Profile",
195
+ "username": "lorangb",
196
+ "type": "googleprofile",
197
+ "typeId": "googleprofile",
198
+ "url": "http://profiles.google.com/lorangb"
199
+ },
200
+ {
201
+ "typeName": "Youtube",
202
+ "username": "rainmaker0MakeitRain",
203
+ "type": "youtube",
204
+ "typeId": "youtube",
205
+ "url": "http://youtube.com/user/rainmaker0MakeitRain",
206
+ "rss": "http://youtube.com/rss/user/lorangb/videos.rss"
207
+ },
208
+ {
209
+ "typeName": "Plancast",
210
+ "id": "1634762",
211
+ "username": "lorangb",
212
+ "type": "plancast",
213
+ "typeId": "plancast",
214
+ "url": "http://plancast.com/user/1634762"
215
+ },
216
+ {
217
+ "typeName": "Tungle Me",
218
+ "type": "tungleme",
219
+ "typeId": "tungleme",
220
+ "url": "http://tungle.me/bartlorang"
221
+ }
222
+ ],
223
+ "organizations":
224
+ [
225
+ {
226
+ "name": "FullContact",
227
+ "title": "CEO",
228
+ "isPrimary": true
229
+ }
230
+ ]
231
+ }
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'kickboxer/config'
3
+
4
+ describe Kickboxer do
5
+ it 'stores an api key at the module level' do
6
+ Kickboxer.api_key = '12345'
7
+ Kickboxer.api_key.should eq '12345'
8
+
9
+ # cleanup
10
+ Kickboxer.api_key = nil
11
+ end
12
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'kickboxer/name'
3
+
4
+ describe Kickboxer::Name do
5
+ it 'returns a normalized name' do
6
+ stub_response('name-normalize')
7
+ response = Kickboxer::Name.normalize('Mr. John (Johnny) Michael Smith Jr.')
8
+
9
+ response.status_code.should eq 200
10
+ response.status_text.should eq 'OK'
11
+
12
+ response.likelihood.should eq 0.815
13
+ response.region.should eq 'USA'
14
+
15
+ details = response.nameDetails
16
+ details.givenName.should eq 'John'
17
+ details.familyName.should eq 'Smith'
18
+ details.middleNames.should eq %w( Michael )
19
+ details.prefixes.should eq %w( Mr. )
20
+ details.suffixes.should eq %w( Jr. )
21
+ details.nicknames.should eq %w( Johnny )
22
+ details.fullName.should eq 'John Michael Smith'
23
+ end
24
+
25
+ it 'deduces real name from email' do
26
+ stub_response('name-deduce-email')
27
+ response = Kickboxer::Name.deduce(email: 'johndsmith79@gmail.com')
28
+
29
+ response.status_code.should eq 200
30
+ response.status_text.should eq 'OK'
31
+
32
+ response.likelihood.should eq 0.665
33
+ response.region.should eq 'USA'
34
+
35
+ details = response.nameDetails
36
+ details.givenName.should eq 'John'
37
+ details.familyName.should eq 'Smith'
38
+ details.middleNames.should eq %w( D. )
39
+ details.fullName.should eq 'John D. Smith'
40
+ end
41
+
42
+ it 'calculates the similarity between two names' do
43
+ stub_response('name-similarity')
44
+ response = Kickboxer::Name.similarity('john', 'johnathan')
45
+
46
+ response.status_code.should eq 200
47
+ response.status_text.should eq 'OK'
48
+
49
+ result = response.result
50
+ sim_metrics = result.SimMetrics
51
+
52
+ jaro_winkler = sim_metrics.jaroWinkler
53
+ sprintf('%.4f', jaro_winkler.similarity).should eq '0.8889'
54
+ sprintf('%.4f', jaro_winkler.timeEstimated).should eq '0.0016'
55
+ jaro_winkler.timeActual.should eq 0
56
+
57
+ levenshtein = sim_metrics.levenshtein
58
+ sprintf('%.4f', levenshtein.similarity).should eq '0.4444'
59
+ sprintf('%.4f', levenshtein.timeEstimated).should eq '0.0065'
60
+ levenshtein.timeActual.should eq 0
61
+
62
+ second_string = result.SecondString
63
+
64
+ jaro_winkler = second_string.jaroWinkler
65
+ sprintf('%.4f', jaro_winkler.similarity).should eq '0.8889'
66
+ jaro_winkler.timeTaken.should eq "1 ms"
67
+
68
+ result.FullContact.BigramAnalysis.dice.similarity.should eq 0.5454545455
69
+ end
70
+
71
+ it 'returns statistics for an ambiguous name' do
72
+ stub_response('name-stats-ambiguous')
73
+ response = Kickboxer::Name.stats(name: 'john')
74
+
75
+ response.status_code.should eq 200
76
+ response.status_text.should eq 'OK'
77
+
78
+ response.name.given.likelihood.should eq 0.992
79
+ response.name.given.rank.should eq 3
80
+ response.name.given.male.likelihood.should eq 0.996
81
+ response.name.given.female.likelihood.should eq 0.004
82
+
83
+ response.name.family.likelihood.should eq 0.008
84
+ end
85
+
86
+ it 'returns statistics for a given name' do
87
+ stub_response('name-stats-given')
88
+ response = Kickboxer::Name.stats(givenName: 'john')
89
+
90
+ response.status_code.should eq 200
91
+ response.status_text.should eq 'OK'
92
+
93
+ response.name.given.should_not respond_to(:likelihood)
94
+ response.name.given.rank.should eq 3
95
+ response.name.given.male.likelihood.should eq 0.996
96
+ response.name.given.female.likelihood.should eq 0.004
97
+
98
+ response.name.should_not respond_to(:family)
99
+ end
100
+
101
+ it 'returns statistics for a family name' do
102
+ stub_response('name-stats-family')
103
+ response = Kickboxer::Name.stats(familyName: 'smith')
104
+
105
+ response.status_code.should eq 200
106
+ response.status_text.should eq 'OK'
107
+
108
+ response.name.family.should_not respond_to(:likelihood)
109
+ response.name.family.rank.should eq 1
110
+
111
+ response.name.should_not respond_to(:given)
112
+ end
113
+
114
+ it 'returns statistics for given and family name' do
115
+ stub_response('name-stats-both')
116
+ response = Kickboxer::Name.stats(givenName: 'john', familyName: 'smith')
117
+
118
+ response.status_code.should eq 200
119
+ response.status_text.should eq 'OK'
120
+
121
+ response.name.family.should_not respond_to(:likelihood)
122
+ response.name.family.rank.should eq 1
123
+
124
+ response.name.given.should_not respond_to(:likelihood)
125
+ response.name.given.rank.should eq 3
126
+ response.name.given.male.likelihood.should eq 0.996
127
+ response.name.given.female.likelihood.should eq 0.004
128
+ end
129
+
130
+ it 'parses full name strings into given and family names' do
131
+ stub_response('name-parse')
132
+ response = Kickboxer::Name.parse('john smith')
133
+
134
+ response.status_code.should eq 200
135
+ response.status_text.should eq 'OK'
136
+
137
+ response.result.givenName.should eq 'John'
138
+ response.result.familyName.should eq 'Smith'
139
+ response.result.likelihood.should eq 1
140
+ end
141
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+ require 'kickboxer/person'
3
+
4
+ describe Kickboxer::Person do
5
+ it 'looks up a person by email address' do
6
+ stub_response('person-email')
7
+ response = Kickboxer::Person.find_by_email('bart@fullcontact.com')
8
+
9
+ response.status_code.should eq 200
10
+ response.contactInfo.familyName.should eq 'Lorang'
11
+ response.contactInfo.givenName.should eq 'Bart'
12
+ response.contactInfo.websites.length.should eq 4
13
+ response.contactInfo.chats.length.should eq 2
14
+ response.photos.length.should eq 26
15
+ response.demographics.age.should eq '32'
16
+ response.demographics.locationGeneral.should eq 'Boulder, Colorado'
17
+ response.demographics.gender.should eq 'Male'
18
+ topics = response.digitalFootprint.topics.map{|topic| topic['value'] }
19
+ topics.should include 'entrepreneurship'
20
+ topics.should include 'tequila'
21
+ topics.should include 'tim tebow'
22
+ twitter = response.socialProfiles.detect{|p| p['type'] == 'twitter' }
23
+ twitter['url'].should eq 'http://www.twitter.com/lorangb'
24
+ organizations = response.organizations.map{|o| o['name'] }
25
+ organizations.should include 'FullContact'
26
+ organizations.should include 'Techstars'
27
+ organizations.should include 'Rainmaker Technologies'
28
+ end
29
+
30
+ it 'looks up a person by phone number' do
31
+ stub_response('person-phone')
32
+ response = Kickboxer::Person.find_by_phone_number('+13037170414')
33
+
34
+ response.status_code.should eq 200
35
+ response.contactInfo.familyName.should eq 'Lorang'
36
+ response.contactInfo.givenName.should eq 'Bart'
37
+ response.contactInfo.websites.length.should eq 5
38
+ response.contactInfo.chats.length.should eq 2
39
+ response.photos.length.should eq 24
40
+ response.demographics.age.should eq '32'
41
+ response.demographics.locationGeneral.should eq 'Denver, Colorado, United States'
42
+ response.demographics.gender.should eq 'male'
43
+ topics = response.digitalFootprint.topics.map{|topic| topic['value'] }
44
+ topics.should include 'entrepreneurship'
45
+ topics.should include 'tequila'
46
+ topics.should include 'tim tebow'
47
+ twitter = response.socialProfiles.detect{|p| p['type'] == 'twitter' }
48
+ twitter['url'].should eq 'http://www.twitter.com/lorangb'
49
+ organizations = response.organizations.map{|o| o['name'] }
50
+ organizations.should include 'FullContact'
51
+ end
52
+
53
+ it 'looks up a person by twitter username' do
54
+ stub_response('person-twitter')
55
+ response = Kickboxer::Person.find_by_twitter('lorangb')
56
+
57
+ response.status_code.should eq 200
58
+ response.contactInfo.familyName.should eq 'Lorang'
59
+ response.contactInfo.givenName.should eq 'Bart'
60
+ response.contactInfo.websites.length.should eq 2
61
+ response.photos.length.should eq 7
62
+ response.demographics.locationGeneral.should eq 'Boulder, Colorado'
63
+ response.demographics.gender.should eq 'male'
64
+ topics = response.digitalFootprint.topics.map{|topic| topic['value'] }
65
+ topics.should include 'angel investing'
66
+ topics.should include 'technology'
67
+ topics.should include 'tim tebow'
68
+ twitter = response.socialProfiles.detect{|p| p['type'] == 'twitter' }
69
+ twitter['url'].should eq 'http://www.twitter.com/lorangb'
70
+ organizations = response.organizations.map{|o| o['name'] }
71
+ organizations.should include 'FullContact'
72
+ end
73
+
74
+ it 'looks up a person by facebook username' do
75
+ stub_response('person-facebook')
76
+ response = Kickboxer::Person.find_by_facebook('bart.lorang')
77
+
78
+ response.status_code.should eq 200
79
+ response.contactInfo.familyName.should eq 'Lorang'
80
+ response.contactInfo.givenName.should eq 'Bart'
81
+ response.contactInfo.websites.length.should eq 1
82
+ response.photos.length.should eq 3
83
+ response.demographics.gender.should eq 'male'
84
+ twitter = response.socialProfiles.detect{|p| p['type'] == 'twitter' }
85
+ twitter['url'].should eq 'http://twitter.com/lorangb'
86
+ end
87
+ end