2018-05-07 00:58:03 +02:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 Arnaud Ysmal. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package model
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
2018-05-10 17:23:38 +02:00
|
|
|
"regexp"
|
2018-05-07 00:58:03 +02:00
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const ISO8601DateLayout = "2006-01-02"
|
|
|
|
|
2018-05-10 17:23:38 +02:00
|
|
|
var MarkdownURLRegexp = regexp.MustCompile(`\[([^]]*)\]\((http[^)]*)\)`)
|
|
|
|
|
2018-05-07 00:58:03 +02:00
|
|
|
type ResumeDate struct {
|
|
|
|
time.Time
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ct *ResumeDate) UnmarshalJSON(b []byte) (err error) {
|
|
|
|
s := strings.Trim(string(b), "\"")
|
|
|
|
if s == "null" {
|
|
|
|
ct.Time = time.Time{}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
ct.Time, err = time.Parse(ISO8601DateLayout, s)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Resume represent Curriculum Vitae
|
|
|
|
type Resume struct {
|
2021-02-07 21:38:09 +01:00
|
|
|
Title string `json:"title"`
|
|
|
|
UseFullAddress bool
|
|
|
|
Language string `json:"lang"`
|
|
|
|
Basic Basic `json:"basics"`
|
|
|
|
Work []Work `json:"work"`
|
|
|
|
Volunteer []Volunteer `json:"volunteer"`
|
|
|
|
Education []Education `json:"education"`
|
|
|
|
Awards []Award `json:"awards"`
|
|
|
|
Publications []Publication `json:"publications"`
|
|
|
|
Skills []Skill `json:"skills"`
|
|
|
|
Languages []Language `json:"languages"`
|
|
|
|
Interests []Interest `json:"interests"`
|
|
|
|
References []Reference `json:"references"`
|
|
|
|
Projects []Project `json:"projects"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Basic is the basic information for a resume
|
|
|
|
type Basic struct {
|
2018-05-09 23:30:40 +02:00
|
|
|
Name string `json:"name"`
|
|
|
|
Label string `json:"label"`
|
|
|
|
Image string `json:"image"`
|
|
|
|
Email string `json:"email"`
|
|
|
|
Phone string `json:"phone"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
Location UserLocation `json:"location"`
|
|
|
|
Profiles []SocialProfile `json:"profiles"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Location is the location details of a resume owner.
|
2018-05-09 23:30:40 +02:00
|
|
|
type UserLocation struct {
|
2021-02-07 21:38:09 +01:00
|
|
|
Address string `json:"address"`
|
|
|
|
ShortAddress string `json:"shortAddress"`
|
|
|
|
PostalCode string `json:"postalCode"`
|
|
|
|
City string `json:"city"`
|
|
|
|
CountryCode string `json:"countryCode"`
|
|
|
|
Region string `json:"region"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// SocialProfile is the profile of the resume owner.
|
|
|
|
type SocialProfile struct {
|
|
|
|
Network string `json:"network"`
|
|
|
|
UserName string `json:"username"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
}
|
|
|
|
|
2018-05-09 23:30:40 +02:00
|
|
|
type Highlight struct {
|
2018-05-08 23:43:11 +02:00
|
|
|
Title string `json:"title"`
|
|
|
|
Items []string `json:"items"`
|
|
|
|
}
|
|
|
|
|
2018-05-07 00:58:03 +02:00
|
|
|
// Work is the work details of the resume owner.
|
|
|
|
type Work struct {
|
2018-05-09 23:30:40 +02:00
|
|
|
Name string `json:"name"`
|
2021-02-01 22:16:53 +01:00
|
|
|
Hide bool `json:"hide"`
|
2018-05-09 23:30:40 +02:00
|
|
|
Location string `json:"location"`
|
|
|
|
Description string `json:"description"`
|
|
|
|
Position string `json:"position"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
StartDate ResumeDate `json:"startDate"`
|
|
|
|
EndDate ResumeDate `json:"endDate"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
Highlights []Highlight `json:"highlights"`
|
|
|
|
Keywords []string `json:"keywords"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Volunteer is the volunteer details of the resume owner.
|
|
|
|
type Volunteer struct {
|
2018-05-09 23:30:40 +02:00
|
|
|
Organization string `json:"organization"`
|
2021-02-01 22:16:53 +01:00
|
|
|
Hide bool `json:"hide"`
|
2018-05-09 23:30:40 +02:00
|
|
|
Position string `json:"position"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
StartDate ResumeDate `json:"startDate"`
|
|
|
|
EndDate ResumeDate `json:"endDate"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
Highlights []Highlight `json:"highlights"`
|
|
|
|
Keywords []string `json:"keywords"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Education is the education details of the resume owner.
|
|
|
|
type Education struct {
|
|
|
|
Institution string `json:"institution"`
|
2021-02-01 22:16:53 +01:00
|
|
|
Hide bool `json:"hide"`
|
2021-02-07 21:10:42 +01:00
|
|
|
Location string `json:"location"`
|
2018-05-07 00:58:03 +02:00
|
|
|
Area string `json:"area"`
|
|
|
|
StudyType string `json:"studyType"`
|
|
|
|
StartDate ResumeDate `json:"startDate"`
|
|
|
|
EndDate ResumeDate `json:"endDate"`
|
|
|
|
GPA string `json:"gpa"`
|
|
|
|
Courses []string `json:"courses"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Award is the award details of the resume owner.
|
|
|
|
type Award struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
Date ResumeDate `json:"date"`
|
|
|
|
Awarder string `json:"awarder"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Publication is the publication details of the resume owner.
|
|
|
|
type Publication struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Publisher string `json:"publisher"`
|
|
|
|
ReleaseDate ResumeDate `json:"releaseDate"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
Summary string `json:"summary"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skill is the skill details of the resume owner.
|
|
|
|
type Skill struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Level string `json:"level"`
|
|
|
|
Keywords []string `json:"keywords"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Language is the language details of the resume owner.
|
|
|
|
type Language struct {
|
|
|
|
Language string `json:"language"`
|
|
|
|
Fluency string `json:"fluency"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Interest is the interest details of the resume owner.
|
|
|
|
type Interest struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Keywords []string `json:"keywords"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Referee is the details about a person who is refereeing for the resume owner.
|
|
|
|
type Reference struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
Reference string `json:"reference"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Volunteer is the volunteer details of the resume owner.
|
|
|
|
type Project struct {
|
2018-05-09 23:30:40 +02:00
|
|
|
Name string `json:"name"`
|
2021-02-01 22:16:53 +01:00
|
|
|
Hide bool `json:"hide"`
|
2018-05-09 23:30:40 +02:00
|
|
|
Description string `json:"description"`
|
|
|
|
Highlights []Highlight `json:"highlights"`
|
|
|
|
Keywords []string `json:"keywords"`
|
|
|
|
StartDate ResumeDate `json:"startDate"`
|
|
|
|
EndDate ResumeDate `json:"endDate"`
|
|
|
|
URL string `json:"url"`
|
|
|
|
Roles []string `json:"roles"`
|
|
|
|
Entity string `json:"entity"`
|
|
|
|
Type string `json:"type"`
|
2018-05-07 00:58:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func Parse(f string) (*Resume, error) {
|
|
|
|
var content []byte
|
|
|
|
var err error
|
|
|
|
var r Resume
|
|
|
|
|
|
|
|
if content, err = ioutil.ReadFile(f); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err = json.Unmarshal(content, &r); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &r, nil
|
|
|
|
}
|