resume_exporter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ require "nokogiri"
2
+ require "uri"
3
+
4
+ module Extractor
5
+ class Stackoverflow
6
+ def initialize(doc)
7
+ @doc = doc
8
+ end
9
+
10
+ def basics
11
+ {
12
+ name: name,
13
+ label: label,
14
+ image: image,
15
+ contact: {
16
+ website: website,
17
+ location: location
18
+ }
19
+ }
20
+ end
21
+
22
+ def name
23
+ @doc.at_css('#section-personal h1').text if @doc.at_css('#section-personal h1')
24
+ end
25
+
26
+ def label
27
+ @doc.at_css('#currently-at-container .job').text.gsub(/\s+/, ' ').strip if @doc.at_css('#currently-at-container .job')
28
+ end
29
+
30
+ def image
31
+ @doc.at_css('.avatar img')['src'] if @doc.at_css('.avatar img')
32
+ end
33
+
34
+ def location
35
+ @doc.at_css('.meta').children.reject{|e| e.name == "a" }.map(&:text).join().gsub(/\s+/, ' ').strip if @doc.at_css('.meta')
36
+ end
37
+
38
+ def website
39
+ @doc.at_css('.meta a').text.strip if @doc.at_css('.meta a')
40
+ end
41
+
42
+ def employment
43
+ {
44
+ history: @doc.css('#cv-Experience .cv-section').map do |item|
45
+ experience = {}
46
+ experience[:position] = item.at_css(".preview h3").children.reject{|e| e.name == "span" }.map(&:text).join().gsub(/\s+/, ' ').strip if item.at_css(".preview h3")
47
+ experience[:employer] = item.at_css(".preview h3 .location").text.gsub(/\s+/, ' ').strip if item.at_css(".preview h3 .location")
48
+ dates = item.at_css('.time-frame').text.gsub(/\s+/, ' ').strip.split(" → ") if item.at_css('.time-frame')
49
+ experience[:startDate] = dates[0] if dates && dates[0]
50
+ experience[:endDate] = dates[1] if dates && dates[1]
51
+ experience[:keywords] = item.css(".timeline-item-tags .post-tag").map(&:text) if item.at_css(".timeline-item-tags .post-tag")
52
+ experience[:summary] = item.at_css(".description").text.gsub(/\s+/, ' ').strip if item.at_css(".description")
53
+ experience
54
+ end
55
+ }
56
+ end
57
+
58
+ def education
59
+ {
60
+ history: @doc.css('#cv-Education .cv-section').map do |item|
61
+ education = {}
62
+ education[:institution] = item.at_css(".preview h3 .location").text.gsub(/\s+/, ' ').strip if item.at_css(".preview h3 .location")
63
+ education[:degree] = item.at_css(".preview h3").children.reject{|e| e.name == "span" }.map(&:text).join().gsub(/\s+/, ' ').strip.gsub(/[,]?$/, '') if item.at_css(".preview h3")
64
+ education[:summary] = item.at_css(".description").text.gsub(/\s+/, ' ').strip if item.at_css(".description")
65
+ dates = item.at_css('.time-frame').text.gsub(/\s+/, ' ').strip.split(" → ") if item.at_css('.time-frame')
66
+ education[:startDate] = dates[0] if dates && dates[0]
67
+ education[:endDate] = dates[1] if dates && dates[1]
68
+ education[:keywords] = item.css(".timeline-item-tags .post-tag").map(&:text) if item.at_css(".timeline-item-tags .post-tag")
69
+ education
70
+ end
71
+ }
72
+ end
73
+
74
+ def projects
75
+ {
76
+ history: @doc.css('#cv-Apps\ \&\ Software .cv-section').map do |item|
77
+ project = {}
78
+ project[:title] = item.at_css(".preview h3").text.gsub(/\s+/, ' ').strip if item.at_css(".preview h3")
79
+ project[:url] = item.at_css(".preview h3 a")["href"] if item.at_css(".preview h3 a")
80
+ dates = item.at_css('.time-frame').text.gsub(/\s+/, ' ').strip.split(" → ") if item.at_css('.time-frame')
81
+ project[:startDate] = dates[0] if dates && dates[0]
82
+ project[:endDate] = dates[1] if dates && dates[1]
83
+ project[:description] = item.at_css(".description").text.gsub(/\s+/, ' ').strip if item.at_css(".description")
84
+ project[:keywords] = item.css(".timeline-item-tags .post-tag").map(&:text) if item.at_css(".timeline-item-tags .post-tag")
85
+ project
86
+ end
87
+ }
88
+ end
89
+
90
+ def qualifications
91
+ {
92
+ history: [
93
+ @doc.css('#cv-Certifications .cv-section').map do |item|
94
+ certification = {}
95
+ certification[:category] = "Certificate"
96
+ certification[:title] = item.at_css(".preview h3").text.gsub(/\s+/, ' ').strip if item.at_css(".preview h3")
97
+ dates = item.at_css('.time-frame').text.gsub(/\s+/, ' ').strip.split(" → ") if item.at_css('.time-frame')
98
+ certification[:startDate] = dates[0] if dates && dates[0]
99
+ certification[:endDate] = dates[1] if dates && dates[1]
100
+ certification[:keywords] = item.css(".timeline-item-tags .post-tag").map(&:text) if item.at_css(".timeline-item-tags .post-tag")
101
+ certification
102
+ end
103
+ ].flatten
104
+ }
105
+ end
106
+
107
+ def openSource
108
+ {
109
+ history: @doc.css('#cv-Open\ Source .cv-section').map do |item|
110
+ project = {}
111
+ project[:title] = item.at_css(".preview h3").text.gsub(/\s+/, ' ').strip if item.at_css(".preview h3")
112
+ project[:repo] = item.at_css(".preview h3 a")["href"] if item.at_css(".preview h3 a")
113
+ dates = item.at_css('.time-frame').text.gsub(/\s+/, ' ').strip.split(" → ") if item.at_css('.time-frame')
114
+ project[:startDate] = dates[0] if dates && dates[0]
115
+ project[:endDate] = dates[1] if dates && dates[1]
116
+ project[:description] = item.at_css(".description").text.gsub(/\s+/, ' ').strip if item.at_css(".description")
117
+ project[:keywords] = item.css(".timeline-item-tags .post-tag").map(&:text) if item.at_css(".timeline-item-tags .post-tag")
118
+ project
119
+ end
120
+ }
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,105 @@
1
+ require "nokogiri"
2
+ require "uri"
3
+
4
+ module Extractor
5
+ class Xing
6
+ def initialize(doc)
7
+ @doc = doc
8
+ end
9
+
10
+ def basics
11
+ {
12
+ name: name,
13
+ image: image
14
+ }
15
+ end
16
+
17
+ def name
18
+ @doc.at_css('.user-name').text.strip if @doc.at_css('.user-name')
19
+ end
20
+
21
+ def image
22
+ @doc.at_css('img.user-image')['src'] if @doc.at_css('img.user-image')
23
+ end
24
+
25
+ def employment
26
+ {
27
+ history: @doc.css('#work-experience li').map do |item|
28
+ experience = {}
29
+ experience[:position] = item.at_css(".job-title").text if item.at_css(".job-title")
30
+ experience[:employer] = item.at_css(".job-company-name").text.gsub(/\s+/, ' ').strip if item.at_css(".job-company-name")
31
+ experience[:url] = item.at_css(".company-url a")["href"] if item.at_css(".company-url a")
32
+ dates = item.css(".additional.top").text.gsub(/\s+/, ' ').strip.split(" - ")
33
+ experience[:startDate] = dates[0] if dates[0]
34
+ experience[:endDate] = dates[1] if dates[1]
35
+ experience[:endDate] ||= "Present"
36
+ experience
37
+ end
38
+ }
39
+ end
40
+
41
+ def education
42
+ {
43
+ history: @doc.css('#education .item-list li').map do |item|
44
+ education = {}
45
+ education[:institution] = item.at_css(".education-title").text if item.at_css(".education-title")
46
+ education[:fieldOfStudy] = item.at_css(".education-description").text.gsub(/\s+/, ' ').strip if item.at_css(".education-description")
47
+ education[:summary] = item.at_css(".meta").text.gsub(/\s+/, ' ').strip if item.at_css(".meta")
48
+
49
+ dates = item.css(".additional.top").text.gsub(/\s+/, ' ').strip.split(" - ")
50
+ education[:startDate] = dates[0] if dates[0]
51
+ education[:endDate] = dates[1] if dates[1]
52
+ education[:endDate] ||= "Present"
53
+ education
54
+ end
55
+ }
56
+ end
57
+
58
+ def languages
59
+ {
60
+ list: @doc.css('#language-skills .language').map do |item|
61
+ language = {}
62
+ language[:language] = item.at_css("h3 text()").text.gsub(/\s+/, ' ').strip if item.at_css("h3")
63
+ language[:level] = item.at_css(".language-level-name").text.gsub(/[()]/, "") if item.at_css(".language-level-name")
64
+ language
65
+ end
66
+ }
67
+ end
68
+
69
+ def qualifications
70
+ {
71
+ history: @doc.css('#qualifications li .title').map do |item|
72
+ { title: item.text.gsub(/\s+/, ' ').strip }
73
+ end
74
+ }
75
+ end
76
+
77
+ def recognition
78
+ {
79
+ history: @doc.css('#awards li').map do |item|
80
+ award = {}
81
+ award[:title] = item.at_css(".title text()").text.gsub(/\s+/, ' ').strip if item.at_css(".title")
82
+ award[:startDate] = item.at_css(".additional.top").text if item.at_css(".additional.top")
83
+ award[:url] = item.at_css(".additional a")["href"] if item.at_css(".additional a")
84
+ award
85
+ end
86
+ }
87
+ end
88
+
89
+ def affiliations
90
+ {
91
+ history: @doc.css('#organizations li .title').map do |item|
92
+ { organization: item.text.gsub(/\s+/, ' ').strip }
93
+ end
94
+ }
95
+ end
96
+
97
+ def interests
98
+ {
99
+ list: @doc.css('#interests li').map do |item|
100
+ { name: item.text.gsub(/\s+/, ' ').strip }
101
+ end
102
+ }
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,38 @@
1
+ require "json"
2
+ require "extractors/base"
3
+ require "extractors/json/json_resume"
4
+ require "extractors/json/fresh"
5
+ require "extractors/json/prtflio"
6
+
7
+ module Extractor
8
+ class Json < Base
9
+ def initialize(file_path)
10
+ @doc = File.open(file_path) { |f| JSON.parse(f.read, symbolize_names: true) }
11
+ end
12
+
13
+ def extract
14
+ if is_prtflio?
15
+ extractor = Extractor::Prtflio.new(@doc)
16
+ elsif is_fresh?
17
+ extractor = Extractor::Fresh.new(@doc)
18
+ else
19
+ extractor = Extractor::JsonResume.new(@doc)
20
+ end
21
+
22
+ attributes.reduce({}) do |hash, attr|
23
+ hash[attr.to_sym] = extractor.send(attr.to_sym) if extractor.respond_to?(attr.to_sym)
24
+ hash
25
+ end
26
+ end
27
+
28
+ def is_prtflio?
29
+ @doc.dig(:meta, :format) &&
30
+ @doc.dig(:meta, :format).downcase.include?("prtflio")
31
+ end
32
+
33
+ def is_fresh?
34
+ @doc.dig(:meta, :format) &&
35
+ @doc.dig(:meta, :format).downcase.include?("fresh")
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,314 @@
1
+ module Extractor
2
+ class Fresh
3
+ def initialize(doc)
4
+ @doc = doc
5
+ end
6
+
7
+ def meta
8
+ {
9
+ format: @doc.dig(:meta, :format),
10
+ version: @doc.dig(:meta, :version)
11
+ }
12
+ end
13
+
14
+ def basics
15
+ {
16
+ name: @doc.dig(:name),
17
+ label: @doc.dig(:info, :label),
18
+ image: @doc.dig(:info, :image),
19
+ summary: @doc.dig(:info, :brief),
20
+ characterClass: @doc.dig(:info, :characterClass),
21
+ quote: @doc.dig(:info, :quote),
22
+ contact: {
23
+ email: @doc.dig(:contact, :email),
24
+ phone: @doc.dig(:contact, :phone),
25
+ website: @doc.dig(:contact, :website),
26
+ location: @doc.dig(:location, :address),
27
+ other: @doc.dig(:contact, :other),
28
+ social: @doc.dig(:social).map do |social|
29
+ {
30
+ network: social[:network],
31
+ user: social[:user],
32
+ label: social[:label],
33
+ url: social[:url]
34
+ }
35
+ end
36
+ }
37
+ }
38
+ end
39
+
40
+ def employment
41
+ {
42
+ summary: @doc.dig(:employment, :summary),
43
+ history: @doc.dig(:employment, :history).map do |job|
44
+ {
45
+ employer: job[:employer],
46
+ position: job[:position],
47
+ url: job[:url],
48
+ startDate: job[:start],
49
+ endDate: job[:end],
50
+ summary: job[:summary],
51
+ location: job[:location],
52
+ highlights: job[:highlights],
53
+ keywords: job[:keywords]
54
+ }
55
+ end
56
+ }
57
+ end
58
+
59
+ def education
60
+ {
61
+ summary: @doc.dig(:education, :summary),
62
+ level: @doc.dig(:education, :level),
63
+ degree: @doc.dig(:education, :degree),
64
+ history: @doc.dig(:education, :history).map do |education|
65
+ {
66
+ title: education[:title],
67
+ institution: education[:institution],
68
+ fieldOfStudy: education[:area],
69
+ degree: education[:studyType],
70
+ startDate: education[:start],
71
+ endDate: education[:end],
72
+ grade: education[:grade],
73
+ url: education[:url],
74
+ summary: education[:summary],
75
+ location: education[:location],
76
+ curriculum: education[:curriculum],
77
+ highlights: education[:highlights],
78
+ keywords: education[:keywords]
79
+ }
80
+ end
81
+ }
82
+ end
83
+
84
+ def projects
85
+ {
86
+ history: @doc.dig(:projects).map do |project|
87
+ {
88
+ title: project[:title],
89
+ description: project[:description],
90
+ url: project[:url],
91
+ repo: project[:repo],
92
+ startDate: project[:start],
93
+ endDate: project[:end],
94
+ roles: [project[:role]],
95
+ category: project[:category],
96
+ summary: project[:summary],
97
+ media: project[:media],
98
+ highlights: project[:highlights],
99
+ keywords: project[:keywords]
100
+ }
101
+ end
102
+ }
103
+ end
104
+
105
+ def skills
106
+ {
107
+ list: @doc.dig(:skills, :list),
108
+ sets: @doc.dig(:skills, :sets).map do |skill|
109
+ {
110
+ name: skill[:name],
111
+ level: skill[:level],
112
+ keywords: skill[:skills]
113
+ }
114
+ end
115
+ }
116
+ end
117
+
118
+ def recognition
119
+ {
120
+ history: @doc.dig(:recognition).map do |recognition|
121
+ {
122
+ category: recognition[:category],
123
+ title: recognition[:title],
124
+ startDate: recognition[:date],
125
+ from: recognition[:from],
126
+ summary: recognition[:summary],
127
+ url: recognition[:url]
128
+ }
129
+ end
130
+ }
131
+ end
132
+
133
+ def writing
134
+ {
135
+ history: @doc.dig(:writing).map do |writing|
136
+ {
137
+ title: writing[:title],
138
+ category: writing[:category],
139
+ publisher: ( writing[:publisher].is_a?(Hash) ? writing.dig(:publisher, :name) : writing[:publisher] ),
140
+ date: writing[:date],
141
+ url: writing[:url],
142
+ summary: writing[:summary]
143
+ }
144
+ end
145
+ }
146
+ end
147
+
148
+ def reading
149
+ {
150
+ history: @doc.dig(:reading).map do |reading|
151
+ {
152
+ title: reading[:title],
153
+ category: reading[:category],
154
+ url: reading[:url],
155
+ author: ( reading[:author].is_a?(Array) ? reading[:author].join(", ") : reading[:author] ),
156
+ date: reading[:date],
157
+ summary: reading[:summary]
158
+ }
159
+ end
160
+ }
161
+ end
162
+
163
+ def speaking
164
+ {
165
+ history: @doc.dig(:speaking).map do |speaking|
166
+ {
167
+ title: speaking[:title],
168
+ event: speaking[:event],
169
+ location: speaking[:location],
170
+ date: speaking[:date],
171
+ summary: speaking[:summary],
172
+ keywords: speaking[:keywords],
173
+ highlights: speaking[:highlights]
174
+ }
175
+ end
176
+ }
177
+ end
178
+
179
+ def languages
180
+ {
181
+ list: @doc.dig(:languages).map do |language|
182
+ {
183
+ language: language[:language],
184
+ level: language[:level],
185
+ years: language[:years]
186
+ }
187
+ end
188
+ }
189
+ end
190
+
191
+ def interests
192
+ {
193
+ list: @doc.dig(:interests).map do |interest|
194
+ {
195
+ name: interest[:name],
196
+ keywords: interest[:keywords],
197
+ description: interest[:summary]
198
+ }
199
+ end
200
+ }
201
+ end
202
+
203
+ def extracurriculars
204
+ {
205
+ history: @doc.dig(:extracurricular).map do |extracurricular|
206
+ {
207
+ title: extracurricular[:title],
208
+ summary: extracurricular[:activity],
209
+ location: extracurricular[:location],
210
+ startDate: extracurricular[:start],
211
+ endDate: extracurricular[:end]
212
+ }
213
+ end
214
+ }
215
+ end
216
+
217
+ def affiliations
218
+ {
219
+ summary: @doc.dig(:affiliation, :summary),
220
+ history: @doc.dig(:affiliation, :history).map do |affiliation|
221
+ {
222
+ category: affiliation[:category],
223
+ organization: affiliation[:organization],
224
+ roles: [affiliation[:role]],
225
+ url: affiliation[:url],
226
+ startDate: affiliation[:start],
227
+ endDate: affiliation[:end],
228
+ summary: affiliation[:summary],
229
+ location: affiliation[:location],
230
+ highlights: affiliation[:highlights],
231
+ keywords: affiliation[:keywords]
232
+ }
233
+ end
234
+ }
235
+ end
236
+
237
+ def governance
238
+ {
239
+ history: @doc.dig(:governance).map do |governance|
240
+ {
241
+ summary: governance[:summary],
242
+ category: governance[:category],
243
+ roles: [governance[:role]],
244
+ organization: governance[:organization],
245
+ startDate: governance[:start],
246
+ endDate: governance[:end],
247
+ keywords: governance[:keywords],
248
+ highlights: governance[:highlights]
249
+ }
250
+ end
251
+ }
252
+ end
253
+
254
+ def service
255
+ {
256
+ summary: @doc.dig(:service, :summary),
257
+ history: @doc.dig(:service, :history).map do |service|
258
+ {
259
+ category: service[:category],
260
+ organization: service[:organization],
261
+ roles: [service[:position]],
262
+ url: service[:url],
263
+ startDate: service[:start],
264
+ endDate: service[:end],
265
+ summary: service[:summary],
266
+ location: service[:location],
267
+ highlights: service[:highlights],
268
+ keywords: service[:keywords]
269
+ }
270
+ end
271
+ }
272
+ end
273
+
274
+ def references
275
+ {
276
+ history: @doc.dig(:references).map do |reference|
277
+ {
278
+ name: reference[:name],
279
+ role: reference[:role],
280
+ category: reference[:category],
281
+ private: reference[:private],
282
+ contact: reference[:contact],
283
+ summary: reference[:summary]
284
+ }
285
+ end
286
+ }
287
+ end
288
+
289
+ def disposition
290
+ {
291
+ travel: @doc.dig(:disposition, :travel),
292
+ authorization: @doc.dig(:disposition, :authorization),
293
+ commitment: @doc.dig(:disposition, :commitment),
294
+ remote: @doc.dig(:disposition, :remote),
295
+ relocation: {
296
+ willing: @doc.dig(:disposition, :relocation, :willing),
297
+ destinations: @doc.dig(:disposition, :relocation, :destinations)
298
+ }
299
+ }
300
+ end
301
+
302
+ def location
303
+ @doc.dig(:location)
304
+ end
305
+
306
+ def samples
307
+ @doc.dig(:samples)
308
+ end
309
+
310
+ def testimonials
311
+ @doc.dig(:testimonials)
312
+ end
313
+ end
314
+ end