ADD electroshot
This commit is contained in:
parent
b6b33b6586
commit
3d2d9347ca
@ -33,6 +33,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'curly': ['error', 'multi-or-nest'],
|
'curly': ['error', 'multi-or-nest'],
|
||||||
|
'space-before-function-paren': ['error', 'always'],
|
||||||
'no-var': 'error'
|
'no-var': 'error'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ test/unit/coverage
|
|||||||
test/e2e/reports
|
test/e2e/reports
|
||||||
selenium-debug.log
|
selenium-debug.log
|
||||||
firefox_root/
|
firefox_root/
|
||||||
|
GeckoChildCrash*
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
MozCrashReason=MOZ_CRASH(Aborting on channel error.)
|
|
||||||
@ -1 +0,0 @@
|
|||||||
MozCrashReason=MOZ_CRASH(Aborting on channel error.)
|
|
||||||
@ -1 +0,0 @@
|
|||||||
MozCrashReason=MOZ_CRASH(Aborting on channel error.)
|
|
||||||
@ -1 +0,0 @@
|
|||||||
MozCrashReason=MOZ_CRASH(Aborting on channel error.)
|
|
||||||
1
electroshot-config.json
Normal file
1
electroshot-config.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
[{"url":"http://localhost:8080/#/resume-material-dark","delay":0,"selector":"","zoom-factor":1,"format":"pdf","quality":75,"user-agent":"","latency":null,"download":null,"upload":null,"css":"","js":"","debug":false,"root":"","pdf":{"pageSize":"A4","marginsType":1,"printBackground":true,"landscape":false},"size":{"width":2481,"height":3508},"out":"/home/s/workspace/pdf/resume-material-dark.pdf"}]
|
||||||
28
node/ResumeToPdf.js
Normal file
28
node/ResumeToPdf.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const Util = require('./Util');
|
||||||
|
const ResumeToPdf = {
|
||||||
|
/**
|
||||||
|
* generates electroshot command for screenshoting resume
|
||||||
|
* @param {string} resume resume name in URL
|
||||||
|
* @return {string} electroshot command
|
||||||
|
*/
|
||||||
|
electroshotScript: resume => {
|
||||||
|
const dir = path.join(__dirname, '../../pdf');
|
||||||
|
return 'electroshot localhost:8080/#/' + resume +
|
||||||
|
' 2481x3508 --pdf-margin none --format pdf --out ' + dir +
|
||||||
|
' --filename "' + resume + '.pdf" --pdf-background; ';
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* converts resumes to pdf
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
convert: async() => {
|
||||||
|
const directories = Util.getResumesFromDirectories();
|
||||||
|
let script = '';
|
||||||
|
directories.forEach(resume => (script += ResumeToPdf.electroshotScript(resume.path)));
|
||||||
|
script = script.substring(0, script.length - 2);
|
||||||
|
await Util.execBash(script);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ResumeToPdf;
|
||||||
15
node/Server.js
Normal file
15
node/Server.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const request = require('request-promise');
|
||||||
|
|
||||||
|
const PORT = 8080;
|
||||||
|
const Server = {
|
||||||
|
/**
|
||||||
|
* kills express app
|
||||||
|
*/
|
||||||
|
kill: () => {
|
||||||
|
request.get('http://localhost:' + PORT + '/kill')
|
||||||
|
.catch(error => {
|
||||||
|
if (error) return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
module.exports = Server;
|
||||||
83
node/Util.js
Normal file
83
node/Util.js
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
const path = require('path');
|
||||||
|
const writeFile = require('write');
|
||||||
|
const fs = require('fs');
|
||||||
|
const exec = require('child_process').exec;
|
||||||
|
|
||||||
|
const Util = {
|
||||||
|
/**
|
||||||
|
* gets directories starting with 'resume-'
|
||||||
|
* @return {[]}
|
||||||
|
*/
|
||||||
|
getDirectories: () => {
|
||||||
|
const srcpath = path.join(__dirname, '../src/components');
|
||||||
|
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: () => {
|
||||||
|
const directories = Util.getDirectories();
|
||||||
|
return directories
|
||||||
|
.filter(dir => dir.includes('resume-') && dir !== 'resume-XX')
|
||||||
|
.map(dir => {
|
||||||
|
let name = dir.replace('resume-', '');
|
||||||
|
return {
|
||||||
|
path: dir.replace('.vue', ''),
|
||||||
|
name: name.replace('-', ' ')
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* setTimeout as Promise
|
||||||
|
* @param {number} time time in ms
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
setTimeout: time => {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, time));
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* reads file of content
|
||||||
|
* @param {string} dir directory
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
readFileContent: dir => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(dir, 'utf8', (err, template) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
else resolve(template);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* writes content to given file
|
||||||
|
* @param {string} dir directory
|
||||||
|
* @param {string} content content of file
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
writeFile: async (dir, content) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
writeFile(dir, content, (err) => {
|
||||||
|
if (err) reject(err);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* executes command
|
||||||
|
* @param {string} script e.g. 'echo "Hello World"'
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
execBash: script => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
exec(script,
|
||||||
|
error => {
|
||||||
|
if (error) reject(error);
|
||||||
|
else resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Util;
|
||||||
2
node/app.js
Normal file
2
node/app.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
const ResumeToPdf = require('./ResumeToPdf');
|
||||||
|
ResumeToPdf.convert();
|
||||||
@ -1,23 +1,23 @@
|
|||||||
module.exports = function(grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.loadNpmTasks('grunt-exec');
|
grunt.loadNpmTasks('grunt-exec');
|
||||||
require('load-grunt-tasks')(grunt);
|
require('load-grunt-tasks')(grunt);
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
babel: {
|
babel: {
|
||||||
options: {
|
options: {
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
presets: ['es2015']
|
presets: ['es2015']
|
||||||
},
|
},
|
||||||
dist: {
|
dist: {
|
||||||
files: {
|
files: {
|
||||||
'public/js/gen/javascript.js': 'public/js/javascript.js'
|
'public/js/gen/javascript.js': 'public/js/javascript.js'
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
exec: {
|
|
||||||
less: 'node --harmony-async-await src/app.js less',
|
|
||||||
pdf: 'node --harmony-async-await src/app.js pdf'
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
},
|
||||||
|
exec: {
|
||||||
|
less: 'node --harmony-async-await src/app.js less',
|
||||||
|
pdf: 'node --harmony-async-await src/app.js pdf'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
grunt.registerTask('default', ['babel', 'exec:less', 'exec:pdf']);
|
grunt.registerTask('default', ['babel', 'exec:less', 'exec:pdf']);
|
||||||
};
|
};
|
||||||
|
|||||||
31
package.json
31
package.json
@ -7,6 +7,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "node build/dev-server.js",
|
"dev": "node build/dev-server.js",
|
||||||
"start": "node build/dev-server.js",
|
"start": "node build/dev-server.js",
|
||||||
|
"pdf": "node --harmony-async-await node/app.js",
|
||||||
"build": "node build/build.js",
|
"build": "node build/build.js",
|
||||||
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
|
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
|
||||||
"e2e": "node test/e2e/runner.js",
|
"e2e": "node test/e2e/runner.js",
|
||||||
@ -26,19 +27,25 @@
|
|||||||
"babel-core": "^6.22.1",
|
"babel-core": "^6.22.1",
|
||||||
"babel-eslint": "^7.1.1",
|
"babel-eslint": "^7.1.1",
|
||||||
"babel-loader": "^6.2.10",
|
"babel-loader": "^6.2.10",
|
||||||
|
"babel-plugin-istanbul": "^4.1.1",
|
||||||
"babel-plugin-transform-runtime": "^6.22.0",
|
"babel-plugin-transform-runtime": "^6.22.0",
|
||||||
"babel-preset-env": "^1.3.2",
|
"babel-preset-env": "^1.3.2",
|
||||||
"babel-preset-stage-2": "^6.22.0",
|
"babel-preset-stage-2": "^6.22.0",
|
||||||
"babel-register": "^6.22.0",
|
"babel-register": "^6.22.0",
|
||||||
|
"chai": "^3.5.0",
|
||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
|
"chromedriver": "^2.27.2",
|
||||||
"connect-history-api-fallback": "^1.3.0",
|
"connect-history-api-fallback": "^1.3.0",
|
||||||
"copy-webpack-plugin": "^4.0.1",
|
"copy-webpack-plugin": "^4.0.1",
|
||||||
|
"cross-env": "^4.0.0",
|
||||||
|
"cross-spawn": "^5.0.1",
|
||||||
"css-loader": "^0.28.0",
|
"css-loader": "^0.28.0",
|
||||||
|
"electroshot": "^1.3.0",
|
||||||
"eslint": "^3.19.0",
|
"eslint": "^3.19.0",
|
||||||
|
"eslint-config-standard": "^6.2.1",
|
||||||
"eslint-friendly-formatter": "^2.0.7",
|
"eslint-friendly-formatter": "^2.0.7",
|
||||||
"eslint-loader": "^1.7.1",
|
"eslint-loader": "^1.7.1",
|
||||||
"eslint-plugin-html": "^2.0.0",
|
"eslint-plugin-html": "^2.0.0",
|
||||||
"eslint-config-standard": "^6.2.1",
|
|
||||||
"eslint-plugin-promise": "^3.4.0",
|
"eslint-plugin-promise": "^3.4.0",
|
||||||
"eslint-plugin-standard": "^2.0.1",
|
"eslint-plugin-standard": "^2.0.1",
|
||||||
"eventsource-polyfill": "^0.9.6",
|
"eventsource-polyfill": "^0.9.6",
|
||||||
@ -48,8 +55,7 @@
|
|||||||
"friendly-errors-webpack-plugin": "^1.1.3",
|
"friendly-errors-webpack-plugin": "^1.1.3",
|
||||||
"html-webpack-plugin": "^2.28.0",
|
"html-webpack-plugin": "^2.28.0",
|
||||||
"http-proxy-middleware": "^0.17.3",
|
"http-proxy-middleware": "^0.17.3",
|
||||||
"webpack-bundle-analyzer": "^2.2.1",
|
"inject-loader": "^3.0.0",
|
||||||
"cross-env": "^4.0.0",
|
|
||||||
"karma": "^1.4.1",
|
"karma": "^1.4.1",
|
||||||
"karma-coverage": "^1.1.1",
|
"karma-coverage": "^1.1.1",
|
||||||
"karma-mocha": "^1.3.0",
|
"karma-mocha": "^1.3.0",
|
||||||
@ -61,27 +67,24 @@
|
|||||||
"karma-webpack": "^2.0.2",
|
"karma-webpack": "^2.0.2",
|
||||||
"lolex": "^1.5.2",
|
"lolex": "^1.5.2",
|
||||||
"mocha": "^3.2.0",
|
"mocha": "^3.2.0",
|
||||||
"chai": "^3.5.0",
|
|
||||||
"sinon": "^2.1.0",
|
|
||||||
"sinon-chai": "^2.8.0",
|
|
||||||
"inject-loader": "^3.0.0",
|
|
||||||
"babel-plugin-istanbul": "^4.1.1",
|
|
||||||
"phantomjs-prebuilt": "^2.1.14",
|
|
||||||
"chromedriver": "^2.27.2",
|
|
||||||
"cross-spawn": "^5.0.1",
|
|
||||||
"nightwatch": "^0.9.12",
|
"nightwatch": "^0.9.12",
|
||||||
"selenium-server": "^3.0.1",
|
|
||||||
"semver": "^5.3.0",
|
|
||||||
"shelljs": "^0.7.6",
|
|
||||||
"opn": "^4.0.2",
|
"opn": "^4.0.2",
|
||||||
"optimize-css-assets-webpack-plugin": "^1.3.0",
|
"optimize-css-assets-webpack-plugin": "^1.3.0",
|
||||||
"ora": "^1.2.0",
|
"ora": "^1.2.0",
|
||||||
|
"phantomjs-prebuilt": "^2.1.14",
|
||||||
|
"request-promise": "^4.2.1",
|
||||||
"rimraf": "^2.6.0",
|
"rimraf": "^2.6.0",
|
||||||
|
"selenium-server": "^3.0.1",
|
||||||
|
"semver": "^5.3.0",
|
||||||
|
"shelljs": "^0.7.6",
|
||||||
|
"sinon": "^2.1.0",
|
||||||
|
"sinon-chai": "^2.8.0",
|
||||||
"url-loader": "^0.5.8",
|
"url-loader": "^0.5.8",
|
||||||
"vue-loader": "^11.3.4",
|
"vue-loader": "^11.3.4",
|
||||||
"vue-style-loader": "^2.0.5",
|
"vue-style-loader": "^2.0.5",
|
||||||
"vue-template-compiler": "^2.2.6",
|
"vue-template-compiler": "^2.2.6",
|
||||||
"webpack": "^2.3.3",
|
"webpack": "^2.3.3",
|
||||||
|
"webpack-bundle-analyzer": "^2.2.1",
|
||||||
"webpack-dev-middleware": "^1.10.0",
|
"webpack-dev-middleware": "^1.10.0",
|
||||||
"webpack-hot-middleware": "^2.18.0",
|
"webpack-hot-middleware": "^2.18.0",
|
||||||
"webpack-merge": "^4.1.0"
|
"webpack-merge": "^4.1.0"
|
||||||
|
|||||||
@ -79,16 +79,16 @@
|
|||||||
<div class="section-headline">
|
<div class="section-headline">
|
||||||
Skills
|
Skills
|
||||||
</div>
|
</div>
|
||||||
<div class="skill" v-for="skill in person.skills">
|
<div class="skill" v-for="skill in person.skills">
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<span>{{skill.name}}</span>
|
<span>{{skill.name}}</span>
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div class="determinate" :style="'width: '+skill.level+'%;'">
|
<div class="determinate" :style="'width: '+skill.level+'%;'">
|
||||||
<i class="fa fa-circle"></i>
|
<i class="fa fa-circle"></i>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -99,23 +99,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-headline">Working experience</div>
|
<div class="section-headline">Working experience</div>
|
||||||
<div class="block" v-for="experience in person.experience">
|
<div class="block" v-for="experience in person.experience">
|
||||||
<div class="block-helper"></div>
|
<div class="block-helper"></div>
|
||||||
<div class="headline">{{experience.position}} - {{experience.company}}</h3>
|
<div class="headline">{{experience.position}} - {{experience.company}}</h3>
|
||||||
<div class="subheadline">{{experience.timeperiod}}</div>
|
<div class="subheadline">{{experience.timeperiod}}</div>
|
||||||
<p class="info">
|
|
||||||
{{experience.description}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="section-headline">Education</div>
|
|
||||||
<div class="block" v-for="education in person.education">
|
|
||||||
<div class="block-helper"></div>
|
|
||||||
<div class="headline">{{education.degree}}</div>
|
|
||||||
<p class="info">
|
<p class="info">
|
||||||
{{education.timeperiod}}, {{education.description}}
|
{{experience.description}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section-headline">Education</div>
|
||||||
|
<div class="block" v-for="education in person.education">
|
||||||
|
<div class="block-helper"></div>
|
||||||
|
<div class="headline">{{education.degree}}</div>
|
||||||
|
<p class="info">
|
||||||
|
{{education.timeperiod}}, {{education.description}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="clear:both;"></div>
|
<div style="clear:both;"></div>
|
||||||
@ -126,14 +126,16 @@
|
|||||||
import {
|
import {
|
||||||
PERSON
|
PERSON
|
||||||
} from '../person';
|
} from '../person';
|
||||||
export default {
|
|
||||||
name: 'hello',
|
import Vue from 'vue';
|
||||||
|
export default Vue.component('resume-material-dark', {
|
||||||
|
name: 'resume-material-dark',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
person: PERSON
|
person: PERSON
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
|||||||
@ -11,5 +11,7 @@ new Vue({
|
|||||||
el: '#app',
|
el: '#app',
|
||||||
router,
|
router,
|
||||||
template: '<App/>',
|
template: '<App/>',
|
||||||
components: { App }
|
components: {
|
||||||
|
App
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Router from 'vue-router';
|
import Router from 'vue-router';
|
||||||
import ResumeMaterialDark from '@/components/resume-material-dark';
|
import ResumeMaterialDark from '@/components/resume-material-dark';
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
export default new Router({
|
export default new Router({
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/resume-material-dark',
|
path: '/resume-material-dark',
|
||||||
name: 'ResumeMaterialDark',
|
name: 'resume-material-dark',
|
||||||
component: ResumeMaterialDark
|
component: ResumeMaterialDark
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user