cl_linkedin 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +14 -0
- data/.document +5 -0
- data/.gitignore +25 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.markdown +80 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/changelog.markdown +76 -0
- data/examples/authenticate.rb +21 -0
- data/examples/network.rb +12 -0
- data/examples/profile.rb +12 -0
- data/examples/status.rb +9 -0
- data/lib/linked_in/api_standard_profile_request.rb +17 -0
- data/lib/linked_in/authorization_helpers.rb +48 -0
- data/lib/linked_in/base.rb +13 -0
- data/lib/linked_in/birthdate.rb +21 -0
- data/lib/linked_in/client.rb +154 -0
- data/lib/linked_in/company.rb +11 -0
- data/lib/linked_in/connections.rb +16 -0
- data/lib/linked_in/country.rb +9 -0
- data/lib/linked_in/current_share.rb +56 -0
- data/lib/linked_in/education.rb +41 -0
- data/lib/linked_in/error.rb +21 -0
- data/lib/linked_in/group.rb +32 -0
- data/lib/linked_in/im_account.rb +28 -0
- data/lib/linked_in/languages.rb +28 -0
- data/lib/linked_in/likes.rb +23 -0
- data/lib/linked_in/location.rb +13 -0
- data/lib/linked_in/message.rb +20 -0
- data/lib/linked_in/network.rb +12 -0
- data/lib/linked_in/patents.rb +42 -0
- data/lib/linked_in/people.rb +18 -0
- data/lib/linked_in/person.rb +7 -0
- data/lib/linked_in/phone_number.rb +29 -0
- data/lib/linked_in/position.rb +46 -0
- data/lib/linked_in/profile.rb +94 -0
- data/lib/linked_in/publications.rb +40 -0
- data/lib/linked_in/recipient.rb +7 -0
- data/lib/linked_in/recipients.rb +18 -0
- data/lib/linked_in/recommendations.rb +30 -0
- data/lib/linked_in/request_helpers.rb +78 -0
- data/lib/linked_in/short_profile.rb +13 -0
- data/lib/linked_in/skill.rb +33 -0
- data/lib/linked_in/to_xml_helpers.rb +53 -0
- data/lib/linked_in/twitter_account.rb +28 -0
- data/lib/linked_in/update.rb +23 -0
- data/lib/linked_in/url_resource.rb +26 -0
- data/lib/linkedin.rb +83 -0
- data/linkedin.gemspec +49 -0
- data/spec/cases/client_spec.rb +230 -0
- data/spec/cases/linkedin_spec.rb +37 -0
- data/spec/cases/oauth_spec.rb +109 -0
- data/spec/client_shared_examples.orig.rb +91 -0
- data/spec/client_shared_examples.rb +104 -0
- data/spec/fixtures/403.xml +7 -0
- data/spec/fixtures/404.xml +7 -0
- data/spec/fixtures/blank.xml +0 -0
- data/spec/fixtures/connections.xml +3733 -0
- data/spec/fixtures/likes.xml +18 -0
- data/spec/fixtures/mailbox_items.xml +16 -0
- data/spec/fixtures/network_status_with_group.xml +44 -0
- data/spec/fixtures/network_statuses.xml +317 -0
- data/spec/fixtures/picture_updates.xml +117 -0
- data/spec/fixtures/profile.xml +9 -0
- data/spec/fixtures/profile_full.orig.xml +3909 -0
- data/spec/fixtures/profile_full.xml +395 -0
- data/spec/fixtures/profile_with_positions.xml +79 -0
- data/spec/fixtures/search.xml +538 -0
- data/spec/fixtures/shares.xml +12 -0
- data/spec/fixtures/status.xml +2 -0
- data/spec/spec_helper.rb +58 -0
- metadata +242 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Connections < LinkedIn::Base
|
3
|
+
|
4
|
+
def connections
|
5
|
+
@connections ||= @doc.xpath('//connections').children.inject([]) do |list, profile|
|
6
|
+
list << Profile.new(Nokogiri::XML(profile.to_xml)) unless profile.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def profiles
|
12
|
+
connections
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
|
3
|
+
class CurrentShare < LinkedIn::Base
|
4
|
+
%w[id comment].each do |f|
|
5
|
+
define_method(f.to_sym) do
|
6
|
+
@doc.xpath("./#{f.gsub(/_/,'-')}").text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def submitted_url
|
11
|
+
@doc.xpath('./content/submitted-url').text
|
12
|
+
end
|
13
|
+
|
14
|
+
def resolved_url
|
15
|
+
@doc.xpath('./content/resolved-url').text
|
16
|
+
end
|
17
|
+
|
18
|
+
def shortened_url
|
19
|
+
@doc.xpath('./content/shortened-url').text
|
20
|
+
end
|
21
|
+
|
22
|
+
def title
|
23
|
+
@doc.xpath('./content/title').text
|
24
|
+
end
|
25
|
+
|
26
|
+
def description
|
27
|
+
@doc.xpath('./content/description').text
|
28
|
+
end
|
29
|
+
|
30
|
+
def submitted_image_url
|
31
|
+
@doc.xpath('./content/submitted-image-url').text
|
32
|
+
end
|
33
|
+
|
34
|
+
def thumbnail_url
|
35
|
+
@doc.xpath('./content/thumbnail-url').text
|
36
|
+
end
|
37
|
+
|
38
|
+
def timestamp
|
39
|
+
time = @doc.xpath('./timestamp').text.to_i
|
40
|
+
Time.at(time / 1000)
|
41
|
+
end
|
42
|
+
|
43
|
+
def visibility
|
44
|
+
@doc.xpath('./visibility/code').text
|
45
|
+
end
|
46
|
+
|
47
|
+
def application
|
48
|
+
@doc.xpath('./source/application/name').text
|
49
|
+
end
|
50
|
+
|
51
|
+
def author
|
52
|
+
@author ||= ShortProfile.new(@doc.xpath('./author'))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Education < LinkedIn::Base
|
3
|
+
|
4
|
+
def educations
|
5
|
+
@educations ||= @doc.children.inject([]) do |list, edu|
|
6
|
+
list << Resource.new(edu) unless edu.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
|
13
|
+
def initialize(education)
|
14
|
+
@education = education
|
15
|
+
end
|
16
|
+
|
17
|
+
%w[id school_name degree field_of_study activities notes].each do |f|
|
18
|
+
define_method(f.to_sym) do
|
19
|
+
@education.xpath("./#{f.gsub(/_/,'-')}").text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_month
|
24
|
+
@education.xpath('./start-date/month').text.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_year
|
28
|
+
@education.xpath('./start-date/year').text.to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def end_month
|
32
|
+
@education.xpath('./end-date/month').text.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_year
|
36
|
+
@education.xpath('./end-date/year').text.to_i
|
37
|
+
end
|
38
|
+
end # resource class
|
39
|
+
|
40
|
+
end # education class
|
41
|
+
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-code').text.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
@doc.xpath('//message').text
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Group < LinkedIn::Base
|
3
|
+
|
4
|
+
def groups
|
5
|
+
@groups ||= @doc.children.inject([]) do |list, group|
|
6
|
+
list << Resource.new(group) unless group.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
|
13
|
+
def initialize(group)
|
14
|
+
@group = group
|
15
|
+
end
|
16
|
+
|
17
|
+
def id
|
18
|
+
@group.xpath('//member-group/id').text.to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
@group.xpath('//member-group/name').text
|
23
|
+
end
|
24
|
+
|
25
|
+
def url
|
26
|
+
@group.xpath('//member-group/site-group-request/url').text
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class ImAccount < LinkedIn::Base
|
3
|
+
|
4
|
+
def im_accounts
|
5
|
+
@im_accounts ||= @doc.children.inject([]) do |list, im_account|
|
6
|
+
list << Resource.new(im_account) unless im_account.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
|
13
|
+
def initialize(im_account)
|
14
|
+
@im_account = im_account
|
15
|
+
end
|
16
|
+
|
17
|
+
def type
|
18
|
+
@im_account.xpath("./im-account-type").text
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
@im_account.xpath("./im-account-name").text
|
23
|
+
end
|
24
|
+
|
25
|
+
end # resource class
|
26
|
+
|
27
|
+
end # skill class
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Languages < LinkedIn::Base
|
3
|
+
|
4
|
+
def languages
|
5
|
+
@languages ||= @doc.children.inject([]) do |list, lang|
|
6
|
+
list << Resource.new(lang) unless lang.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
# proficiency level not implemented yet
|
13
|
+
# http://developer.linkedin.com/community/apis/blog/2011/01/04/new-profile-fields-are-here
|
14
|
+
def initialize(language)
|
15
|
+
@language = language
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
@language.xpath("./id").text
|
20
|
+
end
|
21
|
+
|
22
|
+
def name
|
23
|
+
@language.xpath("./language/name").text
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Likes < LinkedIn::Base
|
3
|
+
|
4
|
+
def likes
|
5
|
+
@likes ||= @doc.xpath('//likes').children.inject([]) do |list, like|
|
6
|
+
list << Resource.new(like) unless like.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
def initialize(like)
|
13
|
+
@like = like
|
14
|
+
end
|
15
|
+
|
16
|
+
def profile
|
17
|
+
Profile.new(Nokogiri::XML(@like.xpath('./person').to_xml))
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Message
|
3
|
+
|
4
|
+
attr_accessor :subject, :body, :recipients
|
5
|
+
|
6
|
+
def to_xml
|
7
|
+
self.to_xml_node(Nokogiri.XML('<root/>', nil, 'UTF-8')).to_xml
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_xml_node(doc)
|
11
|
+
node = Nokogiri::XML::DocumentFragment.new(doc, '<mailbox-item><recipients/><subject/><body/></mailbox-item>')
|
12
|
+
node.at_css('recipients').add_child(self.recipients.to_xml_nodes(doc))
|
13
|
+
node.at_css('subject').content = self.subject
|
14
|
+
node.at_css('body').content = self.body
|
15
|
+
node
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Patents < LinkedIn::Base
|
3
|
+
|
4
|
+
def patents
|
5
|
+
@patents ||= @doc.children.inject([]) do |list, patent|
|
6
|
+
list << Resource.new(patent) unless patent.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
|
13
|
+
def initialize(patent)
|
14
|
+
@patent = patent
|
15
|
+
end
|
16
|
+
|
17
|
+
%w[id title].each do |f|
|
18
|
+
define_method(f.to_sym) do
|
19
|
+
@patent.xpath("./#{f.gsub(/_/,'-')}").text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def year
|
24
|
+
@year ||= @patent.xpath("./date/year").text.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def day
|
28
|
+
@day ||= @patent.xpath("./date/day").text.to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def month
|
32
|
+
@month ||= @patent.xpath("./date/month").text.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def date
|
36
|
+
Date.civil(y=year,m=month,d=day)
|
37
|
+
end
|
38
|
+
|
39
|
+
end # resource class
|
40
|
+
|
41
|
+
end # patent class
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
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
|
+
@profiles ||= @doc.xpath('//people').children.inject([]) do |list, profile|
|
12
|
+
list << Profile.new(Nokogiri::XML(profile.to_xml)) unless profile.blank?
|
13
|
+
list
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class PhoneNumber < LinkedIn::Base
|
3
|
+
|
4
|
+
def phone_numbers
|
5
|
+
@array ||= begin
|
6
|
+
@array = []
|
7
|
+
@doc.children.each do |pn|
|
8
|
+
@array << Resource.new(pn) unless pn.blank?
|
9
|
+
end
|
10
|
+
@array
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Resource
|
15
|
+
|
16
|
+
def initialize(phone_number)
|
17
|
+
@phone_number = phone_number
|
18
|
+
end
|
19
|
+
|
20
|
+
%w[phone_type phone_number].each do |f|
|
21
|
+
define_method(f.to_sym) do
|
22
|
+
@phone_number.xpath("./#{f.gsub(/_/,'-')}").text
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end # resource class
|
27
|
+
|
28
|
+
end # phone_number class
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module LinkedIn
|
2
|
+
class Position < LinkedIn::Base
|
3
|
+
|
4
|
+
def positions
|
5
|
+
@positions ||= @doc.children.inject([]) do |list, position|
|
6
|
+
list << Resource.new(position) unless position.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class Resource
|
12
|
+
|
13
|
+
def initialize(position)
|
14
|
+
@position = position
|
15
|
+
end
|
16
|
+
|
17
|
+
%w[id title summary is_current].each do |f|
|
18
|
+
define_method(f.to_sym) do
|
19
|
+
@position.xpath("./#{f.gsub(/_/,'-')}").text
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def start_month
|
24
|
+
@position.xpath('./start-date/month').text.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_year
|
28
|
+
@position.xpath('./start-date/year').text.to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def end_month
|
32
|
+
@position.xpath('./end-date/month').text.to_i
|
33
|
+
end
|
34
|
+
|
35
|
+
def end_year
|
36
|
+
@position.xpath('./end-date/year').text.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
def company
|
40
|
+
@company ||= Company.new(@position.xpath('./company'))
|
41
|
+
end
|
42
|
+
|
43
|
+
end # resource
|
44
|
+
|
45
|
+
end # class
|
46
|
+
end # module
|