linkedin-idkmybffjill 0.1.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +16 -0
- data/LICENSE +20 -0
- data/README.markdown +74 -0
- data/Rakefile +70 -0
- data/VERSION +1 -0
- data/examples/authenticate.rb +21 -0
- data/examples/network.rb +12 -0
- data/examples/profile.rb +14 -0
- data/examples/status.rb +9 -0
- data/lib/linked_in/api_standard_profile_request.rb +17 -0
- data/lib/linked_in/base.rb +13 -0
- data/lib/linked_in/birthdate.rb +21 -0
- data/lib/linked_in/client.rb +267 -0
- data/lib/linked_in/company.rb +11 -0
- data/lib/linked_in/connections.rb +19 -0
- data/lib/linked_in/country.rb +9 -0
- data/lib/linked_in/education.rb +44 -0
- data/lib/linked_in/error.rb +21 -0
- data/lib/linked_in/group.rb +35 -0
- data/lib/linked_in/location.rb +13 -0
- data/lib/linked_in/message.rb +31 -0
- data/lib/linked_in/network.rb +15 -0
- data/lib/linked_in/people.rb +21 -0
- data/lib/linked_in/person.rb +7 -0
- data/lib/linked_in/position.rb +49 -0
- data/lib/linked_in/profile.rb +54 -0
- data/lib/linked_in/recipient.rb +7 -0
- data/lib/linked_in/recipients.rb +14 -0
- data/lib/linked_in/update.rb +19 -0
- data/lib/linked_in/url_resource.rb +29 -0
- data/lib/linkedin.rb +97 -0
- data/test/client_test.rb +179 -0
- data/test/fixtures/blank.xml +0 -0
- data/test/fixtures/connections.xml +3733 -0
- data/test/fixtures/error.xml +7 -0
- data/test/fixtures/mailbox_items.xml +13 -0
- data/test/fixtures/network_status_with_group.xml +44 -0
- data/test/fixtures/network_statuses.xml +299 -0
- data/test/fixtures/picture_updates.xml +117 -0
- data/test/fixtures/profile.xml +9 -0
- data/test/fixtures/profile_full.xml +3849 -0
- data/test/fixtures/profile_with_positions.xml +79 -0
- data/test/fixtures/search.xml +538 -0
- data/test/fixtures/status.xml +2 -0
- data/test/oauth_test.rb +117 -0
- data/test/test_helper.rb +54 -0
- metadata +214 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Connections < LinkedIn::Base
|
3
|
+
|
4
|
+
def connections
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.xpath('//connections').children.each do |profile|
|
8
|
+
@array << Profile.new(Nokogiri::XML(profile.to_xml)) unless profile.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def profiles
|
15
|
+
connections
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Education < LinkedIn::Base
|
3
|
+
|
4
|
+
def education
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.children.each do |edu|
|
8
|
+
@array << Resource.new(edu) unless edu.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Resource
|
15
|
+
|
16
|
+
def initialize(education)
|
17
|
+
@education = education
|
18
|
+
end
|
19
|
+
|
20
|
+
%w[id school_name degree field_of_study activities].each do |f|
|
21
|
+
define_method(f.to_sym) do
|
22
|
+
@education.xpath("./#{f.gsub(/_/,'-')}").text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def start_month
|
27
|
+
@education.xpath('./start-date/month').text.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
def start_year
|
31
|
+
@education.xpath('./start-date/year').text.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def end_month
|
35
|
+
@education.xpath('./end-date/month').text.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_year
|
39
|
+
@education.xpath('./end-date/year').text.to_i
|
40
|
+
end
|
41
|
+
end # resource class
|
42
|
+
|
43
|
+
end # education class
|
44
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Error < LinkedIn::Base
|
3
|
+
|
4
|
+
def status
|
5
|
+
@doc.xpath('//status').text.to_i
|
6
|
+
end
|
7
|
+
|
8
|
+
def timestamp
|
9
|
+
@doc.xpath('//timestamp').text.to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def code
|
13
|
+
@doc.xpath('//error-coce').text.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
@doc.xpath('//message').text
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Group < LinkedIn::Base
|
3
|
+
|
4
|
+
def groups
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.children.each do |group|
|
8
|
+
@array << Resource.new(group) unless group.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Resource
|
15
|
+
|
16
|
+
def initialize(group)
|
17
|
+
@group = group
|
18
|
+
end
|
19
|
+
|
20
|
+
def id
|
21
|
+
@group.xpath('//member-group/id').text.to_i
|
22
|
+
end
|
23
|
+
|
24
|
+
def name
|
25
|
+
@group.xpath('//member-group/name').text
|
26
|
+
end
|
27
|
+
|
28
|
+
def url
|
29
|
+
@group.xpath('//member-group/site-group-request/url').text
|
30
|
+
end
|
31
|
+
|
32
|
+
end # resource class
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Message
|
3
|
+
|
4
|
+
attr_accessor :subject, :body, :recipients
|
5
|
+
|
6
|
+
def to_xml
|
7
|
+
"<mailbox-item>
|
8
|
+
<recipients>
|
9
|
+
#{recipients.to_xml}
|
10
|
+
</recipients>
|
11
|
+
<subject>#{subject}</subject>
|
12
|
+
<body>#{body}</body>
|
13
|
+
</mailbox-item>"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
# <mailbox-item>
|
21
|
+
# <recipients>
|
22
|
+
# <recipient>
|
23
|
+
# <person path='/people/~'/>
|
24
|
+
# </recipient>
|
25
|
+
# <recipient>
|
26
|
+
# <person path="/people/abcdefg" />
|
27
|
+
# </recipient>
|
28
|
+
# </recipients>
|
29
|
+
# <subject>Congratulations on your new position.</subject>
|
30
|
+
# <body>You're certainly the best person for the job!</body>
|
31
|
+
# </mailbox-item>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Network < LinkedIn::Base
|
3
|
+
|
4
|
+
def updates
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.xpath('//updates').children.each do |update|
|
8
|
+
@array << Update.new(Nokogiri::XML(update.to_xml)) unless update.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class People < LinkedIn::Base
|
3
|
+
|
4
|
+
%w[total start count].each do |f|
|
5
|
+
define_method(f.to_sym) do
|
6
|
+
@doc.xpath('.//people').first["#{f.gsub(/_/,'-')}"].to_i
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def profiles
|
11
|
+
@array ||= begin
|
12
|
+
@array = []
|
13
|
+
@doc.xpath('//people').children.each do |profile|
|
14
|
+
@array << Profile.new(Nokogiri::XML(profile.to_xml)) unless profile.blank?
|
15
|
+
end
|
16
|
+
@array
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Position < LinkedIn::Base
|
3
|
+
|
4
|
+
def positions
|
5
|
+
@arry ||= begin
|
6
|
+
@arry = []
|
7
|
+
@doc.children.each do |position|
|
8
|
+
@arry << Resource.new(position) unless position.blank?
|
9
|
+
end
|
10
|
+
@arry
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Resource
|
15
|
+
|
16
|
+
def initialize(position)
|
17
|
+
@position = position
|
18
|
+
end
|
19
|
+
|
20
|
+
%w[id title summary is_current].each do |f|
|
21
|
+
define_method(f.to_sym) do
|
22
|
+
@position.xpath("./#{f.gsub(/_/,'-')}").text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def start_month
|
27
|
+
@position.xpath('./start-date/month').text.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
def start_year
|
31
|
+
@position.xpath('./start-date/year').text.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def end_month
|
35
|
+
@position.xpath('./end-date/month').text.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
def end_year
|
39
|
+
@position.xpath('./end-date/year').text.to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
def company
|
43
|
+
@company ||= Company.new(@position.xpath('./company'))
|
44
|
+
end
|
45
|
+
|
46
|
+
end # resource
|
47
|
+
|
48
|
+
end # class
|
49
|
+
end # module
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Profile < LinkedIn::Base
|
3
|
+
|
4
|
+
# xml_reader :three_current_positions, :as => [Position]
|
5
|
+
|
6
|
+
PROFILE_FIELDS = %w[id first_name last_name headline industry
|
7
|
+
current_status current_status_timestamp summary
|
8
|
+
specialties proposal_comments associations honors
|
9
|
+
interests picture_url distance num_recommenders]
|
10
|
+
|
11
|
+
PROFILE_FIELDS.each do |f|
|
12
|
+
define_method(f.to_sym) do
|
13
|
+
@doc.xpath("./person/#{f.gsub(/_/,'-')}").text
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def location
|
18
|
+
@location ||= Location.new(@doc)
|
19
|
+
end
|
20
|
+
|
21
|
+
def api_standard_profile_request
|
22
|
+
@api_standard ||= ApiStandardProfileRequest.new(@doc.xpath('./person/api-standard-profile-request'))
|
23
|
+
end
|
24
|
+
|
25
|
+
def site_standard_profile_request
|
26
|
+
@doc.xpath('//site-standard-profile-request/url').text
|
27
|
+
end
|
28
|
+
|
29
|
+
def relation_to_viewer
|
30
|
+
@doc.xpath('//relation-to-viewer/distance').text
|
31
|
+
end
|
32
|
+
|
33
|
+
def member_url_resources
|
34
|
+
@url_resources ||= UrlResource.new(@doc.xpath('//member-url-resources')).resources
|
35
|
+
end
|
36
|
+
|
37
|
+
def positions
|
38
|
+
@positions ||= Position.new(@doc.xpath('//positions')).positions
|
39
|
+
end
|
40
|
+
|
41
|
+
def education
|
42
|
+
@education ||= Education.new(@doc.xpath('//educations')).education
|
43
|
+
end
|
44
|
+
|
45
|
+
def connections
|
46
|
+
@connections ||= Connections.new(@doc.xpath('//connections')).connections
|
47
|
+
end
|
48
|
+
|
49
|
+
def groups
|
50
|
+
@groups ||= Group.new(@doc.xpath('//member-groups')).groups
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Update < LinkedIn::Base
|
3
|
+
|
4
|
+
%w[update_key update_type is_commentable?].each do |f|
|
5
|
+
define_method(f.to_sym) do
|
6
|
+
@doc.xpath("./update/#{f.gsub(/_/,'-')}").text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def timestamp
|
11
|
+
@doc.xpath('./update/timestamp').text.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def profile
|
15
|
+
Profile.new(Nokogiri::XML(@doc.xpath('./update/update-content/person').to_xml))
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class UrlResource < LinkedIn::Base
|
3
|
+
|
4
|
+
def resources
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.children.each do |url|
|
8
|
+
@array << Resource.new(url) unless url.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Resource
|
15
|
+
|
16
|
+
def initialize(member_url)
|
17
|
+
@member_url = member_url
|
18
|
+
end
|
19
|
+
|
20
|
+
%w[url name].each do |f|
|
21
|
+
define_method(f.to_sym) do
|
22
|
+
@member_url.xpath("./#{f.gsub(/_/,'-')}").text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end # resource class
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/linkedin.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# require 'forwardable'
|
2
|
+
# require 'rubygems'
|
3
|
+
#
|
4
|
+
gem 'oauth', '~> 0.3.5'
|
5
|
+
require 'oauth'
|
6
|
+
|
7
|
+
require 'nokogiri'
|
8
|
+
|
9
|
+
gem 'crack', '~> 0.1.4'
|
10
|
+
require 'crack'
|
11
|
+
|
12
|
+
require 'cgi'
|
13
|
+
|
14
|
+
# class Nokogiri::XML::Element
|
15
|
+
# def has_key?(key)
|
16
|
+
# self.keys.include?(key)
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
module LinkedIn
|
21
|
+
class LinkedInError < StandardError
|
22
|
+
attr_reader :data
|
23
|
+
|
24
|
+
def initialize(data)
|
25
|
+
@data = data
|
26
|
+
super
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class RateLimitExceeded < LinkedInError; end
|
31
|
+
class Unauthorized < LinkedInError; end
|
32
|
+
class General < LinkedInError; end
|
33
|
+
|
34
|
+
class Unavailable < StandardError; end
|
35
|
+
class InformLinkedIn < StandardError; end
|
36
|
+
class NotFound < StandardError; end
|
37
|
+
|
38
|
+
# config/initializers/linkedin.rb (for instance)
|
39
|
+
#
|
40
|
+
# LinkedIn.configure do |config|
|
41
|
+
# config.token = 'consumer_token'
|
42
|
+
# config.secret = 'consumer_secret'
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# elsewhere
|
46
|
+
#
|
47
|
+
# client = LinkedIn::Client.new
|
48
|
+
def self.configure
|
49
|
+
yield self
|
50
|
+
|
51
|
+
LinkedIn.token = token
|
52
|
+
LinkedIn.secret = secret
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.token
|
57
|
+
@token
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.token=(token)
|
61
|
+
@token = token
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.secret
|
65
|
+
@secret
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.secret=(secret)
|
69
|
+
@secret = secret
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
directory = File.expand_path(File.dirname(__FILE__))
|
74
|
+
|
75
|
+
require File.join(directory, 'linked_in', 'base')
|
76
|
+
|
77
|
+
require File.join(directory, 'linked_in', 'api_standard_profile_request')
|
78
|
+
require File.join(directory, 'linked_in', 'url_resource')
|
79
|
+
require File.join(directory, 'linked_in', 'company')
|
80
|
+
require File.join(directory, 'linked_in', 'country')
|
81
|
+
require File.join(directory, 'linked_in', 'education')
|
82
|
+
require File.join(directory, 'linked_in', 'error')
|
83
|
+
require File.join(directory, 'linked_in', 'location')
|
84
|
+
require File.join(directory, 'linked_in', 'position')
|
85
|
+
require File.join(directory, 'linked_in', 'profile')
|
86
|
+
require File.join(directory, 'linked_in', 'update')
|
87
|
+
require File.join(directory, 'linked_in', 'network')
|
88
|
+
require File.join(directory, 'linked_in', 'people')
|
89
|
+
require File.join(directory, 'linked_in', 'connections')
|
90
|
+
require File.join(directory, 'linked_in', 'client')
|
91
|
+
require File.join(directory, 'linked_in', 'person')
|
92
|
+
require File.join(directory, 'linked_in', 'recipient')
|
93
|
+
require File.join(directory, 'linked_in', 'recipients')
|
94
|
+
require File.join(directory, 'linked_in', 'message')
|
95
|
+
require File.join(directory, 'linked_in', 'group')
|
96
|
+
require File.join(directory, 'linked_in', 'birthdate')
|
97
|
+
|