linkedin 0.1.7 → 0.2.1
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/README.markdown +12 -7
- data/Rakefile +10 -33
- data/VERSION +1 -1
- data/changelog.markdown +38 -0
- data/examples/authenticate.rb +1 -1
- data/lib/linked_in/api_standard_profile_request.rb +14 -6
- 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 +86 -146
- data/lib/linked_in/company.rb +9 -7
- data/lib/linked_in/connections.rb +14 -5
- data/lib/linked_in/country.rb +7 -5
- data/lib/linked_in/current_share.rb +56 -0
- data/lib/linked_in/education.rb +40 -14
- data/lib/linked_in/error.rb +19 -8
- data/lib/linked_in/group.rb +30 -7
- data/lib/linked_in/languages.rb +28 -0
- data/lib/linked_in/likes.rb +23 -0
- data/lib/linked_in/location.rb +11 -6
- data/lib/linked_in/message.rb +20 -0
- data/lib/linked_in/network.rb +10 -5
- data/lib/linked_in/patents.rb +42 -0
- data/lib/linked_in/people.rb +16 -8
- data/lib/linked_in/person.rb +7 -0
- data/lib/linked_in/phone_number.rb +29 -0
- data/lib/linked_in/position.rb +45 -14
- data/lib/linked_in/profile.rb +81 -28
- 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 +76 -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/update.rb +21 -9
- data/lib/linked_in/url_resource.rb +24 -6
- data/lib/linkedin.rb +58 -59
- data/linkedin.gemspec +52 -0
- data/spec/cases/client_spec.rb +281 -0
- data/spec/cases/linkedin_spec.rb +37 -0
- data/spec/cases/oauth_spec.rb +109 -0
- data/{test → spec}/fixtures/blank.xml +0 -0
- data/{test → spec}/fixtures/connections.xml +0 -0
- data/{test → spec}/fixtures/error.xml +0 -0
- data/spec/fixtures/likes.xml +18 -0
- data/spec/fixtures/mailbox_items.xml +16 -0
- data/{test → spec}/fixtures/network_status_with_group.xml +3 -3
- data/{test → spec}/fixtures/network_statuses.xml +18 -0
- data/{test → spec}/fixtures/picture_updates.xml +0 -0
- data/{test → spec}/fixtures/profile.xml +0 -0
- data/{test → spec}/fixtures/profile_full.xml +57 -0
- data/{test → spec}/fixtures/profile_with_positions.xml +0 -0
- data/{test → spec}/fixtures/search.xml +2 -2
- data/spec/fixtures/shares.xml +12 -0
- data/{test → spec}/fixtures/status.xml +0 -0
- data/spec/spec_helper.rb +49 -0
- metadata +160 -76
- data/test/client_test.rb +0 -124
- data/test/oauth_test.rb +0 -117
- data/test/test_helper.rb +0 -51
data/lib/linked_in/company.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Company
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
class Company < LinkedIn::Base
|
3
|
+
|
4
|
+
%w[type name industry].each do |f|
|
5
|
+
define_method(f.to_sym) do
|
6
|
+
@doc.xpath("./#{f.gsub(/_/,'-')}").text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
8
10
|
end
|
9
|
-
end
|
11
|
+
end
|
@@ -1,7 +1,16 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Connections
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
+
|
6
15
|
end
|
7
|
-
end
|
16
|
+
end
|
data/lib/linked_in/country.rb
CHANGED
@@ -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
|
data/lib/linked_in/education.rb
CHANGED
@@ -1,15 +1,41 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Education
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
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
|
data/lib/linked_in/error.rb
CHANGED
@@ -1,10 +1,21 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Error
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
+
|
9
20
|
end
|
10
|
-
end
|
21
|
+
end
|
data/lib/linked_in/group.rb
CHANGED
@@ -1,9 +1,32 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Group
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
+
|
8
31
|
end
|
9
|
-
end
|
32
|
+
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
|
data/lib/linked_in/location.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Location
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
class Location < LinkedIn::Base
|
3
|
+
|
4
|
+
def name
|
5
|
+
@doc.xpath("/person/location/name").text
|
6
|
+
end
|
7
|
+
|
8
|
+
def country
|
9
|
+
@doc.xpath("/person/location/country/code").text
|
10
|
+
end
|
11
|
+
|
7
12
|
end
|
8
|
-
end
|
13
|
+
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
|
data/lib/linked_in/network.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class Network
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class Network < LinkedIn::Base
|
3
|
+
|
4
|
+
def updates
|
5
|
+
@updates ||= @doc.xpath('//updates').children.inject([]) do |list, update|
|
6
|
+
list << Update.new(Nokogiri::XML(update.to_xml)) unless update.blank?
|
7
|
+
list
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
6
11
|
end
|
7
|
-
end
|
12
|
+
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
|
data/lib/linked_in/people.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
1
|
module LinkedIn
|
2
|
-
class People
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
+
|
9
17
|
end
|
10
|
-
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
|