sovren 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/Rakefile +7 -0
- data/lib/sovren.rb +30 -0
- data/lib/sovren/achievement.rb +16 -0
- data/lib/sovren/association.rb +17 -0
- data/lib/sovren/certification.rb +18 -0
- data/lib/sovren/client.rb +45 -0
- data/lib/sovren/competency.rb +18 -0
- data/lib/sovren/contact_information.rb +33 -0
- data/lib/sovren/education.rb +30 -0
- data/lib/sovren/employment.rb +29 -0
- data/lib/sovren/language.rb +31 -0
- data/lib/sovren/military.rb +19 -0
- data/lib/sovren/patent.rb +19 -0
- data/lib/sovren/publication.rb +35 -0
- data/lib/sovren/reference.rb +18 -0
- data/lib/sovren/resume.rb +28 -0
- data/lib/sovren/version.rb +3 -0
- data/sovren.gemspec +30 -0
- data/spec/sovren/achievement_spec.rb +24 -0
- data/spec/sovren/association_spec.rb +25 -0
- data/spec/sovren/certification_spec.rb +26 -0
- data/spec/sovren/client_spec.rb +28 -0
- data/spec/sovren/competency_spec.rb +26 -0
- data/spec/sovren/contact_information_spec.rb +73 -0
- data/spec/sovren/education_spec.rb +48 -0
- data/spec/sovren/employment_spec.rb +45 -0
- data/spec/sovren/language_spec.rb +27 -0
- data/spec/sovren/military_spec.rb +29 -0
- data/spec/sovren/patent_spec.rb +27 -0
- data/spec/sovren/publication_spec.rb +70 -0
- data/spec/sovren/reference_spec.rb +34 -0
- data/spec/sovren/resume_spec.rb +42 -0
- data/spec/sovren_spec.rb +4 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/support/ResumeSample.doc +0 -0
- data/spec/support/_resume.xml +970 -0
- data/spec/support/achievements.xml +5 -0
- data/spec/support/associations.xml +8 -0
- data/spec/support/certifications.xml +23 -0
- data/spec/support/competencies.xml +353 -0
- data/spec/support/competencies_sparse.xml +3 -0
- data/spec/support/contact_information.xml +69 -0
- data/spec/support/contact_information_sparse.xml +10 -0
- data/spec/support/education.xml +81 -0
- data/spec/support/education_sparse.xml +10 -0
- data/spec/support/employment.xml +179 -0
- data/spec/support/employment_sparse.xml +11 -0
- data/spec/support/languages.xml +23 -0
- data/spec/support/military.xml +19 -0
- data/spec/support/patents.xml +14 -0
- data/spec/support/publications.xml +60 -0
- data/spec/support/references.xml +36 -0
- data/spec/support/resume.json +466 -0
- data/spec/support/resume.xml +1072 -0
- data/spec/support/speaking_events.xml +7 -0
- data/spec/vcr/parsed_resume.yml +3695 -0
- metadata +215 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZGI2YjYyNjA3NDlkOTcwOWExOTk4MTdmNjc1ZGI2MWQ4NWY2NDI3Yw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YjU3ZDU1MzFjYWEyMDQ4MWQ5NTQ3NzQ4MTk0NzFiNTRjNGY2OWIwYg==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NjBlMTc0ODVhMTMxZjZjODM2ZjkzZTRkNGZhMWQ4NmI5YjE5NTViYTZkZmNl
|
10
|
+
NzM0OGUzMzNkMDBjZjlkZDVlNTgwMGJjZTEyNDc3YzU5MjIzODMyZGMwOWE4
|
11
|
+
M2JkYmM3MzQ2N2EzNjQ0ZTJlZDBhZGNlYTE1MjNhZThiN2Q3Y2I=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NWMwODgwNDA5MmM2OTc5MDU3MzUxY2QwNzg2OGNmZTJlODYyMmFiYjNhODdk
|
14
|
+
Y2ZjM2ZlNGJjZDZkYTJhNzA4NjgwYWMwMTc2MzE4YjAwMjc5NGIwYjA0NjBi
|
15
|
+
OTYxNWJhMGRlYWU4NjA2NWI3ZmI2NDBmZGFiNTMzZTk0ZDE2NTU=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Eric Fleming
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Sovren
|
2
|
+
|
3
|
+
A simple ruby gem that parses a resume using the sovren resume parser and returns the resume back as a ruby object.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'sovren'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install sovren
|
18
|
+
|
19
|
+
## Usage Example
|
20
|
+
|
21
|
+
1. Create a client
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
client = Sovren::Client.new(endpoint: "http://yourhost.com/SovrenConvertAndParse/ConvertAndParse.asmx?WSDL", username: "http basic username (optional)", password: "http basic password (optional)")
|
25
|
+
```
|
26
|
+
|
27
|
+
2. Parse a resume
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
resume = client.parse(File.read('/path/to/your/file/resume.doc'))
|
31
|
+
```
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
The testing could use some more coverage for other hr-xml use cases. I also haven't added any of the sovren specific fields returned but those could be added if you need them.
|
36
|
+
|
37
|
+
1. Fork it
|
38
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
39
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
40
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
41
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/sovren.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require "pry"
|
2
|
+
require "sovren/version"
|
3
|
+
require "savon"
|
4
|
+
|
5
|
+
module Sovren
|
6
|
+
class << self
|
7
|
+
FIELDS = [:endpoint, :username, :password, :timeout, :hard_time_out_multiplier, :parser_configuration_params]
|
8
|
+
attr_accessor(*FIELDS)
|
9
|
+
|
10
|
+
def configure
|
11
|
+
yield self
|
12
|
+
true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
require_relative "sovren/achievement"
|
17
|
+
require_relative "sovren/association"
|
18
|
+
require_relative "sovren/certification"
|
19
|
+
require_relative "sovren/client"
|
20
|
+
require_relative "sovren/competency"
|
21
|
+
require_relative "sovren/contact_information"
|
22
|
+
require_relative "sovren/education"
|
23
|
+
require_relative "sovren/employment"
|
24
|
+
require_relative "sovren/resume"
|
25
|
+
require_relative "sovren/language"
|
26
|
+
require_relative "sovren/military"
|
27
|
+
require_relative "sovren/patent"
|
28
|
+
require_relative "sovren/publication"
|
29
|
+
require_relative "sovren/reference"
|
30
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Achievement
|
3
|
+
attr_accessor :description
|
4
|
+
|
5
|
+
def self.parse(achievements)
|
6
|
+
return Array.new if achievements.nil?
|
7
|
+
result = achievements.css('Achievement').collect do |item|
|
8
|
+
c = Achievement.new
|
9
|
+
c.description = item.css('Description').text
|
10
|
+
c
|
11
|
+
end
|
12
|
+
result
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Association
|
3
|
+
attr_accessor :name, :role
|
4
|
+
|
5
|
+
def self.parse(associations)
|
6
|
+
return Array.new if associations.nil?
|
7
|
+
result = associations.css('Association').collect do |item|
|
8
|
+
c = Association.new
|
9
|
+
c.name = item.css('Name').first.text
|
10
|
+
c.role = item.css('Role Name').text
|
11
|
+
c
|
12
|
+
end
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Certification
|
3
|
+
attr_accessor :name, :description, :effective_date
|
4
|
+
|
5
|
+
def self.parse(certifications)
|
6
|
+
return Array.new if certifications.nil?
|
7
|
+
result = certifications.css('LicenseOrCertification').collect do |item|
|
8
|
+
c = Certification.new
|
9
|
+
c.name = item.css('Name').text
|
10
|
+
c.description = item.css('Description').text
|
11
|
+
c.effective_date = Date.parse(item.css('EffectiveDate FirstIssuedDate AnyDate').text) rescue nil
|
12
|
+
c
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Client
|
3
|
+
attr_reader :endpoint, :username, :password, :timeout, :hard_time_out_multiplier, :parser_configuration_params
|
4
|
+
|
5
|
+
#Initialize the client class that will be used for all sovren requests.
|
6
|
+
#
|
7
|
+
#Certain requests will require an oauth token. See http://developer.foursquare.com/docs/index_docs.html for the full list.
|
8
|
+
#
|
9
|
+
# @param [Hash] options
|
10
|
+
# @option options String :endpoint The url that the web service is located at
|
11
|
+
# @option options String :username The HTTP Basic auth username for the webservice
|
12
|
+
# @option options String :password The HTTP Basic auth password for the webservice
|
13
|
+
# @option options Integer :timeout The timeout for the parser
|
14
|
+
# @option options Integer :hard_time_out_multiplier The hard timeout for the parser
|
15
|
+
# @option options Integer :parser_configuration_params The parser configuration params, used to tweak the output of the parser
|
16
|
+
|
17
|
+
def initialize(options={})
|
18
|
+
@endpoint = options[:endpoint]
|
19
|
+
@username = options[:username]
|
20
|
+
@password = options[:password]
|
21
|
+
@timeout = options[:timout] || 30000
|
22
|
+
@hard_time_out_multiplier = options[:hard_time_out_multiplier] || 2
|
23
|
+
@parser_configuration_params = options[:parser_configuration_params] || "_100000_0_00000010_0000000110101100_1_0000000000000111111102000000000010000100000000000000"
|
24
|
+
end
|
25
|
+
|
26
|
+
def connection
|
27
|
+
Savon.client(wsdl: endpoint, log: false)
|
28
|
+
end
|
29
|
+
|
30
|
+
def parse(file)
|
31
|
+
result = connection.call(:parse) do |c|
|
32
|
+
c.message({
|
33
|
+
"DocumentAsByteArray" => Base64.encode64(file),
|
34
|
+
"ParserConfigurationParams" => parser_configuration_params,
|
35
|
+
"AlsoUseSovrenTaxonomy" => true,
|
36
|
+
"EmbedConvertedTextInHrXml" => true,
|
37
|
+
"HardTimeOutMultiplier" => hard_time_out_multiplier,
|
38
|
+
"TimeOutInMs" => timeout})
|
39
|
+
end
|
40
|
+
|
41
|
+
Resume.parse(result.body[:parse_response][:parse_result])
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Competency
|
3
|
+
attr_accessor :name, :months, :last_used_date
|
4
|
+
|
5
|
+
def self.parse(competencies)
|
6
|
+
return Array.new if competencies.nil?
|
7
|
+
results = competencies.css('Competency').collect do |item|
|
8
|
+
c = Competency.new
|
9
|
+
c.name = item['name']
|
10
|
+
c.months = item.css('CompetencyEvidence NumericValue').text.to_i rescue nil
|
11
|
+
c.last_used_date = Date.parse(item.css('CompetencyEvidence').first['lastUsed']) rescue nil
|
12
|
+
c
|
13
|
+
end
|
14
|
+
results
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sovren
|
2
|
+
class ContactInformation
|
3
|
+
attr_accessor :first_name, :middle_name, :last_name, :aristocratic_title, :form_of_address, :generation, :qualification, :address_line_1, :address_line_2, :city, :state, :country, :postal_code, :home_phone, :mobile_phone, :email, :website
|
4
|
+
|
5
|
+
def self.parse(contact_information)
|
6
|
+
return nil if contact_information.nil?
|
7
|
+
result = self.new
|
8
|
+
result.first_name = contact_information.css('PersonName GivenName').collect(&:text).join(" ")
|
9
|
+
result.middle_name = contact_information.css('PersonName MiddleName').collect(&:text).join(" ")
|
10
|
+
result.last_name = contact_information.css('PersonName FamilyName').collect(&:text).join(" ")
|
11
|
+
result.aristocratic_title = contact_information.css('PersonName Affix[type=aristocraticTitle]').collect(&:text).join(" ")
|
12
|
+
result.form_of_address = contact_information.css('PersonName Affix[type=formOfAddress]').collect(&:text).join(" ")
|
13
|
+
result.generation = contact_information.css('PersonName Affix[type=generation]').collect(&:text).join(" ")
|
14
|
+
result.qualification = contact_information.css('PersonName Affix[type=qualification]').collect(&:text).join(" ")
|
15
|
+
|
16
|
+
address = contact_information.css('PostalAddress DeliveryAddress AddressLine').collect(&:text)
|
17
|
+
result.address_line_1 = address[0] if address.length > 0
|
18
|
+
result.address_line_2 = address[1] if address.length > 1
|
19
|
+
result.city = contact_information.css('PostalAddress').first.css('Municipality').text rescue nil
|
20
|
+
result.state = contact_information.css('PostalAddress').first.css('Region').text rescue nil
|
21
|
+
result.postal_code = contact_information.css('PostalAddress').first.css('PostalCode').text rescue nil
|
22
|
+
result.country = contact_information.css('PostalAddress').first.css('CountryCode').text rescue nil
|
23
|
+
|
24
|
+
result.home_phone = contact_information.css('Telephone FormattedNumber').first.text rescue nil
|
25
|
+
result.mobile_phone = contact_information.css('Mobile FormattedNumber').first.text rescue nil
|
26
|
+
|
27
|
+
result.website = contact_information.css('InternetWebAddress').first.text rescue nil
|
28
|
+
result.email = contact_information.css('InternetEmailAddress').first.text rescue nil
|
29
|
+
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Education
|
3
|
+
attr_accessor :school_name, :city, :state, :country, :degree_name, :degree_type, :major, :minor, :gpa, :gpa_out_of, :start_date, :end_date, :graduated
|
4
|
+
|
5
|
+
def self.parse(education_history)
|
6
|
+
return Array.new if education_history.nil?
|
7
|
+
result = education_history.css('SchoolOrInstitution').collect do |item|
|
8
|
+
e = Education.new
|
9
|
+
e.school_name = item.css('SchoolName').text
|
10
|
+
e.city, e.state, e.country = item.css('PostalAddress Municipality, PostalAddress Region, PostalAddress CountryCode').collect(&:text)
|
11
|
+
e.degree_type = item.css('Degree').first['degreeType']
|
12
|
+
e.degree_name = item.css('Degree DegreeName').text
|
13
|
+
e.major = item.css('DegreeMajor Name').text
|
14
|
+
e.minor = item.css('DegreeMinor name').text
|
15
|
+
e.gpa = item.css('EducationalMeasure MeasureValue StringValue').text.to_f rescue nil
|
16
|
+
e.gpa_out_of = item.css('EducationalMeasure HighestPossibleValue StringValue').text.to_f rescue nil
|
17
|
+
e.start_date = Date.parse(item.css('DatesOfAttendance StartDate AnyDate').text) rescue nil
|
18
|
+
e.end_date = Date.parse(item.css('DatesOfAttendance EndDate AnyDate').text) rescue nil
|
19
|
+
e.graduated = item.css('Degree DegreeDate AnyDate').text != ""
|
20
|
+
e
|
21
|
+
end
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def graduated?
|
26
|
+
!graduated.nil? && graduated
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Employment
|
3
|
+
attr_accessor :employer, :division, :city, :state, :country, :title, :description, :start_date, :end_date, :current_employer
|
4
|
+
|
5
|
+
def self.parse(employment_history)
|
6
|
+
return Array.new if employment_history.nil?
|
7
|
+
result = employment_history.css('EmployerOrg').collect do |item|
|
8
|
+
position = item.css('PositionHistory').first
|
9
|
+
e = Employment.new
|
10
|
+
e.employer = item.css('EmployerOrgName').text
|
11
|
+
e.division = position.css('OrganizationName').text
|
12
|
+
e.division = nil if e.employer == e.division
|
13
|
+
e.city, e.state, e.country = item.css('PositionLocation Municipality, PositionLocation Region, PositionLocation CountryCode').collect(&:text)
|
14
|
+
e.title = position.css('Title').text
|
15
|
+
e.description = position.css('Description').text
|
16
|
+
e.start_date = Date.parse(position.css('StartDate').text) rescue nil
|
17
|
+
e.current_employer = position['currentEmployer'] == "true"
|
18
|
+
e.end_date = e.current_employer ? nil : (Date.parse(position.css('EndDate').text) rescue nil)
|
19
|
+
e
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_employer?
|
25
|
+
!current_employer.nil? && current_employer
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Language
|
3
|
+
attr_accessor :language_code, :read, :write, :speak
|
4
|
+
|
5
|
+
def self.parse(languages)
|
6
|
+
return Array.new if languages.nil?
|
7
|
+
result = languages.css('Language').collect do |item|
|
8
|
+
c = Language.new
|
9
|
+
c.language_code = item.css('LanguageCode').text
|
10
|
+
c.read = item.css('Read').text == "true" rescue nil
|
11
|
+
c.write = item.css('Write').text == "true" rescue nil
|
12
|
+
c.speak = item.css('Speak').text == "true" rescue nil
|
13
|
+
c
|
14
|
+
end
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
def read?
|
19
|
+
!read.nil? && read
|
20
|
+
end
|
21
|
+
|
22
|
+
def write?
|
23
|
+
!write.nil? && write
|
24
|
+
end
|
25
|
+
|
26
|
+
def speak?
|
27
|
+
!speak.nil? && speak
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Military
|
3
|
+
attr_accessor :country_served, :branch, :rank_achieved, :recognition_achieved, :discharge_status, :start_date, :end_date
|
4
|
+
|
5
|
+
def self.parse(military_history)
|
6
|
+
return nil if military_history.nil?
|
7
|
+
e = Military.new
|
8
|
+
e.country_served = military_history.css('CountryServed').text
|
9
|
+
e.branch = military_history.css('ServiceDetail').first['branch']
|
10
|
+
e.rank_achieved = military_history.css('ServiceDetail RankAchieved CurrentOrEndRank').text
|
11
|
+
e.recognition_achieved = military_history.css('ServiceDetail RecognitionAchieved').text
|
12
|
+
e.discharge_status = military_history.css('ServiceDetail DischargeStatus').text
|
13
|
+
e.start_date = Date.parse(military_history.css('DatesOfService StartDate AnyDate').text) rescue nil
|
14
|
+
e.end_date = Date.parse(military_history.css('DatesOfService EndDate AnyDate').text) rescue nil
|
15
|
+
e
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sovren
|
2
|
+
class Patent
|
3
|
+
attr_accessor :title, :description, :inventor_name, :patent_id
|
4
|
+
|
5
|
+
def self.parse(patents)
|
6
|
+
return Array.new if patents.nil?
|
7
|
+
result = patents.css('Patent').collect do |item|
|
8
|
+
c = Patent.new
|
9
|
+
c.title = item.css('PatentTitle').text
|
10
|
+
c.description = item.css('Description').text
|
11
|
+
c.inventor_name = item.css('Inventors InventorName').first.text rescue nil
|
12
|
+
c.patent_id = item.css('PatentDetail PatentMilestone Id').text
|
13
|
+
c
|
14
|
+
end
|
15
|
+
result
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|