resume_exporter 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.
@@ -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