mirror of
https://github.com/JuanCanham/HackMyResume.git
synced 2024-11-22 00:10:15 +00:00
Improve date parsing and sorting.
This commit is contained in:
parent
c55a2f9f35
commit
1a1310cef5
@ -28,6 +28,7 @@
|
|||||||
"jst": "0.0.13",
|
"jst": "0.0.13",
|
||||||
"marked": "^0.3.5",
|
"marked": "^0.3.5",
|
||||||
"minimist": "^1.2.0",
|
"minimist": "^1.2.0",
|
||||||
|
"moment": "^2.10.6",
|
||||||
"underscore": "^1.8.3",
|
"underscore": "^1.8.3",
|
||||||
"wkhtmltopdf": "^0.1.5",
|
"wkhtmltopdf": "^0.1.5",
|
||||||
"xml-escape": "^1.0.0"
|
"xml-escape": "^1.0.0"
|
||||||
|
127
src/sheet.js
127
src/sheet.js
@ -5,14 +5,18 @@ Abstract character/resume sheet representation.
|
|||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
|
||||||
var FS = require('fs');
|
var FS = require('fs')
|
||||||
var extend = require('./extend');
|
, extend = require('./extend')
|
||||||
var validator = require('is-my-json-valid');
|
, validator = require('is-my-json-valid')
|
||||||
|
, _ = require('underscore')
|
||||||
|
, moment = require('moment');
|
||||||
|
|
||||||
|
/**
|
||||||
|
Initialize a new Sheet instance.
|
||||||
|
*/
|
||||||
function Sheet() {
|
function Sheet() {
|
||||||
this.id = null;
|
this.id = null;
|
||||||
this.title = "New";
|
this.title = "New";
|
||||||
this.rep = { };
|
|
||||||
this.fileName = null;
|
this.fileName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,9 +26,12 @@ Abstract character/resume sheet representation.
|
|||||||
Sheet.prototype.open = function( file, title ) {
|
Sheet.prototype.open = function( file, title ) {
|
||||||
var rep = JSON.parse( FS.readFileSync( file, 'utf8' ) );
|
var rep = JSON.parse( FS.readFileSync( file, 'utf8' ) );
|
||||||
extend( true, this, rep );
|
extend( true, this, rep );
|
||||||
console.log( this );
|
|
||||||
this.fileName = file;
|
this.fileName = file;
|
||||||
this.title = title || this.basics.name;
|
this.title = title || this.basics.name;
|
||||||
|
_parseDates.call( this );
|
||||||
|
this.sort();
|
||||||
|
this.computed = this.computed || { };
|
||||||
|
this.computed.numYears = this.duration();
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,10 +40,22 @@ Abstract character/resume sheet representation.
|
|||||||
*/
|
*/
|
||||||
Sheet.prototype.hasProfile = function( socialNetwork ) {
|
Sheet.prototype.hasProfile = function( socialNetwork ) {
|
||||||
socialNetwork = socialNetwork.trim().toLowerCase();
|
socialNetwork = socialNetwork.trim().toLowerCase();
|
||||||
return this.basics.profiles && this.basics.profiles.filter(function(prof) {
|
return this.basics.profiles && _.some( this.basics.profiles, function(prof) {
|
||||||
return prof.network.trim().toLowerCase() === socialNetwork;
|
return prof.network.trim().toLowerCase() === socialNetwork;
|
||||||
}).length > 0;
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Determine if the sheet includes a specific skill.
|
||||||
|
*/
|
||||||
|
Sheet.prototype.hasSkill = function( skill ) {
|
||||||
|
skill = skill.trim().toLowerCase();
|
||||||
|
return this.skills && _.some( this.skills, function(sk) {
|
||||||
|
return sk.keywords && _.some( sk.keywords, function(kw) {
|
||||||
|
return kw.trim().toLowerCase() === skill;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Validate the sheet against a specific JSON schema.
|
Validate the sheet against a specific JSON schema.
|
||||||
@ -46,8 +65,100 @@ Abstract character/resume sheet representation.
|
|||||||
var validator = require('is-my-json-valid')
|
var validator = require('is-my-json-valid')
|
||||||
var validate = validator( schemaObj );
|
var validate = validator( schemaObj );
|
||||||
return validate( this );
|
return validate( this );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Calculate the total duration of the sheet. Assumes this.work has been sorted
|
||||||
|
by start date descending.
|
||||||
|
*/
|
||||||
|
Sheet.prototype.duration = function() {
|
||||||
|
var careerStart = _fmt( this.work[ this.work.length - 1].startDate );
|
||||||
|
var careerLast = _fmt( _.max( this.work, function( w ) {
|
||||||
|
return _fmt( w.endDate ).unix();
|
||||||
|
}).endDate );
|
||||||
|
return careerLast.diff( careerStart, 'years' );
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sort dated things by start date descending.
|
||||||
|
*/
|
||||||
|
Sheet.prototype.sort = function( ) {
|
||||||
|
var da, db;
|
||||||
|
if( this.work && this.work.length > 1 ) {
|
||||||
|
this.work.sort( function(a, b) {
|
||||||
|
return( a.safeStartDate.isBefore(b.safeStartDate) ) ? 1 : ( a.safeStartDate.isAfter(b.safeStartDate) && -1 ) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if( this.education && this.education.length > 1 ) {
|
||||||
|
this.education.sort( function(a, b) {
|
||||||
|
return( a.safeStartDate.isBefore(b.safeStartDate) ) ? 1 : ( a.safeStartDate.isAfter(b.safeStartDate) && -1 ) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if( this.volunteer && this.volunteer.length > 1 ) {
|
||||||
|
this.volunteer.sort( function(a, b) {
|
||||||
|
return( a.safeStartDate.isBefore(b.safeStartDate) ) ? 1 : ( a.safeStartDate.isAfter(b.safeStartDate) && -1 ) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if( this.awards && this.awards.length > 1 ) {
|
||||||
|
this.awards.sort( function(a, b) {
|
||||||
|
return( a.safeDate.isBefore(b.safeDate) ) ? 1 : ( a.safeDate.isAfter(b.safeDate) && -1 ) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if( this.publications && this.publications.length > 1 ) {
|
||||||
|
this.publications.sort( function(a, b) {
|
||||||
|
return( a.safeReleaseDate.isBefore(b.safeReleaseDate) ) ? 1 : ( a.safeReleaseDate.isAfter(b.safeReleaseDate) && -1 ) || 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Format a human-friendly FluentCV date to a Moment.js-compatible date.
|
||||||
|
*/
|
||||||
|
function _fmt( dt ) {
|
||||||
|
dt = dt.toLowerCase().trim();
|
||||||
|
if( dt === 'present' ) {
|
||||||
|
return moment();
|
||||||
|
}
|
||||||
|
else if( /^\D+/.test(dt) ) {
|
||||||
|
var parts = dt.split(' ');
|
||||||
|
return moment( parts[1] + '-' + (months[ parts[0] ] || abbr[ parts[0] ] || ( parts[0] === 'sept' && '09' )) + '-' + '01', 'YYYY-MM-DD' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var mt = moment( dt );
|
||||||
|
if(mt.isValid())
|
||||||
|
return mt;
|
||||||
|
throw 'Invalid date format encountered. Use YYYY-MM-DD.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _parseDates() {
|
||||||
|
this.work.forEach( function(job) {
|
||||||
|
job.safeStartDate = _fmt( job.startDate );
|
||||||
|
job.safeEndDate = _fmt( job.endDate );
|
||||||
|
});
|
||||||
|
this.education.forEach( function(edu) {
|
||||||
|
edu.safeStartDate = _fmt( edu.startDate );
|
||||||
|
edu.safeEndDate = _fmt( edu.endDate );
|
||||||
|
});
|
||||||
|
this.volunteer.forEach( function(vol) {
|
||||||
|
vol.safeStartDate = _fmt( vol.startDate );
|
||||||
|
vol.safeEndDate = _fmt( vol.endDate );
|
||||||
|
});
|
||||||
|
this.awards.forEach( function(awd) {
|
||||||
|
awd.safeDate = _fmt( awd.date );
|
||||||
|
});
|
||||||
|
this.publications.forEach( function(pub) {
|
||||||
|
pub.safeReleaseDate = _fmt( pub.releaseDate );
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var months = {}, abbr = {};
|
||||||
|
moment.months().forEach( function(m, idx) { months[ m.toLowerCase() ] = idx + 1; });
|
||||||
|
moment.monthsShort().forEach( function(m, idx) { abbr[ m.toLowerCase() ] = idx + 1; });
|
||||||
|
|
||||||
|
/**
|
||||||
|
Export the Sheet function/ctor.
|
||||||
|
*/
|
||||||
module.exports = Sheet;
|
module.exports = Sheet;
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
Loading…
Reference in New Issue
Block a user