diff --git a/index.html b/index.html old mode 100755 new mode 100644 diff --git a/package.json b/package.json index 7f9cd94..454d5ab 100755 --- a/package.json +++ b/package.json @@ -9,13 +9,13 @@ "author": "salomonelli", "homepage": "https://github.com/salomonelli/best-resume-ever", "scripts": { - "server": "node --harmony-async-await src/server.js", - "less": "node --harmony-async-await src/compileLess.js", - "babel": "babel --presets es2015 src/javascript.js -o public/javascript.js", - "readme": "node --harmony-async-await src/renderReadMe.js", + "server": "node --harmony-async-await src/app.js", + "less": "node --harmony-async-await src/less.js", + "babel": "babel --presets es2015 src/public/javascript.js -o public/javascript.js", + "readme": "node --harmony-async-await src/RenderReadMe.js", "start": "npm run babel && npm run less && npm run server", "dev": "watch 'npm start' src/ resumes/ less/", - "pdf": "npm run babel && npm run less && node --harmony-async-await src/htmlToPdf.js" + "pdf": "npm run babel && npm run less && node --harmony-async-await src/ResumeToPdf.js" }, "dependencies": { "@typopro/web-montserrat": "3.4.9", diff --git a/pdf/resume-grey-boxes.pdf b/pdf/resume-grey-boxes.pdf old mode 100755 new mode 100644 index df00365..9295c82 Binary files a/pdf/resume-grey-boxes.pdf and b/pdf/resume-grey-boxes.pdf differ diff --git a/pdf/resume-left-right.pdf b/pdf/resume-left-right.pdf old mode 100755 new mode 100644 index 0b8e3ec..aa8f27a Binary files a/pdf/resume-left-right.pdf and b/pdf/resume-left-right.pdf differ diff --git a/pdf/resume-oblique.pdf b/pdf/resume-oblique.pdf old mode 100755 new mode 100644 index f82e8dc..4d3221c Binary files a/pdf/resume-oblique.pdf and b/pdf/resume-oblique.pdf differ diff --git a/pdf/resume-side-bar.pdf b/pdf/resume-side-bar.pdf old mode 100755 new mode 100644 index 593fd75..77c10b4 Binary files a/pdf/resume-side-bar.pdf and b/pdf/resume-side-bar.pdf differ diff --git a/pdf/resume-spotify.pdf b/pdf/resume-spotify.pdf old mode 100755 new mode 100644 index 42f5deb..29c3132 Binary files a/pdf/resume-spotify.pdf and b/pdf/resume-spotify.pdf differ diff --git a/pdf/resume-wanted.pdf b/pdf/resume-wanted.pdf old mode 100755 new mode 100644 index 46e13a5..b3e601f Binary files a/pdf/resume-wanted.pdf and b/pdf/resume-wanted.pdf differ diff --git a/public/javascript.js b/public/javascript.js old mode 100755 new mode 100644 index bba7382..52a0fb0 --- a/public/javascript.js +++ b/public/javascript.js @@ -56,7 +56,7 @@ var removeBoxShadowOfElement = function removeBoxShadowOfElement(element) { /** * gets border radius of element * @param {HTMLElement} element - * @return {String} e.g. '50%' + * @return {string} e.g. '50%' */ var getBorderRadiusOfElement = function getBorderRadiusOfElement(element) { return window.getComputedStyle(element, null).getPropertyValue('border-radius'); @@ -123,10 +123,17 @@ var fixBoxShadows = function fixBoxShadows() { } }; +/** + * checks if the page contains a resume + * @return {Boolean} true if page contains resume + */ var isResume = function isResume() { if (document.getElementsByTagName('page')[0]) return true;else return false; }; +/** + * fixes resume + */ var fixResume = function fixResume() { if (!isResume()) return; getAllDOMElements(); diff --git a/public/style.min.css b/public/style.min.css old mode 100755 new mode 100644 diff --git a/src/Config.js b/src/Config.js new file mode 100644 index 0000000..60c5930 --- /dev/null +++ b/src/Config.js @@ -0,0 +1,5 @@ +const Config = { + port: 3000 +}; + +module.exports = Config; diff --git a/src/RenderReadMe.js b/src/RenderReadMe.js new file mode 100755 index 0000000..a77b529 --- /dev/null +++ b/src/RenderReadMe.js @@ -0,0 +1,27 @@ +const showdown = require('showdown'); +const converter = new showdown.Converter(); +const fs = require('fs'); +const path = require('path'); +const Mustache = require('mustache'); +const writeFile = require('write'); +const Util = require('./Util'); + +/** + * renders readme to html for github Pages + * @return {Promise} + */ +RenderReadMe = async function() { + let dir = path.join(__dirname, '../' + 'README.md'); + const readmeContent = await Util.readFileContent(dir); + const readmeHTML = converter.makeHtml(readmeContent); + dir = path.join(__dirname, '../' + 'resumes/views/githubPages.mustache'); + const githubPagesTemplate = await Util.readFileContent(dir); + const readme = Mustache.render(githubPagesTemplate, { + content: readmeHTML + }); + await Util.writeFile('index.html', readme); +} + +RenderReadMe(); + +module.exports = RenderReadMe; diff --git a/src/ResumeToPdf.js b/src/ResumeToPdf.js new file mode 100755 index 0000000..f98fe41 --- /dev/null +++ b/src/ResumeToPdf.js @@ -0,0 +1,35 @@ +const pdf = require('html-pdf'); +const path = require('path'); +const Config = require('./Config'); +const Util = require('./Util'); +const Server = require('./Server'); + + +const ResumeToPdf = { + /** + * generates electroshot command for screenshoting resume + * @param {string} resume resume name in URL + * @return {string} electroshot command + */ + electroshotScript: function(resume) { + const dir = path.join(__dirname, '../pdf'); + return 'electroshot localhost:3000/' + resume + + ' 2481x3508 --pdf-margin none --format pdf --out ' + dir + + ' --filename "' + resume + '.pdf" --pdf-background; '; + }, + /** + * converts resumes to pdf + * @return {Promise} + */ + convert: async function() { + Server.run(); + const directories = Util.getResumesFromDirectories(); + let script = ''; + directories.forEach(async(resume) => script += ResumeToPdf.electroshotScript(resume.path)); + script = script.substring(0, script.length - 2); + await Util.execBash(script); + await Server.kill(); + } +} + +ResumeToPdf.convert(); diff --git a/src/Server.js b/src/Server.js new file mode 100755 index 0000000..0e1631b --- /dev/null +++ b/src/Server.js @@ -0,0 +1,83 @@ +const path = require('path'); +const fs = require('fs'); +const express = require('express'); +const mustacheExpress = require('mustache-express'); +const request = require('request-promise'); +const Config = require('./Config'); +const Util = require('./Util'); +const person = require('./person.js'); + +let app, resumes; +const Server = { + /** + * sets configurations of express app + */ + setup: function() { + if (!app) app = express(); + app.set('views', path.join(__dirname, '../resumes')); + app.engine('mustache', require('hogan-express')); + app.set('view engine', 'mustache'); + app.use(express.static(path.join(__dirname, '../public'))); + app.use(express.static(path.join(__dirname, '../node_modules'))); + }, + /** + * starts up express app + */ + start: function() { + app.listen(Config.port, '0.0.0.0', () => console.log('Listening on localhost:' + Config.port + '!')); + }, + /** + * kills express app + */ + kill: function() { + request.get('http://localhost:' + Config.port + '/kill') + .catch(error => {}); + }, + /** + * sets route of express app + * @param {string} path e.g. '/' or '/resumes' + * @param {string} template e.g. 'views/resumeX/index' + */ + setRoute: function(path, template) { + app.get(path, (req, res) => { + res.render('views/layout', { + partials: { + content: template + }, + resumes: resumes, + person: person + }); + }); + }, + /** + * sets route to kill app + */ + setKillRoute: function() { + app.get('/kill', () => process.exit()); + }, + /** + * sets routes for each resume + */ + setRoutesForResumes: function() { + const directories = Util.getDirectories(); + for (let resume of directories) { + Server.setRoute('/' + resume, resume + '/index'); + } + }, + /** + * run server + * @return {Promise} resolves when server is running + */ + run: async function() { + resumes = Util.getResumesFromDirectories(); + Server.setup(); + Server.setRoute('/', 'views/index'); + Server.setRoutesForResumes(); + Server.setKillRoute(); + Server.kill(); + await Util.setTimeout(500); + Server.start(); + } +} + +module.exports = Server; diff --git a/src/StyleCompiler.js b/src/StyleCompiler.js new file mode 100755 index 0000000..12e284f --- /dev/null +++ b/src/StyleCompiler.js @@ -0,0 +1,65 @@ +const less = require('less'); +const path = require('path'); +const fs = require('fs'); +const CleanCSS = require('clean-css'); +const writeFile = require('write'); +const Util = require('./Util'); + +const StyleCompiler = { + /** + * compiles less string to css string + * @param {string} lessContent + * @return {string} css + */ + compile: function(lessContent) { + let lessDir = path.join(__dirname, '../less'); + return new Promise((res, rej) => { + less.render(lessContent, { + paths: [lessDir, lessDir + '/fonts'], + }, (e, output) => { + if (e) rej(e); + else res(output.css); + }); + }); + }, + /** + * minifies css + * @param {string} css + * @return {string} minified css + */ + minify: function(css) { + return new Promise((res, rej) => { + new CleanCSS().minify(css, (err, output) => { + if (err) rej(err); + else res(output) + }); + }); + }, + /** + * compiles less files to minified css file + * @return {Promise} + */ + run: async function() { + const directories = Util.getResumesFromDirectories(); + const styleLess = await Util.readFileContent(path.join(__dirname, '../less/style.less')); + let css = await StyleCompiler.compile(styleLess); + const contents = await Promise.all( + directories + .map(resume => Util.readFileContent( + path.join(__dirname, '../resumes/' + resume.path + '/style.less') + )) + ); + const compiledContents = await Promise.all( + contents + .map(content => StyleCompiler.compile(content)) + ); + const ret = compiledContents.reduce((pre, cur) => pre += cur, css); + // minify + const minCSS = await StyleCompiler.minify(ret); + // write file + const p = path.join(__dirname, '../public/style.min.css'); + await Util.writeFile(p, minCSS.styles); + } +} + +module.exports = StyleCompiler; diff --git a/src/Util.js b/src/Util.js new file mode 100644 index 0000000..142113e --- /dev/null +++ b/src/Util.js @@ -0,0 +1,86 @@ +const path = require('path'); +const request = require('request-promise'); +const writeFile = require('write'); +const fs = require('fs'); +const Config = require('./Util'); +var exec = require('child_process').exec; + +const Util = { + /** + * gets directories starting with 'resume-' + * @return {[]} + */ + getDirectories: function() { + const srcpath = path.join(__dirname, '../resumes'); + return fs.readdirSync(srcpath) + .filter(file => file.includes('resume-')) + }, + /** + * gets resumes names and paths from directories + * @return {Object[]} array with resumes object {path: '', name: ''} + */ + getResumesFromDirectories: function() { + const directories = Util.getDirectories(); + let resumes = []; + directories.forEach(dir => { + let name = dir.replace('resume-', ''); + resumes.push({ + path: dir, + name: name.replace('-', ' ') + }) + }); + return resumes; + }, + /** + * setTimeout as Promise + * @param {number} time time in ms + * @return {Promise} + */ + setTimeout: function(time) { + return new Promise(res => setTimeout(res, time)); + }, + /** + * reads file of content + * @param {string} dir directory + * @return {Promise} + */ + readFileContent: function(dir) { + return new Promise((res, rej) => { + fs.readFile(dir, 'utf8', (err, template) => { + if (err) rej(err); + else res(template); + }); + }); + }, + /** + * writes content to given file + * @param {string} dir directory + * @param {string} content content of file + * @return {Promise} + */ + writeFile: function(dir, content) { + return new Promise((res, rej) => { + writeFile(dir, content, err => { + if (err) rej(err); + res(); + }); + }); + + }, + /** + * executes command + * @param {string} script e.g. 'echo "Hello World"' + * @return {Promise} + */ + execBash: function(script) { + return new Promise((res, rej) => { + exec(script, + (error, stdout, stderr) => { + if (error) rej(err); + else res(); + }); + }); + } +} + +module.exports = Util; diff --git a/src/app.js b/src/app.js new file mode 100644 index 0000000..cd50f5f --- /dev/null +++ b/src/app.js @@ -0,0 +1,2 @@ +const Server = require('./Server'); +Server.run(); diff --git a/src/compileLess.js b/src/compileLess.js deleted file mode 100755 index d03d54f..0000000 --- a/src/compileLess.js +++ /dev/null @@ -1,70 +0,0 @@ -const less = require('less'); -const path = require('path'); -const fs = require('fs'); -const CleanCSS = require('clean-css'); -const writeFile = require('write'); - -const dir = path.join(__dirname, '../resumes'); -const directories = getDirectories(dir); - -function getDirectories(srcpath) { - return fs.readdirSync(srcpath) - .filter(file => file.includes('resume-')) -} - -function compileToCSS(lessContent) { - let lessDir = path.join(__dirname, '../less'); - return new Promise((res, rej) => { - less.render(lessContent, { - paths: [lessDir, lessDir + '/fonts'], - }, (e, output) => { - if (e) rej(e); - else res(output.css); - }); - }); -} - -function readFileContent(fileName) { - const dir = path.join(__dirname, '../' + fileName); - return new Promise((res, rej) => { - fs.readFile(dir, 'utf8', (err, template) => { - if (err) rej(err); - else res(template); - }); - }); -} - -function minifyCSS(css) { - return new Promise((res, rej) => { - new CleanCSS().minify(css, (err, output) => { - if (err) rej(err); - else res(output) - }); - }); -} - -async function compileLessFiles() { - const styleLess = await readFileContent('less/style.less'); - let css = await compileToCSS(styleLess); - - const contents = await Promise.all( - directories - .map(resume => readFileContent('resumes/' + resume + '/style.less')) - ); - const compiledContents = await Promise.all( - contents - .map(content => compileToCSS(content)) - ); - const ret = compiledContents.reduce((pre, cur) => pre += cur, css); - - // minify - const minCSS = await minifyCSS(ret); - - // write file - const p = path.join(__dirname, '../public/style.min.css'); - writeFile(p, minCSS.styles, err => { - if (err) console.log(err); - }); -} - -compileLessFiles(); diff --git a/src/htmlToPdf.js b/src/htmlToPdf.js deleted file mode 100755 index b504ae7..0000000 --- a/src/htmlToPdf.js +++ /dev/null @@ -1,38 +0,0 @@ -const person = require('./person.js'); -const Mustache = require('mustache'); -const pdf = require('html-pdf'); -const fs = require('fs'); -const path = require('path'); -var exec = require('child_process').exec; -const dir = path.join(__dirname, '../resumes'); -const directories = getDirectories(dir); -const request = require('request-promise'); -const port = 3000; - -require('./server'); - -function getDirectories(srcpath) { - return fs.readdirSync(srcpath) - .filter(file => file.includes('resume-')) -} - -async function convertToPdf() { - let script = ''; - let dir = path.join(__dirname, '../pdf'); - directories.forEach(async(resume) => { - script += 'electroshot localhost:3000/' + resume + - ' 2481x3508 --pdf-margin none --format pdf --out ' + dir + - ' --filename "' + resume + '.pdf" --pdf-background; '; - }); - script = script.substring(0, script.length - 2); - exec(script, - (error, stdout, stderr) => { - if (error) console.log(error); - else console.log(stderr); - request.get('http://localhost:' + port + '/kill') - .catch(error => {}); - }); -} - - -convertToPdf(); diff --git a/src/less.js b/src/less.js new file mode 100644 index 0000000..b2173b0 --- /dev/null +++ b/src/less.js @@ -0,0 +1,2 @@ +const StyleCompiler = require('./StyleCompiler'); +StyleCompiler.run(); diff --git a/src/javascript.js b/src/public/javascript.js similarity index 95% rename from src/javascript.js rename to src/public/javascript.js index f7c85e1..25ce429 100755 --- a/src/javascript.js +++ b/src/public/javascript.js @@ -60,7 +60,7 @@ const removeBoxShadowOfElement = element => { /** * gets border radius of element * @param {HTMLElement} element - * @return {String} e.g. '50%' + * @return {string} e.g. '50%' */ const getBorderRadiusOfElement = element => { return window @@ -128,11 +128,18 @@ const fixBoxShadows = () => { } } +/** + * checks if the page contains a resume + * @return {Boolean} true if page contains resume + */ const isResume = () => { if (document.getElementsByTagName('page')[0]) return true; else return false; } +/** + * fixes resume + */ const fixResume = () => { if (!isResume()) return; getAllDOMElements(); diff --git a/src/renderReadMe.js b/src/renderReadMe.js deleted file mode 100755 index ea5740a..0000000 --- a/src/renderReadMe.js +++ /dev/null @@ -1,31 +0,0 @@ -const showdown = require('showdown'); -const converter = new showdown.Converter(); -const fs = require('fs'); -const path = require('path'); -const Mustache = require('mustache'); -const writeFile = require('write'); - -function readFileContent(fileName) { - const dir = path.join(__dirname, '../' + fileName); - return new Promise((res, rej) => { - fs.readFile(dir, 'utf8', (err, template) => { - if (err) rej(err); - else res(template); - }); - }); -} - -async function renderReadMe() { - const readmeContent = await readFileContent('README.md'); - const readmeHTML = converter.makeHtml(readmeContent); - const githubPagesTemplate = await readFileContent('resumes/views/githubPages.mustache'); - const readme = Mustache.render(githubPagesTemplate, { - content: readmeHTML - }); - writeFile('index.html', readme, err => { - if (err) console.log(err) - else console.log('Github pages index.html was successfully generated from README.'); - }); -} - -renderReadMe(); diff --git a/src/server.js b/src/server.js deleted file mode 100755 index 2c007eb..0000000 --- a/src/server.js +++ /dev/null @@ -1,60 +0,0 @@ -const path = require('path'); -const fs = require('fs'); -const person = require('./person.js'); -const express = require('express'); -const mustacheExpress = require('mustache-express'); -const request = require('request-promise'); -const port = 3000; - -let app = express(); -app.set('views', path.join(__dirname, '../resumes')); -app.engine('mustache', require('hogan-express')); -app.set('view engine', 'mustache'); -app.use(express.static(path.join(__dirname, '../public'))); -app.use(express.static(path.join(__dirname, '../node_modules'))); - -const dir = path.join(__dirname, '../resumes'); -const directories = getDirectories(dir); - -function getDirectories(srcpath) { - return fs.readdirSync(srcpath) - .filter(file => file.includes('resume-')) -} - -let resumes = []; -directories.forEach(dir => { - let name = dir.replace('resume-', ''); - resumes.push({ - path: dir, - name: name.replace('-', ' ') - }) -}); - -app.get('/', (req, res) => { - res.render('views/layout', { - partials: { - content: 'views/index' - }, - resumes: resumes - }); -}); - -app.get('/kill', () => process.exit()); - -for (let resume of directories) { - app.get('/' + resume, (req, res) => { - res.render('views/layout', { - partials: { - content: resume + '/index' - }, - person: person - }); - }); -} - -request.get('http://localhost:' + port + '/kill') - .catch(error => {}); - -setTimeout(() => { - app.listen(port, '0.0.0.0', () => console.log('Listening on localhost:' + port + '!')); -}, 500);