mirror of
				https://github.com/JuanCanham/HackMyResume.git
				synced 2025-11-03 22:37:27 +00:00 
			
		
		
		
	Improve date parsing and sorting.
This commit is contained in:
		@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}());
 | 
					}());
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user