|
|
@ -44,10 +44,129 @@ Trestle.resource(:users) do |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def generate_json |
|
|
def generate_json |
|
|
|
|
|
generate_json_resume |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
def generate_json_resume |
|
|
user = admin.find_instance(params) |
|
|
user = admin.find_instance(params) |
|
|
ac = ActionController::Base.new() |
|
|
|
|
|
json = ac.render_to_string(layout: false, template: "users/show", locals: { "@user": user } ) |
|
|
split_list = lambda do |value| |
|
|
render json: json, layout: false |
|
|
value.to_s.split(/[;,]/).map { |item| item.strip }.reject(&:blank?) |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
parse_period = lambda do |period| |
|
|
|
|
|
years = period.to_s.scan(/\b(19\d{2}|20\d{2})\b/).flatten |
|
|
|
|
|
return [nil, nil] if years.empty? |
|
|
|
|
|
[years[0], years[1]] |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
normalize_url = lambda do |value| |
|
|
|
|
|
return nil if value.blank? |
|
|
|
|
|
value.match?(/\Ahttps?:\/\//) ? value : "https://#{value}" |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
profile_from = lambda do |value, network, base_url| |
|
|
|
|
|
return nil if value.blank? |
|
|
|
|
|
|
|
|
|
|
|
if value.include?("/") || value.include?(".") |
|
|
|
|
|
url = normalize_url.call(value) |
|
|
|
|
|
username = url.to_s.split("/").last&.delete_prefix("@") |
|
|
|
|
|
else |
|
|
|
|
|
username = value.delete_prefix("@") |
|
|
|
|
|
url = base_url.present? ? "#{base_url}/#{username}" : nil |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
profile = { "network" => network } |
|
|
|
|
|
profile["username"] = username if username.present? |
|
|
|
|
|
profile["url"] = url if url.present? |
|
|
|
|
|
profile |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
basics = { |
|
|
|
|
|
"name" => user.name, |
|
|
|
|
|
"label" => user.title, |
|
|
|
|
|
"email" => user.email, |
|
|
|
|
|
"phone" => user.phone, |
|
|
|
|
|
"summary" => user.objective |
|
|
|
|
|
}.compact |
|
|
|
|
|
|
|
|
|
|
|
if user.address.present? |
|
|
|
|
|
basics["location"] = { "address" => user.address } |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
primary_url = user.other_page_url.presence || user.linkedin.presence || user.github.presence |
|
|
|
|
|
basics["url"] = normalize_url.call(primary_url) if primary_url.present? |
|
|
|
|
|
|
|
|
|
|
|
profiles = [] |
|
|
|
|
|
profiles << profile_from.call(user.linkedin, "LinkedIn", "https://www.linkedin.com/in") |
|
|
|
|
|
profiles << profile_from.call(user.github, "GitHub", "https://github.com") |
|
|
|
|
|
profiles << profile_from.call(user.other_page_url, "Website", nil) |
|
|
|
|
|
profiles.compact! |
|
|
|
|
|
basics["profiles"] = profiles if profiles.any? |
|
|
|
|
|
|
|
|
|
|
|
work = user.work_experiences.active.map do |work_entry| |
|
|
|
|
|
start_date, end_date = parse_period.call(work_entry.period) |
|
|
|
|
|
highlights = split_list.call(work_entry.items_csv) |
|
|
|
|
|
technologies = split_list.call(work_entry.technologies) |
|
|
|
|
|
highlights << "Technologies: #{technologies.join(', ')}" if technologies.any? |
|
|
|
|
|
|
|
|
|
|
|
summary = work_entry.achivements.presence |
|
|
|
|
|
summary = work_entry.period.presence if summary.blank? && start_date.blank? && end_date.blank? |
|
|
|
|
|
|
|
|
|
|
|
entry = { |
|
|
|
|
|
"name" => work_entry.employer, |
|
|
|
|
|
"position" => work_entry.title |
|
|
|
|
|
}.compact |
|
|
|
|
|
entry["summary"] = summary if summary.present? |
|
|
|
|
|
entry["highlights"] = highlights if highlights.any? |
|
|
|
|
|
entry["startDate"] = start_date if start_date.present? |
|
|
|
|
|
entry["endDate"] = end_date if end_date.present? |
|
|
|
|
|
if entry["startDate"].blank? && entry["endDate"].blank? && work_entry.reference_date.present? |
|
|
|
|
|
entry["endDate"] = work_entry.reference_date.iso8601 |
|
|
|
|
|
end |
|
|
|
|
|
entry |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
education = user.education_entries.active.map do |education_entry| |
|
|
|
|
|
start_date, end_date = parse_period.call(education_entry.period) |
|
|
|
|
|
|
|
|
|
|
|
study_type = education_entry.title |
|
|
|
|
|
area = nil |
|
|
|
|
|
if study_type.present? && study_type.match?(/\s+in\s+/i) |
|
|
|
|
|
study_type, area = study_type.split(/\s+in\s+/i, 2) |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
courses = split_list.call(education_entry.items_csv) |
|
|
|
|
|
|
|
|
|
|
|
entry = { "institution" => education_entry.institution }.compact |
|
|
|
|
|
entry["studyType"] = study_type if study_type.present? |
|
|
|
|
|
entry["area"] = area if area.present? |
|
|
|
|
|
entry["courses"] = courses if courses.any? |
|
|
|
|
|
entry["startDate"] = start_date if start_date.present? |
|
|
|
|
|
entry["endDate"] = end_date if end_date.present? |
|
|
|
|
|
if entry["startDate"].blank? && entry["endDate"].blank? && education_entry.reference_date.present? |
|
|
|
|
|
entry["endDate"] = education_entry.reference_date.iso8601 |
|
|
|
|
|
end |
|
|
|
|
|
entry |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
skills = user.skills.active.map do |skill| |
|
|
|
|
|
keywords = split_list.call(skill.detail) |
|
|
|
|
|
entry = { "name" => skill.title }.compact |
|
|
|
|
|
if keywords.any? |
|
|
|
|
|
entry["keywords"] = keywords |
|
|
|
|
|
elsif skill.detail.present? |
|
|
|
|
|
entry["level"] = skill.detail |
|
|
|
|
|
end |
|
|
|
|
|
entry |
|
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
resume = { "basics" => basics } |
|
|
|
|
|
resume["work"] = work if work.any? |
|
|
|
|
|
resume["education"] = education if education.any? |
|
|
|
|
|
resume["skills"] = skills if skills.any? |
|
|
|
|
|
|
|
|
|
|
|
render json: resume, layout: false |
|
|
end |
|
|
end |
|
|
|
|
|
|
|
|
def generate_tex(template: "resume") |
|
|
def generate_tex(template: "resume") |
|
|
|