1
0
mirror of https://github.com/JuanCanham/HackMyResume.git synced 2024-06-30 23:40:05 +01:00
This commit is contained in:
hacksalot 2016-01-05 23:59:41 -05:00
parent 40e71238ac
commit c5eab0fd9c
2 changed files with 158 additions and 109 deletions

View File

@ -36,9 +36,7 @@ Definition of the FRESHResume class.
/**
Open and parse the specified FRESH resume sheet. Merge the JSON object model
onto this Sheet instance with extend() and convert sheet dates to a safe &
consistent format. Then sort each section by startDate descending.
Initialize the FreshResume from file.
*/
FreshResume.prototype.open = function( file, title ) {
this.imp = { fileName: file };
@ -48,6 +46,50 @@ Definition of the FRESHResume class.
/**
Initialize the the FreshResume from string.
*/
FreshResume.prototype.parse = function( stringData, opts ) {
return this.parseJSON( JSON.parse( stringData ), opts );
};
/**
Initialize the FreshResume from JSON.
Open and parse the specified FRESH resume. Merge the JSON object model onto
this Sheet instance with extend() and convert sheet dates to a safe &
consistent format. Then sort each section by startDate descending.
*/
FreshResume.prototype.parseJSON = function( rep, opts ) {
// Convert JSON Resume to FRESH if necessary
if( rep.basics ) {
rep = CONVERTER.toFRESH( rep );
rep.imp = rep.imp || { };
rep.imp.orgFormat = 'JRS';
}
// Now apply the resume representation onto this object
extend( true, this, rep );
// Set up metadata
opts = opts || { };
if( opts.imp === undefined || opts.imp ) {
this.imp = this.imp || { };
this.imp.title = (opts.title || this.imp.title) || this.name;
}
// Parse dates, sort dates, and calculate computed values
(opts.date === undefined || opts.date) && _parseDates.call( this );
(opts.sort === undefined || opts.sort) && this.sort();
(opts.compute === undefined || opts.compute) && (this.computed = {
numYears: this.duration(),
keywords: this.keywords()
});
return this;
};
/**
Save the sheet to disk (for environments that have disk access).
*/
@ -89,8 +131,8 @@ Definition of the FRESHResume class.
/**
Convert the supplied object to a JSON string, sanitizing meta-properties along
the way.
Convert the supplied FreshResume to a JSON string, sanitizing meta-properties
along the way.
*/
FreshResume.stringify = function( obj ) {
function replacer( key,value ) { // Exclude these keys from stringification
@ -104,6 +146,16 @@ Definition of the FRESHResume class.
/**
Convert this object to a JSON string, sanitizing meta-properties along the
way.
*/
FreshResume.prototype.stringify = function() {
return FreshResume.stringify( this );
};
/**
Create a copy of this resume in which all string fields have been run through
a transformation function (such as a Markdown filter or XML encoder).
@ -179,61 +231,14 @@ Definition of the FRESHResume class.
Markdown.
*/
FreshResume.prototype.xmlify = function() {
function trx(key, val) {
return XML(val);
}
return this.transformStrings( [], trx );
};
/**
Convert this object to a JSON string, sanitizing meta-properties along the
way. Don't override .toString().
*/
FreshResume.prototype.stringify = function() {
return FreshResume.stringify( this );
};
/**
Initialize the FreshResume from JSON data.
Open and parse the specified FRESH resume. Merge the JSON object model onto
this Sheet instance with extend() and convert sheet dates to a safe &
consistent format. Then sort each section by startDate descending.
*/
FreshResume.prototype.parseJSON = function( rep, opts ) {
// Convert JSON Resume to FRESH if necessary
if( rep.basics ) {
rep = CONVERTER.toFRESH( rep );
rep.imp = rep.imp || { };
rep.imp.orgFormat = 'JRS';
}
// Now apply the resume representation onto this object
extend( true, this, rep );
// Set up metadata
opts = opts || { };
if( opts.imp === undefined || opts.imp ) {
this.imp = this.imp || { };
this.imp.title = (opts.title || this.imp.title) || this.name;
}
// Parse dates, sort dates, and calculate computed values
(opts.date === undefined || opts.date) && _parseDates.call( this );
(opts.sort === undefined || opts.sort) && this.sort();
(opts.compute === undefined || opts.compute) && (this.computed = {
numYears: this.duration(),
keywords: this.keywords()
});
return this;
};
/**
Return the resume format.
*/
@ -243,15 +248,6 @@ Definition of the FRESHResume class.
/**
Initialize the the FreshResume from string data.
*/
FreshResume.prototype.parse = function( stringData, opts ) {
return this.parseJSON( JSON.parse( stringData ), opts );
};
/**
Return internal metadata. Create if it doesn't exist.
*/
@ -285,7 +281,7 @@ Definition of the FRESHResume class.
/**
Reset the sheet to an empty state.
Reset the sheet to an empty state. TODO: refactor/review
*/
FreshResume.prototype.clear = function( clearMeta ) {
clearMeta = ((clearMeta === undefined) && true) || clearMeta;
@ -346,6 +342,7 @@ Definition of the FRESHResume class.
};
/**
Determine if the sheet includes a specific social profile (eg, GitHub).
*/
@ -403,7 +400,7 @@ Definition of the FRESHResume class.
FreshResume.prototype.isValid = function( info ) {
var schemaObj = require('fresca');
var validator = require('is-my-json-valid');
var validate = validator( schemaObj, { // Note [1]
var validate = validator( schemaObj, { // See Note [1].
formats: { date: /^\d{4}(?:-(?:0[0-9]{1}|1[0-2]{1})(?:-[0-9]{2})?)?$/ }
});
var ret = validate( this );

View File

@ -4,8 +4,12 @@ Definition of the JRSResume class.
@module jrs-resume.js
*/
(function() {
var FS = require('fs')
, extend = require('../utils/extend')
, validator = require('is-my-json-valid')
@ -15,25 +19,24 @@ Definition of the JRSResume class.
, CONVERTER = require('./convert')
, moment = require('moment');
/**
The JRSResume class represent a specific JSON character sheet. When Sheet.open
is called, we merge the loaded JSON sheet properties onto the Sheet instance
via extend(), so a full-grown sheet object will have all of the methods here,
plus a complement of JSON properties from the backing JSON file. That allows
us to treat Sheet objects interchangeably with the loaded JSON model.
A JRS resume or CV. JRS resumes are backed by JSON, and each JRSResume object
is an instantiation of that JSON decorated with utility methods.
@class JRSResume
*/
function JRSResume() {
}
/**
Open and parse the specified JSON resume sheet. Merge the JSON object model
onto this Sheet instance with extend() and convert sheet dates to a safe &
consistent format. Then sort each section by startDate descending.
Initialize the JSResume from file.
*/
JRSResume.prototype.open = function( file, title ) {
//this.imp = { fileName: file }; <-- schema violation, tuck it into .basics instead
//this.imp = { fileName: file }; <-- schema violation, tuck it into .basics
this.basics = {
imp: {
fileName: file,
@ -43,15 +46,58 @@ Definition of the JRSResume class.
return this.parse( this.basics.imp.raw, title );
};
/**
Initialize the the JSResume from string.
*/
JRSResume.prototype.parse = function( stringData, opts ) {
opts = opts || { };
var rep = JSON.parse( stringData );
return this.parseJSON( rep, opts );
};
/**
Initialize the JRSResume from JSON.
Open and parse the specified JRS resume. Merge the JSON object model onto this
Sheet instance with extend() and convert sheet dates to a safe & consistent
format. Then sort each section by startDate descending.
*/
JRSResume.prototype.parseJSON = function( rep, opts ) {
opts = opts || { };
extend( true, this, rep );
// Set up metadata
if( opts.imp === undefined || opts.imp ) {
this.basics.imp = this.basics.imp || { };
this.basics.imp.title =
(opts.title || this.basics.imp.title) || this.basics.name;
this.basics.imp.orgFormat = 'JRS';
}
// Parse dates, sort dates, and calculate computed values
(opts.date === undefined || opts.date) && _parseDates.call( this );
(opts.sort === undefined || opts.sort) && this.sort();
(opts.compute === undefined || opts.compute) && (this.basics.computed = {
numYears: this.duration(),
keywords: this.keywords()
});
return this;
};
/**
Save the sheet to disk (for environments that have disk access).
*/
JRSResume.prototype.save = function( filename ) {
this.basics.imp.fileName = filename || this.basics.imp.fileName;
FS.writeFileSync( this.basics.imp.fileName, this.stringify( this ), 'utf8' );
FS.writeFileSync(this.basics.imp.fileName, this.stringify( this ), 'utf8');
return this;
};
/**
Save the sheet to disk in a specific format, either FRESH or JRS.
*/
@ -70,6 +116,8 @@ Definition of the JRSResume class.
};
/**
Return the resume format.
*/
@ -77,6 +125,8 @@ Definition of the JRSResume class.
return 'JRS';
};
/**
Convert this object to a JSON string, sanitizing meta-properties along the
way. Don't override .toString().
@ -85,50 +135,20 @@ Definition of the JRSResume class.
function replacer( key,value ) { // Exclude these keys from stringification
return _.some(['imp', 'warnings', 'computed', 'filt', 'ctrl', 'index',
'safeStartDate', 'safeEndDate', 'safeDate', 'safeReleaseDate', 'result',
'isModified', 'htmlPreview', 'display_progress_bar'],
'isModified', 'htmlPreview', 'display_progress_bar'],
function( val ) { return key.trim() === val; }
) ? undefined : value;
}
return JSON.stringify( obj, replacer, 2 );
};
JRSResume.prototype.stringify = function() {
return JRSResume.stringify( this );
};
/**
Initialize the JRS Resume from string data.
Open and parse the specified JSON resume sheet. Merge the JSON object model
onto this Sheet instance with extend() and convert sheet dates to a safe &
consistent format. Then sort each section by startDate descending.
*/
JRSResume.prototype.parse = function( stringData, opts ) {
opts = opts || { };
var rep = JSON.parse( stringData );
return this.parseJSON( rep, opts );
};
/**
Initialize the JRSRume from JSON data.
*/
JRSResume.prototype.parseJSON = function( rep, opts ) {
opts = opts || { };
extend( true, this, rep );
// Set up metadata
if( opts.imp === undefined || opts.imp ) {
this.basics.imp = this.basics.imp || { };
this.basics.imp.title = (opts.title || this.basics.imp.title) || this.basics.name;
this.basics.imp.orgFormat = 'JRS';
}
// Parse dates, sort dates, and calculate computed values
(opts.date === undefined || opts.date) && _parseDates.call( this );
(opts.sort === undefined || opts.sort) && this.sort();
(opts.compute === undefined || opts.compute) && (this.basics.computed = {
numYears: this.duration(),
keywords: this.keywords()
});
return this;
};
/**
Return a unique list of all keywords across all skills.
@ -143,6 +163,8 @@ Definition of the JRSResume class.
return flatSkills;
};
/**
Return internal metadata. Create if it doesn't exist.
JSON Resume v0.0.0 doesn't allow additional properties at the root level,
@ -153,6 +175,8 @@ Definition of the JRSResume class.
return this.basics;
};
/**
Reset the sheet to an empty state.
*/
@ -170,13 +194,19 @@ Definition of the JRSResume class.
delete this.basics.profiles;
};
/**
Get the default (empty) sheet.
*/
JRSResume.default = function() {
return new JRSResume().open( PATH.join( __dirname, 'empty-jrs.json'), 'Empty' );
return new JRSResume().open(
PATH.join( __dirname, 'empty-jrs.json'), 'Empty'
);
};
/**
Add work experience to the sheet.
*/
@ -188,6 +218,8 @@ Definition of the JRSResume class.
return newObject;
};
/**
Determine if the sheet includes a specific social profile (eg, GitHub).
*/
@ -198,6 +230,8 @@ Definition of the JRSResume class.
});
};
/**
Determine if the sheet includes a specific skill.
*/
@ -210,11 +244,13 @@ Definition of the JRSResume class.
});
};
/**
Validate the sheet against the JSON Resume schema.
*/
JRSResume.prototype.isValid = function( ) { // TODO: ↓ fix this path ↓
var schema = FS.readFileSync( PATH.join( __dirname, 'resume.json' ), 'utf8' );
var schema = FS.readFileSync( PATH.join( __dirname, 'resume.json' ),'utf8');
var schemaObj = JSON.parse( schema );
var validator = require('is-my-json-valid');
var validate = validator( schemaObj, { // Note [1]
@ -228,6 +264,8 @@ Definition of the JRSResume class.
return ret;
};
/**
Calculate the total duration of the sheet. Assumes this.work has been sorted
by start date descending, perhaps via a call to Sheet.sort().
@ -250,6 +288,8 @@ Definition of the JRSResume class.
return 0;
};
/**
Sort dated things on the sheet by start date descending. Assumes that dates
on the sheet have been processed with _parseDates().
@ -276,12 +316,16 @@ Definition of the JRSResume class.
};
JRSResume.prototype.dupe = function() {
var rnew = new JRSResume();
rnew.parse( this.stringify(), { } );
return rnew;
};
/**
Create a copy of this resume in which all fields have been interpreted as
Markdown.
@ -319,7 +363,9 @@ Definition of the JRSResume class.
Object.keys( obj ).forEach(function(key) {
var sub = obj[key];
if( typeof sub === 'string' || sub instanceof String ) {
if( _.contains(['skills','url','website','startDate','endDate','releaseDate','date','phone','email','address','postalCode','city','country','region'], key) )
if( _.contains(['skills','url','website','startDate','endDate',
'releaseDate','date','phone','email','address','postalCode',
'city','country','region'], key) )
return;
if( key === 'summary' )
obj[key] = HD( obj[key] );
@ -340,6 +386,8 @@ Definition of the JRSResume class.
return ret;
};
/**
Convert human-friendly dates into formal Moment.js dates for all collections.
We don't want to lose the raw textual date as entered by the user, so we store
@ -371,9 +419,13 @@ Definition of the JRSResume class.
});
}
/**
Export the JRSResume function/ctor.
*/
module.exports = JRSResume;
}());