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

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