Selaa lähdekoodia

switch linter to eslint and fix errors (#135)

pull/137/head
Cian Butler 4 vuotta sitten
committed by GitHub
vanhempi
commit
6d9b6bb0a5
15 muutettua tiedostoa jossa 240 lisäystä ja 334 poistoa
  1. +4
    -0
      .eslintignore
  2. +47
    -0
      .eslintrc
  3. +15
    -14
      app.js
  4. +8
    -13
      bin/www
  5. +51
    -75
      lib/emailNewPosts.js
  6. +15
    -28
      lib/getLatestPosts.js
  7. +4
    -5
      lib/logger.js
  8. +1
    -2
      lib/smtpTransport.js
  9. +7
    -8
      lib/utils.js
  10. +9
    -9
      package.json
  11. +30
    -29
      routes/contact.js
  12. +7
    -8
      routes/contactForm.js
  13. +13
    -11
      routes/posts.js
  14. +12
    -16
      routes/regenerate.js
  15. +17
    -116
      yarn.lock

+ 4
- 0
.eslintignore Näytä tiedosto

@@ -0,0 +1,4 @@
node_modules/
themes
public
source

+ 47
- 0
.eslintrc Näytä tiedosto

@@ -0,0 +1,47 @@
{
"extends": "standard",
"env": {
"es6": true,
"jest": true,
"node": true
},
"globals": {
"GENTLY": true
},
"rules": {
"no-multi-spaces": 0,
"comma-dangle": [
"error",
"always-multiline"
],
"key-spacing": [
"error",
{
"multiLine": {
"beforeColon": false,
"afterColon": true
},
"align": {
"beforeColon": false,
"afterColon": true,
"on": "colon",
"mode": "strict"
}
}
],
"semi": [
"error",
"always"
],
"no-var": [
"error"
],
"prefer-const": [
"error",
{
"destructuring": "any",
"ignoreReadBeforeAssign": false
}
]
}
}

+ 15
- 14
app.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
require('dotenv-safe').load();

const express = require('express');
@@ -25,9 +24,9 @@ fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

const accessLogStream = FileStreamRotator.getStream({
date_format: 'YYYYMMDD',
filename: path.join(logDirectory, 'access-%DATE%.log'),
frequency: process.env.LOG_ROTATE || config.logRotationFreqency,
verbose: false
filename : path.join(logDirectory, 'access-%DATE%.log'),
frequency : process.env.LOG_ROTATE || config.logRotationFreqency,
verbose : false,
});

app.set('views', path.join(__dirname, 'views'));
@@ -36,9 +35,11 @@ app.set('view engine', 'ejs');
// Serve Static files generate from hexo
app.use(express.static(path.join(__dirname, 'public')));
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(morgan('combined', {
stream: accessLogStream
}));
app.use(
morgan('combined', {
stream: accessLogStream,
})
);
app.use(bodyParser.json());
app.use(compression());
app.use(bodyParser.urlencoded({ extended: false }));
@@ -61,26 +62,26 @@ const contactRoute = require('./routes/contact');
app.use(baseUrl, contactRoute);

// /api/fetchMeSomeTea 418 responce
app.get(path.join(baseUrl, 'fetchMeSomeTea'), function (req, res) {
res.status(418).json({message: "I'm a teapot", image: 'https://httpstatusdogs.com/img/418.jpg'});
app.get(path.join(baseUrl, 'fetchMeSomeTea'), (req, res) => {
res.status(418).json({ message: "I'm a teapot", image: 'https://httpstatusdogs.com/img/418.jpg' });
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
app.use((req, res, next) => {
const err = new Error('Not Found');
err.status = 404;
res.status(err.status).sendFile(path.join(__dirname, '/public/404.html'));
});

// error handlers
app.use(function (err, req, res, next) {
app.use((err, req, res, next) => {
if (app.get('env') === 'development') {
// development error handler
// will print stacktrace
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
error : err,
});
} else {
// production error handler
@@ -90,8 +91,8 @@ app.use(function (err, req, res, next) {

// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500).sendFile(path.join(__dirname, '/public/404.html'));
app.use(({ status }, req, res, next) => {
res.status(status || 500).sendFile(path.join(__dirname, '/public/404.html'));
});

emailNewPosts();


+ 8
- 13
bin/www Näytä tiedosto

@@ -1,5 +1,4 @@
#!/usr/bin/env node
'use strict';
/**
* Module dependencies.
*/
@@ -33,7 +32,7 @@ server.on('listening', onListening);
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
function normalizePort (val) {
const port = parseInt(val, 10);

if (isNaN(port)) {
@@ -53,23 +52,21 @@ function normalizePort(val) {
* Event listener for HTTP server "error" event.
*/

function onError(error) {
function onError (error) {
if (error.syscall !== 'listen') {
throw error;
}

const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
const bind = typeof port === 'string' ? `Pipe ${port}` : `Port ${port}`;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
console.error(`${bind} requires elevated privileges`);
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
console.error(`${bind} is already in use`);
process.exit(1);
break;
default:
@@ -81,10 +78,8 @@ function onError(error) {
* Event listener for HTTP server "listening" event.
*/

function onListening() {
function onListening () {
const addr = server.address();
const bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
const bind = typeof addr === 'string' ? `pipe ${addr}` : `port ${addr.port}`;
debug(`Listening on ${bind}`);
}

+ 51
- 75
lib/emailNewPosts.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const fs = require('fs');
const path = require('path');
const async = require('async');
@@ -21,57 +20,42 @@ const postsDirectory = path.join(process.cwd(), 'source/_posts');
const emailLogFilename = path.join(process.cwd(), 'logs/email_update_log');
const mailingListFilename = path.join(process.cwd(), 'mailing_list');

function sendEmail (emailData, address, callback) {
let mailOptions = {
from: emailData.senderName + ' <' + config.email.auth.user + '>',
to: address,
subject: '[' + config.mailsubject + '] ' + emailData.subject,
text: emailData.body
function sendEmail ({ senderName, subject, body }, address, callback) {
const mailOptions = {
from : `${senderName} <${config.email.auth.user}>`,
to : address,
subject: `[${config.mailsubject}] ${subject}`,
text : body,
};
smtpTransport.sendMail(mailOptions, function (err) {
smtpTransport.sendMail(mailOptions, err => {
if (err) {
logger.error(err);
logger.error('Unable to send email "' + emailData.subject + '" to recipient: ' + address);
logger.error(`Unable to send email "${subject}" to recipient: ${address}`);
}
callback(err);
});
}

function sendEmails (addresses, emailData, callback) {
async.each(addresses, sendEmail.bind(null, emailData), function (err) {
async.each(addresses, sendEmail.bind(null, emailData), err => {
if (err) {
logger.error('Failed to send email "' + emailData.subject + '" to some recipients.');
logger.error(`Failed to send email "${emailData.subject}" to some recipients.`);
} else {
logger.info('Email update for "' + emailData.subject + '" succeeded.');
logger.info(`Email update for "${emailData.subject}" succeeded.`);
}
callback(err);
});
}

function getEmailBody (postData) {
let title = postData.frontMatter.title;
let date = new Date(postData.frontMatter.date);
let author = postData.frontMatter.author;
let tags = (postData.frontMatter.tags || []).map(function (tag) {
return '#' + tag;
}).join(', ');
const plainTextContents = (
postData.contents
.split(/<[\w\W]+>/).join('') // strip html
.split(/!\[[\w\W]*]\([\w\W]*\)/).join('') // strip images
);
let directory = moment(date).format('YYYY/MM/DD');
let permalink = config.siteroot + '/' + path.join(directory, postData.slug);
return wrap80(
title + '\n' +
moment(date).format('DD/MM/YYYY') + '\n' +
'tags: ' + tags + '\n' +
'posted by ' + author + '\n' +
'\n' +
'See full post at: ' + permalink + '\n' +
'\n' +
plainTextContents
);
function getEmailBody ({ frontMatter, contents, slug }) {
const title = frontMatter.title;
const date = new Date(frontMatter.date);
const author = frontMatter.author;
const tags = (frontMatter.tags || []).map(tag => `#${tag}`).join(', ');
const plainTextContents = contents.split(/<[\w\W]+>/).join('').split(/!\[[\w\W]*]\([\w\W]*\)/).join(''); // strip html // strip images
const directory = moment(date).format('YYYY/MM/DD');
const permalink = `${config.siteroot}/${path.join(directory, slug)}`;
return wrap80(`${title}\n${moment(date).format('DD/MM/YYYY')}\ntags: ${tags}\nposted by ${author}\n\nSee full post at: ${permalink}\n\n${plainTextContents}`);
}

function bail (err, callback) {
@@ -85,64 +69,56 @@ function bail (err, callback) {

function emailNewPosts (callback) {
logger.info('Sending email update(s) for any new posts...');
readFileAsArray(mailingListFilename, function (err, addresses) {
readFileAsArray(mailingListFilename, (err, addresses) => {
if (err) {
return bail('Unable to read file: ' + mailingListFilename, callback);
return bail(`Unable to read file: ${mailingListFilename}`, callback);
}
let realAddresses = addresses.map(function (a) {
return a.trim();
}).filter(function (a) {
// barebones email address validation
return /^.+@.+$/.test(a);
});
readFileAsArray(emailLogFilename, function (err, log) {
const realAddresses = addresses.map(a => a.trim()).filter(a => /^.+@.+$/.test(a)); // barebones email address validation
readFileAsArray(emailLogFilename, (err, log) => {
if (err) {
return bail('Unable to read file: ' + emailLogFilename, callback);
return bail(`Unable to read file: ${emailLogFilename}`, callback);
}
// if date doesn't exist, choose beginning of (unix) time
let lastUpdated = new Date(log[0] || 0);
fs.readdir(postsDirectory, function (err, filenames) {
const lastUpdated = new Date(log[0] || 0);
fs.readdir(postsDirectory, (err, filenames) => {
if (err) {
return bail('Unable to read directory ' + postsDirectory, callback);
return bail(`Unable to read directory ${postsDirectory}`, callback);
}
let lastCheckedDirectory = new Date();
let postFilenames = filenames.filter(function (filename) {
return filename.indexOf('.md') !== -1;
}).map(function (filename) {
return path.join(postsDirectory, filename);
});
async.map(postFilenames, readFileAsString, function (err, posts) {
const lastCheckedDirectory = new Date();
const postFilenames = filenames.filter(filename => filename.indexOf('.md') !== -1).map(filename => path.join(postsDirectory, filename));
async.map(postFilenames, readFileAsString, (err, posts) => {
if (err) {
return bail('Unable to read files in directory: ' + postsDirectory, callback);
return bail(`Unable to read files in directory: ${postsDirectory}`, callback);
}
let emailDataList = posts.map(function (post, index) {
return {
const emailDataList = posts
.map((post, index) => ({
// cut out front matter and surrounding whitespace
contents: post.replace(/---[\w\W]*---/, '').trim(),

frontMatter: parseFrontMatter(post),

// get filename without parent directory and without '.md'
slug: postFilenames[index].split('/').slice(-1)[0].slice(0, -3)
};
}).filter(function (postData) {
let date = postData.frontMatter.date;
return new Date(date) > lastUpdated;
}).map(function (postData) {
return {
subject: postData.frontMatter.title,
body: getEmailBody(postData),
senderName: postData.frontMatter.author
};
});
async.each(emailDataList, sendEmails.bind(null, realAddresses), function (err) {
slug: postFilenames[index].split('/').slice(-1)[0].slice(0, -3),
}))
.filter(({ frontMatter }) => {
const date = frontMatter.date;
return new Date(date) > lastUpdated;
})
.map(postData => ({
subject : postData.frontMatter.title,
body : getEmailBody(postData),
senderName: postData.frontMatter.author,
}));
async.each(emailDataList, sendEmails.bind(null, realAddresses), err => {
if (err) {
logger.error('Failed to send some emails.');
} else if (emailDataList.length) {
logger.info('Email update(s) successfully sent to ' + realAddresses.length + ' recipients.');
logger.info(`Email update(s) successfully sent to ${realAddresses.length} recipients.`);
} else {
logger.info('No email updates were necessary.');
}
let updatedEmailLog = [lastCheckedDirectory.toISOString()].concat(log);
writeArrayToFile(emailLogFilename, updatedEmailLog, function (err) {
const updatedEmailLog = [lastCheckedDirectory.toISOString()].concat(log);
writeArrayToFile(emailLogFilename, updatedEmailLog, err => {
if (err) {
return bail('Unable to update email log after send.', callback);
}


+ 15
- 28
lib/getLatestPosts.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const fs = require('fs');
const path = require('path');
const async = require('async');
@@ -20,47 +19,37 @@ function getLatestPosts (options, callback) {
options.limit = options.limit || 10;
options.include = options.include || [];

fs.readdir(postsDirectory, function (err, filenames) {
fs.readdir(postsDirectory, (err, filenames) => {
if (err) {
return callback(err);
}

const postFilenames = filenames.filter(function (filename) {
return filename.indexOf('.md') !== -1;
});
const fullpaths = postFilenames.map(function (filename) {
return path.join(postsDirectory, filename);
});
const slugs = postFilenames.map(function (filename) {
return filename.slice(0, -3);
});
const postFilenames = filenames.filter(filename => filename.indexOf('.md') !== -1);
const fullpaths = postFilenames.map(filename => path.join(postsDirectory, filename));
const slugs = postFilenames.map(filename => filename.slice(0, -3));

async.map(fullpaths, readFileAsString, function (err, posts) {
async.map(fullpaths, readFileAsString, (err, posts) => {
if (err) {
return callback(err);
}

const postDataList = posts.map(function (post, index) {
const postDataList = posts.map((post, index) => {
const frontMatter = parseFrontMatter(post);
const directory = moment(frontMatter.date).format('YYYY/MM/DD');
const permalink = config.siteroot + '/' + path.join(directory, slugs[index]);
const thumbnail = frontMatter.thumbnail ? permalink + '/' + frontMatter.thumbnail : void 0;
const permalink = `${config.siteroot}/${path.join(directory, slugs[index])}`;
const thumbnail = frontMatter.thumbnail ? `${permalink}/${frontMatter.thumbnail}` : void 0;

const data = {
title: frontMatter.title,
date: frontMatter.date,
title : frontMatter.title,
date : frontMatter.date,
author: frontMatter.author,
tags: frontMatter.tags,
permalink: permalink,
thumbnail: thumbnail
tags : frontMatter.tags,
permalink,
thumbnail,
};

// strip out images
const content = (
frontMatter._content
.split(/!\[[\w\W]*]\([\w\W]*\)/)
.join('')
);
const content = frontMatter._content.split(/!\[[\w\W]*]\([\w\W]*\)/).join('');

if (options.include.indexOf('content') !== -1) {
data.content = content.split('<!-- more -->').join('');
@@ -73,9 +62,7 @@ function getLatestPosts (options, callback) {
return data;
});

const selectedPostData = orderBy(postDataList, function (data) {
return new Date(data.date);
}).reverse().slice(options.offset, options.offset + options.limit);
const selectedPostData = orderBy(postDataList, ({ date }) => new Date(date)).reverse().slice(options.offset, options.offset + options.limit);

callback(null, selectedPostData);
});


+ 4
- 5
lib/logger.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const FileStreamRotator = require('file-stream-rotator');
const logger = require('winston');
const yaml = require('js-yaml');
@@ -13,13 +12,13 @@ fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

const winstonLogStream = FileStreamRotator.getStream({
date_format: 'YYYYMMDD',
filename: path.join(logDirectory, 'winston-%DATE%.log'),
frequency: config.logRotationFreqency,
verbose: false
filename : path.join(logDirectory, 'winston-%DATE%.log'),
frequency : config.logRotationFreqency,
verbose : false,
});

logger.add(logger.transports.File, {
stream: winstonLogStream
stream: winstonLogStream,
});

module.exports = logger;

+ 1
- 2
lib/smtpTransport.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const nodemailer = require('nodemailer');

const fs = require('fs');
@@ -7,7 +6,7 @@ const yaml = require('js-yaml');
const configFile = fs.readFileSync('./_config.yml', 'utf8');
const config = yaml.safeLoad(configFile).server;

let email = config.email;
const email = config.email;
email.host = process.env.SMTP_HOST || config.email.host;
email.port = process.env.SMTP_PORT || config.email.port;
email.secure = process.env.SMTP_SECURE || config.email.secure;


+ 7
- 8
lib/utils.js Näytä tiedosto

@@ -1,8 +1,7 @@
'use strict';
const fs = require('fs');

function readFileAsString (filename, callback) {
fs.readFile(filename, function (err, buffer) {
fs.readFile(filename, (err, buffer) => {
if (err) {
return callback(err);
}
@@ -11,7 +10,7 @@ function readFileAsString (filename, callback) {
}

function readFileAsArray (filename, callback) {
readFileAsString(filename, function (err, contents) {
readFileAsString(filename, (err, contents) => {
if (err) {
return callback(err);
}
@@ -24,7 +23,7 @@ function writeArrayToFile (filename, array, callback) {
}

function orderBy (array, mapper) {
return array.slice().sort(function (a, b) {
return array.slice().sort((a, b) => {
const aPrime = mapper(a);
const bPrime = mapper(b);
if (aPrime < bPrime) {
@@ -38,8 +37,8 @@ function orderBy (array, mapper) {
}

module.exports = {
readFileAsString: readFileAsString,
readFileAsArray: readFileAsArray,
writeArrayToFile: writeArrayToFile,
orderBy: orderBy
readFileAsString,
readFileAsArray,
writeArrayToFile,
orderBy,
};

+ 9
- 9
package.json Näytä tiedosto

@@ -14,7 +14,6 @@
"scripts": {
"server": "node ./bin/www",
"test": "npm run lint && npm run generate",
"lint": "./node_modules/.bin/semistandard",
"theme": "git submodule init && git submodule update --remote",
"postinstall": "npm run theme && cd themes/redbrick-theme && npm install",
"generate": "hexo g",
@@ -24,20 +23,16 @@
"post": "hexo new post",
"start": "npm run generate && node ./bin/www ",
"fresh": "hexo clean",
"regenerate": "npm run postinstall && npm run clean && hexo g"
"regenerate": "npm run postinstall && hexo clean && hexo g",
"fix": "eslint . --fix",
"lint": "eslint ."
},
"hexo": {
"version": "3.2.2"
},
"semistandard": {
"ignore": [
"themes"
]
},
"dependencies": {
"async": "^2.0.1",
"body-parser": "~1.15.1",
"bower": "^1.7.9",
"compression": "^1.6.2",
"cookie-parser": "~1.4.3",
"debug": "^2.4.4",
@@ -71,9 +66,14 @@
"morgan": "~1.7.0",
"nodemailer": "^2.5.0",
"recaptcha2": "^1.0.8",
"semistandard": "^9.0.0",
"serve-favicon": "^2.3.0",
"winston": "^2.2.0",
"wordwrap": "^1.0.0"
},
"devDependencies": {
"eslint": "3.16.1",
"eslint-config-standard": "6.2.1",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "2.1.0"
}
}

+ 30
- 29
routes/contact.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const express = require('express');
const router = express.Router();
const yaml = require('js-yaml');
@@ -10,38 +9,40 @@ const smtpTransport = require('../lib/smtpTransport');
const configFile = fs.readFileSync('./_config.yml', 'utf8');
const config = yaml.safeLoad(configFile).server;
const recaptcha = new ReCAPTCHA({
siteKey: process.env.RECAPTCHA_SITE_KEY || config.recaptcha.siteKey,
secretKey: process.env.RECAPTCHA_SECRET_KEY || config.recaptcha.secretKey
siteKey : process.env.RECAPTCHA_SITE_KEY || config.recaptcha.siteKey,
secretKey: process.env.RECAPTCHA_SECRET_KEY || config.recaptcha.secretKey,
});

// contact form email sender
router.get('/contact', function (req, res) {
recaptcha.validate(req.query.recaptcha).then(function () {
// validated and secure
let to = req.query.to;
let mailOptions = {
from: req.query.name + ' <' + req.query.email + '>',
to: to + '@redbrick.dcu.ie',
subject: '[Sent from the website] ' + req.query.subject,
text: req.query.text,
replyTo: req.query.email
};
smtpTransport.sendMail(mailOptions, function (error, info) {
if (error) {
logger.error(error);
res.json({formSubmit: true, errors: 'error in SMTP Server'});
} else {
logger.info(info);
res.json({formSubmit: true, errors: null});
}
router.get('/contact', ({ query }, res) => {
recaptcha
.validate(query.recaptcha)
.then(() => {
// validated and secure
const to = query.to;
const mailOptions = {
from : `${query.name} <${query.email}>`,
to : `${to}@redbrick.dcu.ie`,
subject: `[Sent from the website] ${query.subject}`,
text : query.text,
replyTo: query.email,
};
smtpTransport.sendMail(mailOptions, (error, info) => {
if (error) {
logger.error(error);
res.json({ formSubmit: true, errors: 'error in SMTP Server' });
} else {
logger.info(info);
res.json({ formSubmit: true, errors: null });
}
});
})
.catch(errorCodes => {
// invalid
console.log('error in captcha', errorCodes);
logger.error(errorCodes);
res.json({ formSubmit: false, errors: recaptcha.translateErrors(errorCodes) });
});
})
.catch(function (errorCodes) {
// invalid
console.log('error in captcha', errorCodes);
logger.error(errorCodes);
res.json({formSubmit: false, errors: recaptcha.translateErrors(errorCodes)});
});
});

module.exports = router;

+ 7
- 8
routes/contactForm.js Näytä tiedosto

@@ -1,21 +1,20 @@
'use strict';
const express = require('express');
const path = require('path');
const router = express.Router();
const logger = require('../lib/logger');

// dynamically create contact page
router.get('*', function (req, res) {
let options = {
root: path.join(__dirname, '..', '/public/'),
router.get('*', (req, res) => {
const options = {
root : path.join(__dirname, '..', '/public/'),
dotfiles: 'deny',
headers: {
headers : {
'x-timestamp': Date.now(),
'x-sent': true
}
'x-sent' : true,
},
};
const fileName = 'about/contact/contact.html';
res.sendFile(fileName, options, function (err) {
res.sendFile(fileName, options, err => {
if (err) {
logger.error(err);
res.status(err.status).end();


+ 13
- 11
routes/posts.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const express = require('express');
const router = express.Router();
const getLatestPosts = require('../lib/getLatestPosts');
@@ -9,17 +8,20 @@ const getLatestPosts = require('../lib/getLatestPosts');
* - limit (0-indexed maximum number of returned results - default 10)
* - include (comma-separated list possibly including 'content,excerpt')
*/
router.get('/posts', function (req, res) {
getLatestPosts({
offset: parseInt(req.query.offset),
limit: parseInt(req.query.limit),
include: (req.query.include || '').split(',')
}, function (err, posts) {
if (err) {
return res.status(500).json(err).end();
router.get('/posts', ({ query }, res) => {
getLatestPosts(
{
offset : parseInt(query.offset),
limit : parseInt(query.limit),
include: (query.include || '').split(','),
},
(err, posts) => {
if (err) {
return res.status(500).json(err).end();
}
res.json(posts).end();
}
res.json(posts).end();
});
);
});

module.exports = router;

+ 12
- 16
routes/regenerate.js Näytä tiedosto

@@ -1,4 +1,3 @@
'use strict';
const express = require('express');
const path = require('path');
const fs = require('fs');
@@ -12,15 +11,15 @@ const emailNewPosts = require('../lib/emailNewPosts');
* request means you can easily run this from a browser window.
* also, normal users won't be hitting this endpoint.
*/
router.get('/regenerate', function (req, res) {
if (req.query.token !== process.env.SECRET_API_TOKEN) {
router.get('/regenerate', ({ query }, res) => {
if (query.token !== process.env.SECRET_API_TOKEN) {
return res.status(401).end('Bad token.');
}

/* Using wx write flag to combine check and write into one atomic operation;
* This prevents concurrent initiation of hexo child processes.
*/
fs.writeFile('hexo_lock', 'hexo_lock', { flag: 'wx' }, function (err) {
fs.writeFile('hexo_lock', 'hexo_lock', { flag: 'wx' }, err => {
if (err) {
if (err.code === 'EEXIST') {
return res.status(423).end('Site generation already in progress. Please wait.');
@@ -32,42 +31,39 @@ router.get('/regenerate', function (req, res) {
res.end('Re-generating static site...');
logger.info('Pulling from Github');
const gitPull = spawn('git', ['pull', 'origin', 'master']);
gitPull.stdout.on('data', function (buffer) {
gitPull.stdout.on('data', buffer => {
logger.info(buffer.toString());
});
gitPull.stderr.on('data', function (buffer) {
gitPull.stderr.on('data', buffer => {
logger.error(buffer.toString());
});

logger.info('Pulling Submodules');
const gitModule = spawn('git', ['submodule', 'update', '--remote']);
gitModule.stdout.on('data', function (buffer) {
gitModule.stdout.on('data', buffer => {
logger.info(buffer.toString());
});
gitModule.stderr.on('data', function (buffer) {
gitModule.stderr.on('data', buffer => {
logger.error(buffer.toString());
});

logger.info('Generating hexo static files...');
let generateOk = true;
const hexoGenerate = spawn(
path.join(process.cwd(), 'node_modules/.bin/hexo'),
['generate']
);
hexoGenerate.stdout.on('data', function (buffer) {
const hexoGenerate = spawn(path.join(process.cwd(), 'node_modules/.bin/hexo'), ['generate']);
hexoGenerate.stdout.on('data', buffer => {
logger.info(buffer.toString());
});
hexoGenerate.stderr.on('data', function (buffer) {
hexoGenerate.stderr.on('data', buffer => {
logger.error(buffer.toString());
generateOk = false;
});
hexoGenerate.on('close', function () {
hexoGenerate.on('close', () => {
if (!generateOk) {
fs.unlink('hexo_lock'); // async delete
return logger.error('Hexo generation failed.');
}
logger.log('Hexo generation was successful.');
emailNewPosts(function (err) {
emailNewPosts(err => {
if (err) {
logger.error(err);
}


+ 17
- 116
yarn.lock Näytä tiedosto

@@ -342,10 +342,6 @@ boom@2.x.x:
dependencies:
hoek "2.x.x"

bower@^1.7.9:
version "1.8.0"
resolved "https://registry.yarnpkg.com/bower/-/bower-1.8.0.tgz#55dbebef0ad9155382d9e9d3e497c1372345b44a"

brace-expansion@^1.0.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9"
@@ -824,10 +820,6 @@ dateformat@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17"

debug-log@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"

debug@*, debug@2.6.1, debug@^2.1.1, debug@^2.4.4:
version "2.6.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351"
@@ -916,17 +908,6 @@ deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"

deglob@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/deglob/-/deglob-2.1.0.tgz#4d44abe16ef32c779b4972bd141a80325029a14a"
dependencies:
find-root "^1.0.0"
glob "^7.0.5"
ignore "^3.0.9"
pkg-config "^1.1.0"
run-parallel "^1.1.2"
uniq "^1.0.1"

del@^2.0.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
@@ -1196,36 +1177,21 @@ escope@^3.6.0:
esrecurse "^4.1.0"
estraverse "^4.1.1"

eslint-config-semistandard@7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/eslint-config-semistandard/-/eslint-config-semistandard-7.0.0.tgz#f803493f56a5172f7f59c35ae648360b41f2ff71"

eslint-config-standard-jsx@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-3.2.0.tgz#c240e26ed919a11a42aa4de8059472b38268d620"

eslint-config-standard@6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-6.2.1.tgz#d3a68aafc7191639e7ee441e7348739026354292"

eslint-plugin-promise@~3.4.0:
version "3.4.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.4.2.tgz#1be2793eafe2d18b5b123b8136c269f804fe7122"

eslint-plugin-react@~6.8.0:
version "6.8.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.8.0.tgz#741ab5438a094532e5ce1bbb935d6832356f492d"
dependencies:
doctrine "^1.2.2"
jsx-ast-utils "^1.3.4"
eslint-plugin-promise@3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz#78fbb6ffe047201627569e85a6c5373af2a68fca"

eslint-plugin-standard@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-2.0.1.tgz#3589699ff9c917f2c25f76a916687f641c369ff3"
eslint-plugin-standard@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-2.1.0.tgz#b7ca4b6d2cf3d60e33fa8ffc8384a5d1aac6c268"

eslint@~3.11.1:
version "3.11.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.11.1.tgz#408be581041385cba947cd8d1cd2227782b55dbf"
eslint@3.16.1:
version "3.16.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.16.1.tgz#9bc31fc7341692cf772e80607508f67d711c5609"
dependencies:
babel-code-frame "^6.16.0"
chalk "^1.1.3"
@@ -1233,12 +1199,12 @@ eslint@~3.11.1:
debug "^2.1.1"
doctrine "^1.2.2"
escope "^3.6.0"
espree "^3.3.1"
espree "^3.4.0"
estraverse "^4.2.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
glob "^7.0.3"
globals "^9.2.0"
globals "^9.14.0"
ignore "^3.2.0"
imurmurhash "^0.1.4"
inquirer "^0.12.0"
@@ -1257,12 +1223,12 @@ eslint@~3.11.1:
require-uncached "^1.0.2"
shelljs "^0.7.5"
strip-bom "^3.0.0"
strip-json-comments "~1.0.1"
strip-json-comments "~2.0.1"
table "^3.7.8"
text-table "~0.2.0"
user-home "^2.0.0"

espree@^3.3.1:
espree@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d"
dependencies:
@@ -1546,10 +1512,6 @@ finalhandler@1.0.0:
statuses "~1.3.1"
unpipe "~1.0.0"

find-root@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.0.0.tgz#962ff211aab25c6520feeeb8d6287f8f6e95807a"

find-up@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
@@ -1688,10 +1650,6 @@ get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"

get-stdin@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"

get-stream@^2.0.0, get-stream@^2.2.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de"
@@ -1802,7 +1760,7 @@ global@~4.3.0:
min-document "^2.19.0"
process "~0.5.1"

globals@^9.2.0:
globals@^9.14.0:
version "9.16.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80"

@@ -2209,13 +2167,6 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"

home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"

hosted-git-info@^2.1.4:
version "2.2.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5"
@@ -2292,7 +2243,7 @@ iconv-lite@0.4.15:
version "0.4.15"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb"

ignore@^3.0.9, ignore@^3.2.0:
ignore@^3.2.0:
version "3.2.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.4.tgz#4055e03596729a8fabe45a43c100ad5ed815c4e8"

@@ -2827,12 +2778,6 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.3.6"

jsx-ast-utils@^1.3.4:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.0.tgz#5afe38868f56bc8cc7aeaef0100ba8c75bd12591"
dependencies:
object-assign "^4.1.0"

kew@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b"
@@ -3544,7 +3489,7 @@ os-locale@^1.4.0:
dependencies:
lcid "^1.0.0"

os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
os-tmpdir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"

@@ -3681,14 +3626,6 @@ pixelmatch@^4.0.0:
dependencies:
pngjs "^3.0.0"

pkg-config@^1.0.1, pkg-config@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pkg-config/-/pkg-config-1.1.1.tgz#557ef22d73da3c8837107766c52eadabde298fe4"
dependencies:
debug-log "^1.0.0"
find-root "^1.0.0"
xtend "^4.0.1"

pluralize@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
@@ -4042,10 +3979,6 @@ run-async@^0.1.0:
dependencies:
once "^1.3.0"

run-parallel@^1.1.2:
version "1.1.6"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039"

rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
@@ -4068,19 +4001,6 @@ seek-bzip@^1.0.3:
dependencies:
commander "~2.8.1"

semistandard@^9.0.0:
version "9.2.1"
resolved "https://registry.yarnpkg.com/semistandard/-/semistandard-9.2.1.tgz#65d0e99deb63225250b8a993cec8174b54593a9d"
dependencies:
eslint "~3.11.1"
eslint-config-semistandard "7.0.0"
eslint-config-standard "6.2.1"
eslint-config-standard-jsx "3.2.0"
eslint-plugin-promise "~3.4.0"
eslint-plugin-react "~6.8.0"
eslint-plugin-standard "~2.0.1"
standard-engine "~5.3.0"

semver-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-1.0.0.tgz#92a4969065f9c70c694753d55248fc68f8f652c9"
@@ -4262,17 +4182,6 @@ stack-trace@0.0.x:
version "0.0.9"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.9.tgz#a8f6eaeca90674c333e7c43953f275b451510695"

standard-engine@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-5.3.0.tgz#fa254d7e068d92de8019d9945d420286d1ce04c9"
dependencies:
deglob "^2.1.0"
find-root "^1.0.0"
get-stdin "^5.0.1"
home-or-tmp "^2.0.0"
minimist "^1.1.0"
pkg-config "^1.0.1"

stat-mode@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.2.2.tgz#e6c80b623123d7d80cf132ce538f346289072502"
@@ -4375,10 +4284,6 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"

strip-json-comments@~1.0.1:
version "1.0.4"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"

strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -4672,10 +4577,6 @@ underscore@^1.8.3:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"

uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"

unique-stream@^2.0.2:
version "2.2.1"
resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.2.1.tgz#5aa003cfbe94c5ff866c4e7d668bb1c4dbadb369"
@@ -4937,7 +4838,7 @@ xmlbuilder@^4.1.0:
dependencies:
lodash "^4.0.0"

"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"



Ladataan…
Peruuta
Tallenna