Modernize codebase

parent 3b1268aa
Pipeline #774 passed with stage
in 9 seconds
module.exports = {
root: true,
plugins: ['prettier'],
extends: ['airbnb-base', 'prettier'],
env: {
node: true,
es6: true,
},
parser: 'babel-eslint',
rules: {
'prettier/prettier': [
'error',
{
singleQuote: true,
trailingComma: 'all',
semi: false,
},
],
'no-console': 0,
'no-unused-vars': 1, // only warning
'prefer-destructuring': 0,
'no-restricted-syntax': 0,
'no-underscore-dangle': 0,
'no-nested-ternary': 0,
},
globals: {
process: true,
},
}
{
// JSHint Default Configuration File (as on JSHint website)
// See http://jshint.com/docs/ for more details
"maxerr" : 50, // {int} Maximum error before stopping
// Enforcing
"camelcase" : true, // true: Identifiers must be in camelCase
"curly" : false, // true: Require {} for every new block or scope
"nonew" : true, // true: Prohibit use of constructors for side-effects (without assignment)
"quotmark" : "single", // Quotation mark consistency
"strict" : false, // true: Requires all functions run in ES5 Strict Mode
"maxparams" : 5, // {int} Max number of formal params allowed per function
"maxdepth" : 5, // {int} Max depth of nested blocks (within functions)
"maxstatements" : 40, // {int} Max number statements per function
"maxcomplexity" : 20, // {int} Max cyclomatic complexity per function
"maxlen" : 120, // {int} Max number of characters per line
// Relaxing
"asi" : true, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"esversion" : 6, // {int} Specify the ECMAScript version to which the code must adhere.
"funcscope" : true, // true: Tolerate defining variables inside control statements
// Environments
"browser" : false, // Web Browser (window, document, etc)
"devel" : true, // Development/debugging (alert, confirm, etc)
"jquery" : false, // jQuery
"mocha" : true, // Mocha
"node" : true, // Node.js
// Custom Globals
"globals" : {} // additional predefined global variables
}
This diff is collapsed.
......@@ -15,6 +15,7 @@
"filendir": "^1.0.0",
"highlight.js": "^9.2.0",
"jsesc": "^1.0.0",
"latinize": "^0.4.0",
"marked": "^0.3.5",
"mkdirp": "^0.5.1",
"moment": "^2.12.0",
......@@ -30,8 +31,15 @@
"walk": "^2.3.9"
},
"devDependencies": {
"babel-eslint": "^8.0.3",
"eslint": "^4.12.1",
"eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-prettier": "^2.3.1",
"istanbul": "^0.4.2",
"mocha": "^2.3.4",
"prettier": "^1.8.2",
"unit.js": "^2.0.0"
},
"optionalDependencies": {
......
'use strict';
/*
* This file specifies whole configuration of sitegin.
* It reads config file from content/config.toml it also parses command-line
* arguments. CLI args take precedence over config options
*/
var Git = require('nodegit');
var cli = require('cli');
var fs = require('fs');
var path = require('path');
var toml = require('toml');
var options = cli.parse({
noserver: ['n', 'Dont run server'],
port: ['p', 'Port on which server should run', 'number', 1337],
uiport: [null, 'BrowserSync UI port', 'number', 'port+1'],
httpsonly: [null, 'Converts all http://ok1kvk.cz links to https'],
httponly: [null, 'Converts all https://ok1kvk.cz links to http'],
contentdir: [null, 'Allows to specify arbitrary content directory.', 'string', 'content'],
themedir: [null, 'Allows to specify arbitrary content directory.', 'string', 'theme'],
builddir: [null, 'Allows to specify arbitrary content directory.', 'string', null],
staticdir: [null, 'Allows to specify arbitrary directory for static files.', 'string', 'static'],
baseurl: [null, 'BaseURL without trailing /', 'string', ''],
nowatch: [null, 'Disable watching for changes'],
debugarticle: [null, 'Article for which extra information should be printed out. Full file path '+
'relative to contentdir (Ex. articles/2010/hello-word.md)','string', null]
});
const cli = require('cli')
const fs = require('fs')
const path = require('path')
const toml = require('toml')
module.exports = function() {
console.log('Build step: Config');
var builddir = 'build';
if(options.builddir)
builddir = options.builddir;
else if(!options.noserver) builddir = 'build-debug';
const options = cli.parse({
noserver: ['n', 'Dont run server'],
port: ['p', 'Port on which server should run', 'number', 1337],
uiport: [null, 'BrowserSync UI port', 'number', 'port+1'],
httpsonly: [null, 'Converts all http://ok1kvk.cz links to https'],
httponly: [null, 'Converts all https://ok1kvk.cz links to http'],
contentdir: [
null,
'Allows to specify arbitrary content directory.',
'string',
'content',
],
themedir: [
null,
'Allows to specify arbitrary content directory.',
'string',
'theme',
],
builddir: [
null,
'Allows to specify arbitrary content directory.',
'string',
null,
],
staticdir: [
null,
'Allows to specify arbitrary directory for static files.',
'string',
'static',
],
baseurl: [null, 'BaseURL without trailing /', 'string', ''],
nowatch: [null, 'Disable watching for changes'],
debugarticle: [
null,
'Article for which extra information should be printed out. Full file path ' +
'relative to contentdir (Ex. articles/2010/hello-word.md)',
'string',
null,
],
})
if(options.uiport == 'port+1') {
options.uiport = options.port+1;
module.exports = () => {
console.log('Build step: Config')
let builddir = 'build'
if (options.builddir) ({ builddir } = options)
else if (!options.noserver) builddir = 'build-debug'
if (options.uiport === 'port+1') {
options.uiport = options.port + 1
}
return new Promise(function(resolve, reject) {
var config = {
options: options,
builddir: builddir,
return new Promise(resolve => {
const config = {
options,
builddir,
sourceDir: options.contentdir,
staticDir: options.staticdir,
themeDir: options.themedir,
articlesLocation: 'articles',
redirectsLocation: 'redirects',
linksPerPage: 6
};
var configFile = path.join(config.sourceDir, 'config.toml');
fs.readFile(configFile,'utf-8',function(err,data) {
if(err) {
console.log('Failed to read configuration from '+configFile);
linksPerPage: 6,
}
const configFile = path.join(config.sourceDir, 'config.toml')
fs.readFile(configFile, 'utf-8', (err, data_) => {
if (err) {
console.log(`Failed to read configuration from ${configFile}`)
console.log('Using defaults')
return resolve({config: config});
resolve({ config })
return
}
const data = toml.parse(data_)
for (const attr of Object.keys(config)) {
data[attr] = config[attr]
}
data = toml.parse(data);
for(let attr in config) { data[attr] = config[attr]; }
resolve({config: data});
resolve({ config: data })
})
})
}
module.exports.watch = !options.noserver;
module.exports.themeDir = options.themedir;
module.exports.watch = !options.noserver
module.exports.themeDir = options.themedir
module.exports.options = options
This diff is collapsed.
'use strict';
const youtube = require('./utils/youtube.js')
const path = require('path')
const url = require('url')
const jobs = require('./jobs')
const { rewriteURL } = require('./urls')
var youtube = require('./utils/youtube.js');
var path = require('path');
var url = require('url');
var jobs = require('./jobs');
var rewriteURL = require('./urls').rewriteURL;
const generateImage = (file, targetDir, width, height) =>
jobs.run('imageResizer', file, targetDir, width, height)
var generateImage = function(file, targetDir, width, height) {
return jobs.run('imageResizer', file, targetDir, width, height);
}
var paramInHrefParser = function(href) {
var sepIndex = href.indexOf(' =');
var ret = {
href: href,
options: {}
const paramInHrefParser = href => {
const sepIndex = href.indexOf(' =')
const ret = {
href,
options: {},
}
if(sepIndex < 0) {
return ret;
} else {
ret.href = href.substr(0, sepIndex);
var options = href.substr(sepIndex+2);
options = options // split by ',' but not '\,'
.replace('a,','\u0007')
.split(',')
.map(function(e) {return e.replace('\u0007','a,')});
options.forEach(function(option) {
var index = option.indexOf('=');
if(index < 0) {
ret.options[option] = true;
} else {
var key = option.substr(0,index);
var value = option.substr(index+1);
ret.options[key] = value;
}
});
return ret;
if (sepIndex < 0) {
return ret
}
ret.href = href.substr(0, sepIndex)
let options = href.substr(sepIndex + 2)
options = options // split by ',' but not '\,'
.replace('a,', '\u0007')
.split(',')
.map(e => e.replace('\u0007', 'a,'))
options.forEach(option => {
const index = option.indexOf('=')
if (index < 0) {
ret.options[option] = true
} else {
const key = option.substr(0, index)
const value = option.substr(index + 1)
ret.options[key] = value
}
})
return ret
}
var renderYoutube = function(href, options) {
var info = youtube.info(href);
let out = '<div class="video-container"><div class="videodiv">';
out += '<iframe src="https://www.youtube.com/embed/'+info.videoid+
'?modestbranding&start='+info.time+'" frameborder="0" allowfullscreen></iframe>'
const renderYoutube = href => {
const info = youtube.info(href)
let out = '<div class="video-container"><div class="videodiv">'
out += `${`<iframe src="https://www.youtube.com/embed/${info.videoid}` +
'?modestbranding&start='}${
info.time
}" frameborder="0" allowfullscreen></iframe>`
out += '</div></div>'
return out;
return out
}
module.exports = function(href, title, text, curFile, cfg) {
var parsed = paramInHrefParser(href);
href = parsed.href;
var options = parsed.options;
module.exports = (href_, title, text, curFile_, cfg) => {
let curFile = curFile_
const parsed = paramInHrefParser(href_)
const { href } = parsed
const { options } = parsed
for(let option in options) {
if( !options.hasOwnProperty(option) ) continue;
if(option.match(/x[0-9]+/) || option.match(/[0-9]+x[0-9]*/)) { // 123x or x123 or 123x123
options.size = option.split('x');
if(options.size !== undefined) {
if(options.size[0].length > 0) {
options.width = options.size[0];
for (const option of Object.keys(options)) {
if (option.match(/x[0-9]+/) || option.match(/[0-9]+x[0-9]*/)) {
// 123x or x123 or 123x123
options.size = option.split('x')
if (options.size !== undefined) {
if (options.size[0].length > 0) {
options.width = options.size[0]
}
if(options.size.length > 1 && options.size[1].length > 0) {
options.height = options.size[1];
if (options.size.length > 1 && options.size[1].length > 0) {
options.height = options.size[1]
}
}
}
}
if(youtube.isVideo(href)) {
return renderYoutube(href, options);
} else {
var genHTML = function(file, norel) {
var rel = file;
if(!norel) path.relative(process.cwd(),file);
var out = '<img src="' + rel + '" alt="' + text + '"';
if(options.width) {
out += ' width="' + options.width + '"';
}
if(options.height) {
out += ' height="' + options.height + '"';
}
if (title) {
out += ' title="' + title + '"';
}
if (youtube.isVideo(href)) {
return renderYoutube(href, options)
}
const genHTML = (file, norel) => {
const rel = file
if (!norel) path.relative(process.cwd(), file)
out += '>';
if(!options.nolightbox) { // if lightbox
var a = '<a href="'+href+'"';
a += ' data-lightbox="group"';
a += ' data-title="' + text + '"';
a += '>';
out = a+out+'</a>';
}
return out;
let out = `<img src="${rel}" alt="${text}"`
if (options.width) {
out += ` width="${options.width}"`
}
if (options.height) {
out += ` height="${options.height}"`
}
if (title) {
out += ` title="${title}"`
}
var parsedHref = url.parse(href);
if(parsedHref.host) {
return genHTML(href, true);
} else if(path.isAbsolute(href)) {
return genHTML(href);
} else {
curFile = curFile.replace(/\.md$/,'');
var targetDir = rewriteURL(curFile);
targetDir = path.resolve(cfg.builddir, targetDir);
var absSrc = path.resolve(cfg.staticDir, curFile, href);
if(!options.size) options.size = [];
var w = options.size[0],
h = options.size[1];
if(w === '') w = undefined; else w = Number(w);
if(h === '') h = undefined; else h = Number(h);
if(w === undefined && h === undefined) w = 512;
var file = generateImage(absSrc, targetDir, w, h);
return genHTML(file);
out += '>'
if (!options.nolightbox) {
// if lightbox
let a = `<a href="${href}"`
a += ' data-lightbox="group"'
a += ` data-title="${text}"`
a += '>'
out = `${a + out}</a>`
}
return out
}
const parsedHref = url.parse(href)
if (parsedHref.host) {
return genHTML(href, true)
} else if (path.isAbsolute(href)) {
return genHTML(href)
}
curFile = curFile.replace(/\.md$/, '')
let targetDir = rewriteURL(curFile)
targetDir = path.resolve(cfg.builddir, targetDir)
const absSrc = path.resolve(cfg.staticDir, curFile, href)
if (!options.size) options.size = []
let w = options.size[0]
let h = options.size[1]
if (w === '') w = undefined
else w = Number(w)
if (h === '') h = undefined
else h = Number(h)
if (w === undefined && h === undefined) w = 512
const file = generateImage(absSrc, targetDir, w, h)
return genHTML(file)
}
module.exports._test = {
paramInHrefParser: paramInHrefParser
paramInHrefParser,
}
'use strict';
var lwip;
var path = require('path');
try {lwip = require('lwip');}
catch(e) {
let lwip
const path = require('path')
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, import/no-unresolved
lwip = require('lwip')
} catch (e) {
lwip = null
console.log('WARNING! LWIP is not installed - image minification won\'t work.');
console.log('You can try to run npm install.');
console.log('If it does not help try to make npm install lwip work.');
console.log("WARNING! LWIP is not installed - image minification won't work.")
console.log('You can try to run npm install.')
console.log('If it does not help try to make npm install lwip work.')
}
var mkdirp = require('mkdirp');
var path = require('path');
const mkdirp = require('mkdirp')
module.exports = function(file, targetDir, width, height) {
if(lwip && (width || height)) {
let tmp = path.basename(file).split('.');
tmp.splice(-1,1);
let base = tmp.join('.');
let targetFile = base+'_thumb_';
if(width) targetFile += width;
targetFile += 'x';
if(height) targetFile += height;
targetFile += '.png';
let ret = targetFile;
targetFile = path.resolve(targetDir,targetFile);
lwip.open(file, function(err, image) {
module.exports = function imageResizer(file, targetDir, _width, _height) {
let width = _width
let height = _height
if (lwip && (width || height)) {
const tmp = path.basename(file).split('.')
tmp.splice(-1, 1)
const base = tmp.join('.')
let targetFile = `${base}_thumb_`
if (width) targetFile += width
targetFile += 'x'
if (height) targetFile += height
targetFile += '.png'
const ret = targetFile
targetFile = path.resolve(targetDir, targetFile)
lwip.open(file, (err, image) => {
function doResize() {
mkdirp(path.dirname(targetFile), function() {
image.batch()
.resize(width, height)
.writeFile(targetFile, function(err) {
if(err) console.log(err);
});
mkdirp(path.dirname(targetFile), () => {
image
.batch()
.resize(width, height)
.writeFile(targetFile, e => {
if (e) console.log(e)
})
})
}
if(err) return console.log(err);
var w = image.width(), h = image.height();
if(width && height) {
doResize();
} else if(height) {
if(h > height) {
width = Math.round(height*w/h);
doResize();
if (err) {
console.log(err)
return
}
const w = image.width()
const h = image.height()
if (width && height) {
doResize()
} else if (height) {
if (h > height) {
width = Math.round(height * w / h)
doResize()
}
} else if(width) {
if(w > width) {
height = Math.round(width*h/w);
doResize();
} else if (width) {
if (w > width) {
height = Math.round(width * h / w)
doResize()
}
} else {
console.log(new Error('Panic! Code should never get here!'));
console.log(new Error('Panic! Code should never get here!'))
}
})
return ret;
} else {
return path.basename(file);
return ret
}
return path.basename(file)
}
'use strict';
const syntaxError = require('syntax-error')
const fs = require('fs')
const chokidar = require('chokidar')
var syntaxError = require('syntax-error');
var fs = require('fs');
var chokidar = require('chokidar');
var eventEmitter = new (require('events').EventEmitter)();
var jobList = {};
var watchers = [];
const jobList = {}
let watchers = []
function JobError(message, name) {
Error.captureStackTrace(this, JobError);
this.name = name+'Error';
this.message = message;
return this;
Error.captureStackTrace(this, JobError)
this.name = `${name}Error`
this.message = message
return this
}
var onReload = function() {}
var requireError = function(e, jobName, module, reject) {
if(e instanceof SyntaxError) {
console.log(module+': '+e);
var resolved = require.resolve(module);
fs.readFile(resolved, 'utf8', function(err, content) {
console.log(syntaxError(content,resolved));
reject(new JobError('Failed to register job '+jobName+' (SyntaxError)','Require'))
let onReload = () => {}
const requireError = (e, jobName, module, reject) => {
if (e instanceof SyntaxError) {
console.log(`${module}: ${e}`)
const resolved = require.resolve(module)
fs.readFile(resolved, 'utf8', (err, content) => {
console.log(syntaxError(content, resolved))
reject(
new JobError(
`Failed to register job ${jobName} (SyntaxError)`,
'Require',
),
)
})
} else {
if(e.code === 'MODULE_NOT_FOUND')
console.log(e.toString());
reject(new JobError('Failed to register job '+jobName+' ('+e+')','Require'))
if (e.code === 'MODULE_NOT_FOUND') console.log(e.toString())
reject(new JobError(`Failed to register job ${jobName} (${e})`, 'Require'))
}
}
var jobs = {
register: function(jobName, module, watch) {
return new Promise(function(resolve, reject) {
if(watch === undefined) watch = true;
if(jobList[jobName] !== undefined) {
return Promise.reject(
new JobError('Job '+jobName+' is already registered', 'JobAlreadyRegistered')
const jobs = {
register(jobName, module, watch = true) {
return new Promise((resolve, reject) => {
if (jobList[jobName] !== undefined) {
Promise.reject(
new JobError(
`Job ${jobName} is already registered`,
'JobAlreadyRegistered',
),
)
return
}
var f;
let f
try {
f = require(module);
} catch(e) {
requireError(e, jobName, module, reject);
return;
// eslint-disable-next-line global-require, import/no-dynamic-require
f = require(module)
} catch (e) {
requireError(e, jobName, module, reject)
return
}
if(typeof f !== 'function')
throw new JobError('Module "'+module+'" for job "'+jobName+'" does not export function');
if (typeof f !== 'function')
throw new JobError(
`Module "${module}" for job "${jobName}" does not export function`,
)
jobList[jobName] = {
f: f,
module: module
};
if(watch) jobs.watch(jobName);
resolve();
});
f,
module,
}
if (watch) jobs.watch(jobName)
resolve()
})
},
reload: function(jobName) {
var module = jobList[jobName].module;
delete require.cache[require.resolve(module)];
reload(jobName) {
const { module } = jobList[jobName]
delete require.cache[require.resolve(module)]
return new Promise(function(resolve, reject) {
return new Promise((resolve, reject) => {