You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
6.4 KiB
184 lines
6.4 KiB
Trestle.resource(:users) do
|
|
menu do
|
|
item :users, icon: "fa fa-user", priority: 1
|
|
end
|
|
|
|
form do |item|
|
|
concat Trestle::Form::Automatic.new(admin).render(self, item)
|
|
|
|
text_area :objective
|
|
end
|
|
|
|
# Customize the table columns shown on the index view.
|
|
table do
|
|
column :name
|
|
column :created_at, align: :center
|
|
actions do |toolbar, instance, admin|
|
|
toolbar.edit if admin && admin.actions.include?(:edit)
|
|
toolbar.delete if admin && admin.actions.include?(:destroy)
|
|
toolbar.link 'CV', instance, action: :generate, method: :get, style: :primary, icon: "fa fa-file-pdf", target: "_blank"
|
|
toolbar.link 'CLS', instance, action: :generate_cls, method: :get, style: :secondary, icon: "fa", target: "_blank"
|
|
toolbar.link 'JSON', instance, action: :generate_json, method: :get, style: :secondary, icon: "fa", target: "_blank"
|
|
end
|
|
end
|
|
|
|
controller do
|
|
def generate
|
|
tex_content = generate_tex
|
|
destination_dir = "#{Rails.root}/app/views/templates/awesome"
|
|
`cd #{destination_dir} && make clean`
|
|
File.open("#{destination_dir}/resume.tex", "w") do |f|
|
|
f << tex_content
|
|
end
|
|
`cd #{destination_dir} && make resume.pdf`
|
|
render file: "#{destination_dir}/resume.pdf", layout: false
|
|
end
|
|
|
|
def generate_cls
|
|
tex_content = generate_tex
|
|
destination_dir = "#{Rails.root}/app/views/templates/awesome"
|
|
File.open("#{destination_dir}/resume.tex", "w") do |f|
|
|
f << tex_content
|
|
end
|
|
render file: "#{destination_dir}/resume.tex", layout: false
|
|
end
|
|
|
|
def generate_json
|
|
generate_json_resume
|
|
end
|
|
|
|
def generate_json_resume
|
|
user = admin.find_instance(params)
|
|
|
|
split_list = lambda do |value|
|
|
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
|
|
|
|
def generate_tex(template: "resume")
|
|
user = admin.find_instance(params)
|
|
ac = ActionController::Base.new()
|
|
ac.render_to_string(layout: false, template: "templates/awesome/#{template}", locals: { "@user": user } )
|
|
end
|
|
end
|
|
|
|
routes do
|
|
get :generate, on: :member
|
|
get :generate_cls, on: :member
|
|
get :generate_json, on: :member
|
|
end
|
|
end
|
|
|