omnicontacts 0.3.5 → 0.3.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +16 -22
- data/README.md +32 -1
- data/lib/omnicontacts.rb +1 -1
- data/lib/omnicontacts/http_utils.rb +1 -1
- data/lib/omnicontacts/importer.rb +1 -0
- data/lib/omnicontacts/importer/gmail.rb +3 -2
- data/lib/omnicontacts/importer/linkedin.rb +63 -0
- data/lib/omnicontacts/middleware/oauth2.rb +3 -3
- data/spec/omnicontacts/importer/gmail_spec.rb +6 -0
- data/spec/omnicontacts/importer/linkedin_spec.rb +67 -0
- metadata +35 -19
- checksums.yaml +0 -7
data/Gemfile.lock
CHANGED
@@ -8,31 +8,25 @@ PATH
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
-
diff-lcs (1.
|
12
|
-
docile (1.1.5)
|
11
|
+
diff-lcs (1.1.3)
|
13
12
|
json (1.8.1)
|
14
|
-
multi_json (1.
|
15
|
-
rack (1.
|
16
|
-
rack-test (0.6.
|
13
|
+
multi_json (1.1.0)
|
14
|
+
rack (1.4.1)
|
15
|
+
rack-test (0.6.1)
|
17
16
|
rack (>= 1.0)
|
18
|
-
rake (
|
19
|
-
rspec (
|
20
|
-
rspec-core (~>
|
21
|
-
rspec-expectations (~>
|
22
|
-
rspec-mocks (~>
|
23
|
-
rspec-core (
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
rspec-mocks (3.1.3)
|
29
|
-
rspec-support (~> 3.1.0)
|
30
|
-
rspec-support (3.1.2)
|
31
|
-
simplecov (0.9.1)
|
32
|
-
docile (~> 1.1.0)
|
17
|
+
rake (0.9.2.2)
|
18
|
+
rspec (2.8.0)
|
19
|
+
rspec-core (~> 2.8.0)
|
20
|
+
rspec-expectations (~> 2.8.0)
|
21
|
+
rspec-mocks (~> 2.8.0)
|
22
|
+
rspec-core (2.8.0)
|
23
|
+
rspec-expectations (2.8.0)
|
24
|
+
diff-lcs (~> 1.1.2)
|
25
|
+
rspec-mocks (2.8.0)
|
26
|
+
simplecov (0.6.1)
|
33
27
|
multi_json (~> 1.0)
|
34
|
-
simplecov-html (~> 0.
|
35
|
-
simplecov-html (0.
|
28
|
+
simplecov-html (~> 0.5.3)
|
29
|
+
simplecov-html (0.5.3)
|
36
30
|
|
37
31
|
PLATFORMS
|
38
32
|
ruby
|
data/README.md
CHANGED
@@ -8,6 +8,14 @@ OmniContacts uses the OAuth protocol to communicate with the contacts provider.
|
|
8
8
|
Facebook, Gmail and Hotmail support OAuth 2.0.
|
9
9
|
In order to use OmniContacts, it is therefore necessary to first register your application with the provider and to obtain client_id and client_secret.
|
10
10
|
|
11
|
+
## Contribute!
|
12
|
+
Me (rubytastic) and the orginal author Diego don't actively use this code at the moment, anyone interested in maintaining and contributing to this codebase please write me up in a personal message ( rubytastic )
|
13
|
+
I try to merge pull requests in every once and a while but this code would benefit from someone actively use and contribute to it.
|
14
|
+
|
15
|
+
## Gem build updates
|
16
|
+
There is now a new gem build out which should address many issues people had when posting on the issue tracker. Please update to the latest GEM version if you have problems before posting new issues.
|
17
|
+
|
18
|
+
|
11
19
|
## Usage
|
12
20
|
|
13
21
|
Add OmniContacts as a dependency:
|
@@ -25,13 +33,14 @@ require "omnicontacts"
|
|
25
33
|
Rails.application.middleware.use OmniContacts::Builder do
|
26
34
|
importer :gmail, "client_id", "client_secret", {:redirect_path => "/oauth2callback", :ssl_ca_file => "/etc/ssl/certs/curl-ca-bundle.crt"}
|
27
35
|
importer :yahoo, "consumer_id", "consumer_secret", {:callback_path => '/callback'}
|
36
|
+
importer :linkedin, "consumer_id", "consumer_secret", {:redirect_path => "/oauth2callback", :state => '<long_unique_string_value>'}
|
28
37
|
importer :hotmail, "client_id", "client_secret"
|
29
38
|
importer :facebook, "client_id", "client_secret"
|
30
39
|
end
|
31
40
|
|
32
41
|
```
|
33
42
|
|
34
|
-
Every importer expects `client_id` and `client_secret` as mandatory, while `:redirect_path` and `:ssl_ca_file` are optional.
|
43
|
+
Every importer expects `client_id` and `client_secret` as mandatory, while `:redirect_path` and `:ssl_ca_file` are optional (except linkedin - `state` arg mandatory).
|
35
44
|
Since Yahoo implements the version 1.0 of the OAuth protocol, naming is slightly different. Instead of `:redirect_path` you should use `:callback_path` as key in the hash providing the optional parameters.
|
36
45
|
While `:ssl_ca_file` is optional, it is highly recommended to set it on production environments for obvious security reasons.
|
37
46
|
On the other hand it makes things much easier to leave the default value for `:redirect_path` and `:callback path`, the reason of which will be clear after reading the following section.
|
@@ -46,6 +55,9 @@ On the other hand it makes things much easier to leave the default value for `:r
|
|
46
55
|
|
47
56
|
* For Facebook : [Facebook Developers](https://developers.facebook.com/apps)
|
48
57
|
|
58
|
+
* For Linkedin : [Linkedin Developer Network](https://www.linkedin.com/secure/developer)
|
59
|
+
|
60
|
+
|
49
61
|
##### Note:
|
50
62
|
Please go through [MSDN](http://msdn.microsoft.com/en-us/library/cc287659.aspx) if above Hotmail link will not work.
|
51
63
|
|
@@ -159,6 +171,25 @@ The following table shows which fields are supported by which provider:
|
|
159
171
|
<td>X</td>
|
160
172
|
<td></td>
|
161
173
|
</tr>
|
174
|
+
<tr>
|
175
|
+
<td>Linkedin</td>
|
176
|
+
<td></td>
|
177
|
+
<td>X</td>
|
178
|
+
<td>X</td>
|
179
|
+
<td>X</td>
|
180
|
+
<td>X</td>
|
181
|
+
<td>X</td>
|
182
|
+
<td></td>
|
183
|
+
<td></td>
|
184
|
+
<td></td>
|
185
|
+
<td></td>
|
186
|
+
<td></td>
|
187
|
+
<td></td>
|
188
|
+
<td></td>
|
189
|
+
<td></td>
|
190
|
+
<td></td>
|
191
|
+
<td></td>
|
192
|
+
<tr>
|
162
193
|
</table>
|
163
194
|
|
164
195
|
Obviously it may happen that some fields are blank even if supported by the provider in the case that the contact did not provide any information about them.
|
data/lib/omnicontacts.rb
CHANGED
@@ -57,7 +57,7 @@ module OmniContacts
|
|
57
57
|
# If the result of ssl_ca_file is nil no file is used. In this case a warn message is logged.
|
58
58
|
private
|
59
59
|
|
60
|
-
# Executes an HTTP GET request.
|
60
|
+
# Executes an HTTP GET request.
|
61
61
|
# It raises a RuntimeError if the response code is not equal to 200
|
62
62
|
def http_get host, path, params
|
63
63
|
connection = Net::HTTP.new(host)
|
@@ -13,7 +13,7 @@ module OmniContacts
|
|
13
13
|
@auth_host = "accounts.google.com"
|
14
14
|
@authorize_path = "/o/oauth2/auth"
|
15
15
|
@auth_token_path = "/o/oauth2/token"
|
16
|
-
@scope = "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile"
|
16
|
+
@scope = (args[3] && args[3][:scope]) || "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile"
|
17
17
|
@contacts_host = "www.google.com"
|
18
18
|
@contacts_path = "/m8/feeds/contacts/default/full"
|
19
19
|
@max_results = (args[3] && args[3][:max_results]) || 100
|
@@ -45,6 +45,7 @@ module OmniContacts
|
|
45
45
|
|
46
46
|
def contacts_from_response response_as_json
|
47
47
|
response = JSON.parse(response_as_json)
|
48
|
+
|
48
49
|
return [] if response['feed'].nil? || response['feed']['entry'].nil?
|
49
50
|
contacts = []
|
50
51
|
return contacts if response.nil?
|
@@ -88,7 +89,7 @@ module OmniContacts
|
|
88
89
|
# Support older versions of the gem by keeping singular entries around
|
89
90
|
contact[:email] = contact[:emails][0][:email] if contact[:emails][0]
|
90
91
|
contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:name]) if !contact[:name].nil? && contact[:name].include?('@')
|
91
|
-
contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:emails][0][:email]) if contact[:name].nil? && contact[:emails][0][:email]
|
92
|
+
contact[:first_name], contact[:last_name], contact[:name] = email_to_name(contact[:emails][0][:email]) if (contact[:name].nil? && contact[:emails][0] && contact[:emails][0][:email])
|
92
93
|
#format - year-month-date
|
93
94
|
contact[:birthday] = birthday(entry['gContact$birthday']['when']) if entry['gContact$birthday']
|
94
95
|
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "omnicontacts/parse_utils"
|
2
|
+
require "omnicontacts/middleware/oauth2"
|
3
|
+
|
4
|
+
module OmniContacts
|
5
|
+
module Importer
|
6
|
+
class Linkedin < Middleware::OAuth2
|
7
|
+
include ParseUtils
|
8
|
+
|
9
|
+
attr_reader :auth_host, :authorize_path, :auth_token_path, :scope, :state
|
10
|
+
|
11
|
+
def initialize *args
|
12
|
+
super *args
|
13
|
+
@auth_host = "www.linkedin.com"
|
14
|
+
@authorize_path = "/uas/oauth2/authorization"
|
15
|
+
@auth_token_path = "/uas/oauth2/accessToken"
|
16
|
+
@scope = (args[3] && args[3][:scope]) || "r_network"
|
17
|
+
@contacts_host = "api.linkedin.com"
|
18
|
+
@contacts_path = "/v1/people/~/connections:(id,first-name,last-name,picture-url)"
|
19
|
+
@self_host = "www.linkedin.com"
|
20
|
+
@profile_path = "/oauth2/v1/userinfo"
|
21
|
+
@state = (args[3] && args[3][:state])
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch_contacts_using_access_token access_token, token_type
|
25
|
+
token_type = "Bearer" if token_type.nil?
|
26
|
+
contacts_response = https_get(@contacts_host, @contacts_path, contacts_req_params, contacts_req_headers(access_token, token_type))
|
27
|
+
contacts_from_response contacts_response
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def contacts_req_params
|
33
|
+
{'format' => 'json'}
|
34
|
+
end
|
35
|
+
|
36
|
+
def contacts_req_headers token, token_type
|
37
|
+
{"Authorization" => "#{token_type} #{token}"}
|
38
|
+
end
|
39
|
+
|
40
|
+
def contacts_from_response response_as_json
|
41
|
+
response = JSON.parse(response_as_json)
|
42
|
+
return [] if response['values'].nil?
|
43
|
+
contacts = []
|
44
|
+
return contacts if response.nil?
|
45
|
+
response['values'].map do |entry|
|
46
|
+
{
|
47
|
+
id: entry['id'],
|
48
|
+
first_name: normalize_name(entry['firstName']),
|
49
|
+
last_name: normalize_name(entry['lastName']),
|
50
|
+
name: full_name(entry['firstName'],entry['lastName']),
|
51
|
+
profile_picture: entry['pictureUrl']
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def authorize_url_params
|
57
|
+
# merge state param required by LinkedIn
|
58
|
+
_params = super
|
59
|
+
_params += "&" + to_query_string(state: @state)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -5,7 +5,7 @@ require "omnicontacts/middleware/base_oauth"
|
|
5
5
|
#
|
6
6
|
# Extending class are required to implement
|
7
7
|
# the following methods:
|
8
|
-
# * fetch_contacts_using_access_token -> it
|
8
|
+
# * fetch_contacts_using_access_token -> it
|
9
9
|
# fetches the list of contacts from the authorization
|
10
10
|
# server.
|
11
11
|
module OmniContacts
|
@@ -25,7 +25,7 @@ module OmniContacts
|
|
25
25
|
|
26
26
|
def request_authorization_from_user
|
27
27
|
target_url = append_state_query(authorization_url)
|
28
|
-
[302, {"location" => target_url}, []]
|
28
|
+
[302, {"Content-Type" => "application/x-www-form-urlencoded", "location" => target_url}, []]
|
29
29
|
end
|
30
30
|
|
31
31
|
def redirect_uri
|
@@ -34,7 +34,7 @@ module OmniContacts
|
|
34
34
|
|
35
35
|
# It extract the authorization code from the query string.
|
36
36
|
# It uses it to obtain an access token.
|
37
|
-
# If the authorization code has a refresh token associated
|
37
|
+
# If the authorization code has a refresh token associated
|
38
38
|
# with it in the session, it uses the obtain an access token.
|
39
39
|
# It fetches the list of contacts and stores the refresh token
|
40
40
|
# associated with the access token in the session.
|
@@ -5,6 +5,8 @@ describe OmniContacts::Importer::Gmail do
|
|
5
5
|
|
6
6
|
let(:gmail) { OmniContacts::Importer::Gmail.new({}, "client_id", "client_secret") }
|
7
7
|
|
8
|
+
let(:gmail_with_scope_args) { OmniContacts::Importer::Gmail.new({}, "client_id", "client_secret", {scope: "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/contacts.readonly"}) }
|
9
|
+
|
8
10
|
let(:self_response) {
|
9
11
|
'{
|
10
12
|
"id":"16482944006464829443",
|
@@ -110,6 +112,7 @@ describe OmniContacts::Importer::Gmail do
|
|
110
112
|
|
111
113
|
before(:each) do
|
112
114
|
gmail.instance_variable_set(:@env, {})
|
115
|
+
gmail_with_scope_args.instance_variable_set(:@env, {})
|
113
116
|
end
|
114
117
|
|
115
118
|
it "should request the contacts by specifying version and code in the http headers" do
|
@@ -124,6 +127,9 @@ describe OmniContacts::Importer::Gmail do
|
|
124
127
|
contacts_as_json
|
125
128
|
end
|
126
129
|
gmail.fetch_contacts_using_access_token token, token_type
|
130
|
+
|
131
|
+
gmail.scope.should eq "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/userinfo.profile"
|
132
|
+
gmail_with_scope_args.scope.should eq "https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo#email https://www.googleapis.com/auth/contacts.readonly"
|
127
133
|
end
|
128
134
|
|
129
135
|
it "should correctly parse id, name, email, gender, birthday, profile picture and relation for 1st contact" do
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "omnicontacts/importer/linkedin"
|
3
|
+
|
4
|
+
describe OmniContacts::Importer::Linkedin do
|
5
|
+
|
6
|
+
let(:linkedin) { OmniContacts::Importer::Linkedin.new({}, "client_id", "client_secret", state: "ipsaeumeaque") }
|
7
|
+
|
8
|
+
let(:contacts_as_json) do
|
9
|
+
"{
|
10
|
+
\n \"_total\": 2,
|
11
|
+
\n \"values\": [
|
12
|
+
\n {
|
13
|
+
\n \"firstName\": \"Adolf\",
|
14
|
+
\n \"id\": \"k71S5q6MKe\",
|
15
|
+
\n \"lastName\": \"Witting\",
|
16
|
+
\n \"pictureUrl\": \"https://media.licdn.com/mpr/mprx/0_mLnj-7szw130pFRLB8Op7-p1Sxoyv53U3B47Scp1Sxoyv53U3B47Scp1Sxoyv53U3B47Sc\"\n
|
17
|
+
},
|
18
|
+
\n {
|
19
|
+
\n \"firstName\": \"Emmet\",
|
20
|
+
\n \"id\": \"ms5r3lI3J2\",
|
21
|
+
\n \"lastName\": \"Little\",
|
22
|
+
\n \"pictureUrl\": \"https://media.licdn.com/mpr/mprx/0_iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6\"\n
|
23
|
+
}
|
24
|
+
]\n
|
25
|
+
}"
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "fetch_contacts_using_access_token" do
|
29
|
+
let(:token) { "token" }
|
30
|
+
let(:token_type) { nil }
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
linkedin.instance_variable_set(:@env, {})
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should request the contacts by specifying code in the http headers" do
|
37
|
+
linkedin.should_receive(:https_get) do |host, path, params, headers|
|
38
|
+
headers["Authorization"].should eq("Bearer #{token}")
|
39
|
+
contacts_as_json
|
40
|
+
end
|
41
|
+
linkedin.fetch_contacts_using_access_token token, token_type
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should correctly parse id, name, and profile picture for 1st contact" do
|
45
|
+
linkedin.should_receive(:https_get).and_return(contacts_as_json)
|
46
|
+
result = linkedin.fetch_contacts_using_access_token token, token_type
|
47
|
+
|
48
|
+
result.size.should be(2)
|
49
|
+
result.first[:id].should eq('k71S5q6MKe')
|
50
|
+
result.first[:first_name].should eq('Adolf')
|
51
|
+
result.first[:last_name].should eq('Witting')
|
52
|
+
result.first[:name].should eq("Adolf Witting")
|
53
|
+
result.first[:profile_picture].should eq("https://media.licdn.com/mpr/mprx/0_mLnj-7szw130pFRLB8Op7-p1Sxoyv53U3B47Scp1Sxoyv53U3B47Scp1Sxoyv53U3B47Sc")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should correctly parse id, name, and profile picture for 2nd contact" do
|
57
|
+
linkedin.should_receive(:https_get).and_return(contacts_as_json)
|
58
|
+
result = linkedin.fetch_contacts_using_access_token token, token_type
|
59
|
+
result.size.should be(2)
|
60
|
+
result.last[:id].should eq('ms5r3lI3J2')
|
61
|
+
result.last[:first_name].should eq('Emmet')
|
62
|
+
result.last[:last_name].should eq('Little')
|
63
|
+
result.last[:name].should eq("Emmet Little")
|
64
|
+
result.last[:profile_picture].should eq("https://media.licdn.com/mpr/mprx/0_iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6iH9m158zCdISt1X6")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omnicontacts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.6
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Diego Castorina
|
@@ -9,90 +10,102 @@ authors:
|
|
9
10
|
autorequire:
|
10
11
|
bindir: bin
|
11
12
|
cert_chain: []
|
12
|
-
date:
|
13
|
+
date: 2015-04-30 00:00:00.000000000 Z
|
13
14
|
dependencies:
|
14
15
|
- !ruby/object:Gem::Dependency
|
15
16
|
name: rack
|
16
17
|
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
17
19
|
requirements:
|
18
|
-
- - '>='
|
20
|
+
- - ! '>='
|
19
21
|
- !ruby/object:Gem::Version
|
20
22
|
version: '0'
|
21
23
|
type: :runtime
|
22
24
|
prerelease: false
|
23
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
24
27
|
requirements:
|
25
|
-
- - '>='
|
28
|
+
- - ! '>='
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: '0'
|
28
31
|
- !ruby/object:Gem::Dependency
|
29
32
|
name: json
|
30
33
|
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
31
35
|
requirements:
|
32
|
-
- - '>='
|
36
|
+
- - ! '>='
|
33
37
|
- !ruby/object:Gem::Version
|
34
38
|
version: '0'
|
35
39
|
type: :runtime
|
36
40
|
prerelease: false
|
37
41
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
38
43
|
requirements:
|
39
|
-
- - '>='
|
44
|
+
- - ! '>='
|
40
45
|
- !ruby/object:Gem::Version
|
41
46
|
version: '0'
|
42
47
|
- !ruby/object:Gem::Dependency
|
43
48
|
name: simplecov
|
44
49
|
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
45
51
|
requirements:
|
46
|
-
- - '>='
|
52
|
+
- - ! '>='
|
47
53
|
- !ruby/object:Gem::Version
|
48
54
|
version: '0'
|
49
55
|
type: :development
|
50
56
|
prerelease: false
|
51
57
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
52
59
|
requirements:
|
53
|
-
- - '>='
|
60
|
+
- - ! '>='
|
54
61
|
- !ruby/object:Gem::Version
|
55
62
|
version: '0'
|
56
63
|
- !ruby/object:Gem::Dependency
|
57
64
|
name: rake
|
58
65
|
requirement: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
59
67
|
requirements:
|
60
|
-
- - '>='
|
68
|
+
- - ! '>='
|
61
69
|
- !ruby/object:Gem::Version
|
62
70
|
version: '0'
|
63
71
|
type: :development
|
64
72
|
prerelease: false
|
65
73
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
66
75
|
requirements:
|
67
|
-
- - '>='
|
76
|
+
- - ! '>='
|
68
77
|
- !ruby/object:Gem::Version
|
69
78
|
version: '0'
|
70
79
|
- !ruby/object:Gem::Dependency
|
71
80
|
name: rack-test
|
72
81
|
requirement: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
73
83
|
requirements:
|
74
|
-
- - '>='
|
84
|
+
- - ! '>='
|
75
85
|
- !ruby/object:Gem::Version
|
76
86
|
version: '0'
|
77
87
|
type: :development
|
78
88
|
prerelease: false
|
79
89
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
80
91
|
requirements:
|
81
|
-
- - '>='
|
92
|
+
- - ! '>='
|
82
93
|
- !ruby/object:Gem::Version
|
83
94
|
version: '0'
|
84
95
|
- !ruby/object:Gem::Dependency
|
85
96
|
name: rspec
|
86
97
|
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
87
99
|
requirements:
|
88
|
-
- - '>='
|
100
|
+
- - ! '>='
|
89
101
|
- !ruby/object:Gem::Version
|
90
102
|
version: '0'
|
91
103
|
type: :development
|
92
104
|
prerelease: false
|
93
105
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
94
107
|
requirements:
|
95
|
-
- - '>='
|
108
|
+
- - ! '>='
|
96
109
|
- !ruby/object:Gem::Version
|
97
110
|
version: '0'
|
98
111
|
description: A generalized Rack middleware for importing contacts from major email
|
@@ -118,6 +131,7 @@ files:
|
|
118
131
|
- lib/omnicontacts/importer/facebook.rb
|
119
132
|
- lib/omnicontacts/importer/gmail.rb
|
120
133
|
- lib/omnicontacts/importer/hotmail.rb
|
134
|
+
- lib/omnicontacts/importer/linkedin.rb
|
121
135
|
- lib/omnicontacts/importer/yahoo.rb
|
122
136
|
- lib/omnicontacts/integration_test.rb
|
123
137
|
- lib/omnicontacts/middleware/base_oauth.rb
|
@@ -131,6 +145,7 @@ files:
|
|
131
145
|
- spec/omnicontacts/importer/facebook_spec.rb
|
132
146
|
- spec/omnicontacts/importer/gmail_spec.rb
|
133
147
|
- spec/omnicontacts/importer/hotmail_spec.rb
|
148
|
+
- spec/omnicontacts/importer/linkedin_spec.rb
|
134
149
|
- spec/omnicontacts/importer/yahoo_spec.rb
|
135
150
|
- spec/omnicontacts/integration_test_spec.rb
|
136
151
|
- spec/omnicontacts/middleware/base_oauth_spec.rb
|
@@ -140,25 +155,26 @@ files:
|
|
140
155
|
- spec/spec_helper.rb
|
141
156
|
homepage: http://github.com/Diego81/omnicontacts
|
142
157
|
licenses: []
|
143
|
-
metadata: {}
|
144
158
|
post_install_message:
|
145
159
|
rdoc_options: []
|
146
160
|
require_paths:
|
147
161
|
- lib
|
148
162
|
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
149
164
|
requirements:
|
150
|
-
- - '>='
|
165
|
+
- - ! '>='
|
151
166
|
- !ruby/object:Gem::Version
|
152
167
|
version: '0'
|
153
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
154
170
|
requirements:
|
155
|
-
- - '>='
|
171
|
+
- - ! '>='
|
156
172
|
- !ruby/object:Gem::Version
|
157
173
|
version: 1.3.6
|
158
174
|
requirements: []
|
159
175
|
rubyforge_project:
|
160
|
-
rubygems_version:
|
176
|
+
rubygems_version: 1.8.23
|
161
177
|
signing_key:
|
162
|
-
specification_version:
|
178
|
+
specification_version: 3
|
163
179
|
summary: A generalized Rack middleware for importing contacts from major email providers.
|
164
180
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 153f2fff78dd7440fe1c653a7458f47db2b8717a
|
4
|
-
data.tar.gz: f115709601214db1e8826893355146514c5c8b82
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 29f390858859e150129a1a01d3fbbe6d523b997ece36e113e6c8635d5c0ecb2cc47f77e2686c07503703a4a0148dd543842cebfa5d285f0923be01e5f5d4454c
|
7
|
-
data.tar.gz: 7850d3c9bd1f6309f0dd1065262c6b16f7aa947ba3f33deb186ba8bff3a9809e5baeb1e588b6cc817c7b159650f3692c44c522df1d062f62a37fffbd6a97b90a
|