ruby-linkedin 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.
- data/README +4 -0
- data/lib/old.rb +110 -0
- data/lib/ruby-linkedin.rb +104 -0
- data/test/ts_ruby-linkedin.rb +37 -0
- metadata +56 -0
data/README
ADDED
data/lib/old.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xmlsimple'
|
3
|
+
require 'net/http'
|
4
|
+
require 'hpricot'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'date'
|
7
|
+
|
8
|
+
class Person
|
9
|
+
attr_accessor :given_name, :family_name, :summary, :locality, :title, :skills, :experiences, :educations
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
class Experience
|
14
|
+
attr_accessor :title, :org, :org_details, :start_date, :end_date, :description
|
15
|
+
end
|
16
|
+
|
17
|
+
class Education
|
18
|
+
attr_accessor :org, :degree, :major, :start_date, :end_date, :activities
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class Linkedin
|
23
|
+
|
24
|
+
def initialize(count=50,boss_id= 'mKlZ3iDIkY8WF9_YXz7vwpz7rBAs1Ogz.Q--')
|
25
|
+
@boss_id = boss_id
|
26
|
+
@count = count
|
27
|
+
end
|
28
|
+
|
29
|
+
def find(query={})
|
30
|
+
q = query.values.join(" ")
|
31
|
+
|
32
|
+
url = "http://boss.yahooapis.com/ysearch/web/v1/#{q}?appid=#{@boss_id}&sites=linkedin.com&format=xml&count=#{@count}"
|
33
|
+
(res = Net::HTTP.get_response(URI.parse(URI.escape(url)))) rescue puts 'Cannot reach to URL'
|
34
|
+
d = XmlSimple.xml_in(res.body, { 'ForceArray' => false })['resultset_web']['result']
|
35
|
+
if d.kind_of? Array
|
36
|
+
data = d
|
37
|
+
elsif d.kind_of? Hash
|
38
|
+
data = [] << d
|
39
|
+
end
|
40
|
+
|
41
|
+
data.delete_if { |rec| true unless (rec['url'].include? 'http://www.linkedin.com/pub' or
|
42
|
+
rec['url'].include? 'http://www.linkedin.com/in')}
|
43
|
+
|
44
|
+
@people = []
|
45
|
+
data.each { |rec|
|
46
|
+
person = Person.new
|
47
|
+
doc = Hpricot(open(rec['url']))
|
48
|
+
person.given_name = doc.search('span.given-name').inner_text
|
49
|
+
person.family_name = doc.search('span.family-name').inner_text
|
50
|
+
|
51
|
+
person.title = doc.search('p.headline').inner_text.strip
|
52
|
+
person.summary = doc.search('p.summary').inner_text.strip
|
53
|
+
person.locality = doc.search('p.locality').inner_text.strip
|
54
|
+
|
55
|
+
person.experiences = []
|
56
|
+
# experiences
|
57
|
+
exp = doc.search('div#experience').search('ul.vcalendar').first
|
58
|
+
exp.children_of_type('li').each { |el|
|
59
|
+
ex = Experience.new
|
60
|
+
ex.title = el.at('h3.title').inner_text.strip if !el.at('h3.title').nil?
|
61
|
+
ex.org = el.at('h4.org').inner_text.strip if !el.at('h4.org').nil?
|
62
|
+
ex.org_details = el.at('p.organization-details').inner_text.strip if !el.at('p.organization-details').nil?
|
63
|
+
ex.description = el.at('p.description').inner_text.strip if !el.at('p.description').nil?
|
64
|
+
ex.start_date = Date.parse(el.at('abbr.dtstart').get_attribute('title')).to_s if !el.at('abbr.dtstart').nil? rescue ex.start_date = nil
|
65
|
+
ex.end_date = Date.parse(el.at('abbr.dtend').get_attribute('title')).to_s if !el.at('abbr.dtend').nil? rescue ex.end_date = nil
|
66
|
+
person.experiences << ex
|
67
|
+
} unless exp.nil?
|
68
|
+
|
69
|
+
person.educations = []
|
70
|
+
# educations
|
71
|
+
edu = doc.search('div#education').search('ul.vcalendar').first
|
72
|
+
edu.children_of_type('li').each { |el|
|
73
|
+
ed = Education.new
|
74
|
+
ed.org = el.at('h3.summary').inner_text.strip if !el.at('h3.summary').nil?
|
75
|
+
ed.degree = el.at('span.degree').inner_text.strip if !el.at('span.degree').nil?
|
76
|
+
ed.activities = el.search('dl.activities-societies').search('dd').inner_text.strip if !el.search('dl.activities-societies').search('dd').nil?
|
77
|
+
ed.start_date = Date.parse(el.at('abbr.dtstart').get_attribute('title')).to_s if !el.at('abbr.dtstart').nil? rescue ed.start_date = nil
|
78
|
+
ed.end_date = Date.parse(el.at('abbr.dtend').get_attribute('title')).to_s if !el.at('abbr.dtend').nil? rescue ed.end_date = nil
|
79
|
+
person.educations << ed
|
80
|
+
} unless edu.nil?
|
81
|
+
|
82
|
+
@people << person
|
83
|
+
} unless data.nil?
|
84
|
+
|
85
|
+
filter_off_empty
|
86
|
+
unless query[:given_name].nil? and query[:family_name].nil?
|
87
|
+
filter_off_by_name(query)
|
88
|
+
end
|
89
|
+
@people
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def filter_off_empty
|
96
|
+
@people.delete_if { |person|
|
97
|
+
name = "#{person.given_name} #{person.family_name}"
|
98
|
+
true if name.strip.empty?
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
def filter_off_by_name(query)
|
103
|
+
@people.delete_if { |person|
|
104
|
+
name = "#{person.given_name} #{person.family_name}"
|
105
|
+
gn, fn = query[:given_name].nil? ? "" : query[:given_name], query[:family_name].nil? ? "" : query[:family_name]
|
106
|
+
true unless (name.downcase.include?(gn.downcase.to_s) and name.downcase.include?(fn.downcase.to_s))
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xmlsimple'
|
3
|
+
require 'net/http'
|
4
|
+
require 'hpricot'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'date'
|
7
|
+
require 'mofo'
|
8
|
+
|
9
|
+
|
10
|
+
class Linkedin
|
11
|
+
|
12
|
+
def initialize(count=50,boss_id= 'mKlZ3iDIkY8WF9_YXz7vwpz7rBAs1Ogz.Q--')
|
13
|
+
@boss_id = boss_id
|
14
|
+
@count = count
|
15
|
+
end
|
16
|
+
|
17
|
+
def find(query={})
|
18
|
+
q = query.values.join(" ")
|
19
|
+
|
20
|
+
url = "http://boss.yahooapis.com/ysearch/web/v1/#{q}?appid=#{@boss_id}&sites=linkedin.com&format=xml&count=#{@count}"
|
21
|
+
(res = Net::HTTP.get_response(URI.parse(URI.escape(url)))) rescue puts 'Cannot reach to URL'
|
22
|
+
d = XmlSimple.xml_in(res.body, { 'ForceArray' => false })['resultset_web']['result']
|
23
|
+
if d.kind_of? Array
|
24
|
+
data = d
|
25
|
+
elsif d.kind_of? Hash
|
26
|
+
data = [] << d
|
27
|
+
end
|
28
|
+
|
29
|
+
data.delete_if { |rec| true unless (rec['url'].include? 'http://www.linkedin.com/pub' or
|
30
|
+
rec['url'].include? 'http://www.linkedin.com/in')}
|
31
|
+
|
32
|
+
@people = []
|
33
|
+
data.each { |rec|
|
34
|
+
resume = hResume.find(rec['url'])
|
35
|
+
@people << resume if resume.kind_of? hResume
|
36
|
+
} unless data.nil?
|
37
|
+
|
38
|
+
# filter away the unnnecessary results
|
39
|
+
filter_off_empty
|
40
|
+
|
41
|
+
# filter by company person worked for
|
42
|
+
unless query[:org].nil?
|
43
|
+
filter_off_by_org(query)
|
44
|
+
end
|
45
|
+
|
46
|
+
# filter by name
|
47
|
+
unless query[:given_name].nil? and query[:family_name].nil?
|
48
|
+
filter_off_by_name(query)
|
49
|
+
end
|
50
|
+
|
51
|
+
# filter by current locality
|
52
|
+
unless query[:locality].nil?
|
53
|
+
filter_off_by_locality(query)
|
54
|
+
end
|
55
|
+
|
56
|
+
@people
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def filter_off_empty
|
63
|
+
@people.delete_if { |person|
|
64
|
+
true if person.contact.fn.strip.empty?
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def filter_off_by_org(query)
|
69
|
+
@people.delete_if {|person|
|
70
|
+
if person.experience.kind_of? Array
|
71
|
+
person.experience.each { |exp|
|
72
|
+
return false if exp.summary.downcase.include?(query[:org].downcase)
|
73
|
+
}
|
74
|
+
elsif person.experience.kind_of? HCalendar
|
75
|
+
puts person.experience.summary
|
76
|
+
return false if person.experience.summary.downcase.include?(query[:org].downcase)
|
77
|
+
else
|
78
|
+
return true
|
79
|
+
end
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
def filter_off_by_locality(query)
|
84
|
+
@people.delete_if {|person|
|
85
|
+
locality = person.contact.adr.locality.nil? ? "" : person.contact.adr.locality
|
86
|
+
true unless locality.downcase.include?(query[:locality].downcase)
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def filter_off_by_name(query)
|
91
|
+
@people.delete_if { |person|
|
92
|
+
case
|
93
|
+
when query[:family_name].nil?
|
94
|
+
true unless person.contact.n.given_name.downcase.include?(query[:given_name].downcase)
|
95
|
+
when query[:given_name].nil?
|
96
|
+
true unless person.contact.n.family_name.downcase.include?(query[:family_name].downcase)
|
97
|
+
else
|
98
|
+
true unless person.contact.fn.downcase.include?(query[:family_name].downcase) and
|
99
|
+
person.contact.fn.downcase.include?(query[:given_name].downcase)
|
100
|
+
end
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'lib/ruby-linkedin'
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
class RubyLinkedIn < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@linkedin = Linkedin.new
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
def test_find_barack
|
13
|
+
people = @linkedin.find({:given_name => 'Barack', :family_name => 'Obama'})
|
14
|
+
|
15
|
+
if people.kind_of? Array
|
16
|
+
people.each {|p|
|
17
|
+
puts p.contact.fn
|
18
|
+
puts p.contact.adr.locality
|
19
|
+
if p.experience.kind_of? Array
|
20
|
+
p.experience.each {|exp| puts " - " + exp.summary}
|
21
|
+
elsif p.experience.kind_of? hCalendar
|
22
|
+
puts " - " + p.experience.summary
|
23
|
+
end
|
24
|
+
puts
|
25
|
+
}
|
26
|
+
else
|
27
|
+
puts people.contact.fn
|
28
|
+
puts people.contact.adr.locality
|
29
|
+
if people.experience.kind_of? Array
|
30
|
+
people.experience.each {|exp| puts " - " + exp.summary}
|
31
|
+
end
|
32
|
+
puts
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-linkedin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chang Sau Sheong
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-09 00:00:00 +08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: sausheong@ymail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
files:
|
25
|
+
- lib/old.rb
|
26
|
+
- lib/ruby-linkedin.rb
|
27
|
+
- test/ts_ruby-linkedin.rb
|
28
|
+
- README
|
29
|
+
has_rdoc: true
|
30
|
+
homepage: http://blog.saush.com
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.0.1
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: A Yahoo! BOSS derived Ruby LinkedIn API
|
55
|
+
test_files:
|
56
|
+
- test/ts_ruby-linkedin.rb
|