Change how slides are served to be easier to edit

Serve up markdown based on filename in the data slide folder. Use the
index to find what file to use.

Removed ability to run code on slide on the server. Wasn't that useful
for how much of a pain it is.
This commit is contained in:
Buddy Sandidge 2015-04-27 23:08:20 -07:00
parent 17de8e7fb6
commit c5829b65ea
42 changed files with 55 additions and 194 deletions

125
bin/deck
View File

@ -3,10 +3,8 @@
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var _ = require('lodash');
var async = require('async');
var express = require('express');
var handlebars = require('handlebars');
@ -52,28 +50,16 @@ function index(req, res) {
app.get('/', index);
function serveIfExists(path) {
return function _serveIfExists(cb) {
fs.exists(path, function (exists) {
if (!exists) {
cb(null, null);
return;
}
fs.readFile(path, {encoding: 'utf8'}, cb);
});
};
}
app.get('/slides', function showHandler(req, res) {
fs.readdir(pathToFile('data', 'slide'), function (err, files) {
files.sort();
var jsonFiles = _.filter(files, function (file) {
return /^\d+\.json$/.test(file);
return /^\d+\.md$/.test(file);
});
res.send(_.map(jsonFiles, function (file) {
return {
id: parseInt(file.replace(/\.json$/, ''), 10)
id: parseInt(file.replace(/\.md$/, ''), 10)
};
}));
});
@ -85,107 +71,34 @@ app.get(/slide\/(\d+)/, function showHandler(req, res, next) {
return;
}
var slideId = req.params[0];
var slidePath = pathToFile('data', 'slide', slideId + '.json');
var slideIndex = req.params[0];
fs.exists(slidePath, function (exists) {
if (!exists) {
next();
return;
fs.readdir(pathToFile('data', 'slide'), function (err, files) {
if (err) {
return renderError(res, err);
}
fs.readFile(slidePath, {encoding: 'utf8'}, function (err, content) {
if (err) {
renderError(res, err);
return;
}
try {
var slide = JSON.parse(content);
} catch (err) {
renderError(res, err);
return;
}
async.parallel({
copy: serveIfExists(pathToFile('data', 'copy', slide.copy + '.md')),
code: serveIfExists(pathToFile('data', 'code', slide.code + '.js'))
}, function (err, slideContent) {
if (err) {
renderError(res, err);
return;
}
slideContent.id = parseInt(slideId, 10);
slideContent.title = slide.title || '';
res.send(slideContent);
});
files.sort();
var markdownFiles = _.filter(files, function (file) {
return /\.md$/.test(file);
});
});
});
app.get(/results\/([^\/]+)\/(\d\d)$/, function resultsHandler(req, res, next) {
var app = req.params[0];
var slideId = req.params[1];
var validApps = [
'node', 'phantomjs-1.9.8', 'phantomjs-2.0.0'
];
if (!_.contains(validApps, app)) {
next();
return;
}
var slidePath = pathToFile('data', 'slide', slideId + '.json');
fs.exists(slidePath, function (exists) {
if (!exists) {
if (slideIndex > markdownFiles.length) {
return next();
}
var noSlideError = new Error('No code for slide');
async.waterfall([
function (cb) {
fs.readFile(slidePath, {encoding: 'utf8'}, cb);
},
function (content, cb) {
try {
var slide = JSON.parse(content);
} catch (err) {
cb(err, null);
return;
}
cb(null, slide);
},
function (slide, cb) {
var codePath = pathToFile('data', 'code', slide.code + '.js');
fs.exists(codePath, function (exists) {
if (exists) {
cb(null, codePath);
} else {
cb(noSlideError);
}
});
},
function (path, cb) {
exec(app + ' ' + path, cb);
}
], function (err, stdout, stderr) {
if (err === noSlideError) {
next();
return;
}
var markdownFile = markdownFiles[slideIndex - 1];
var markdownPath = pathToFile('data', 'slide', markdownFile);
fs.readFile(markdownPath, {encoding: 'utf8'}, function (err, content) {
if (err) {
res.send({stdout: '', stderr: err.toString()});
return;
return renderError(res, err);
}
res.send({stdout: stdout, stderr: stderr});
});
res.send({
id: parseInt(slideIndex, 10),
copy: content
});
});
});
});

View File

@ -1,19 +0,0 @@
var page = require('webpage').create();
page.viewportSize = {width: 1280, height: 720};
page.open('https://html5test.com/', function() {
function doneLoading() {
var el = document.getElementById('loading');
return window.getComputedStyle(el).display === 'none';
}
function checkPage() {
if (page.evaluate(doneLoading)) {
page.render('static/html5.' + phantom.version.major + '.png');
console.log('created static/html5.' + phantom.version.major + '.png');
phantom.exit();
}
setTimeout(checkPage, 100);
}
checkPage();
});

View File

@ -1,5 +0,0 @@
# Use After Free
- Create webpage object in JavaScript
- Close webpage in JavaScript
- Do something with webpage in JavaScript

View File

@ -1 +0,0 @@
# JavaScript Runtime

View File

@ -1 +0,0 @@
# PhantomJS

View File

@ -1 +0,0 @@
# Testing

View File

@ -1 +0,0 @@
# Backbone's UMD

View File

@ -1 +0,0 @@
# This will error, not crash

View File

@ -1,3 +0,0 @@
{
"copy": "title"
}

View File

@ -1,3 +0,0 @@
{
"copy": "about"
}

View File

@ -1,3 +0,0 @@
{
"copy": "screen-shot"
}

View File

@ -1,4 +0,0 @@
{
"copy": "only-title",
"code": "phantom-webpage-screenshot"
}

View File

@ -1,3 +1,6 @@
# PhantomJS
```javascript
var page = require('webpage').create();
page.viewportSize = {width: 1280, height: 720};
@ -7,3 +10,4 @@ page.open('http://phantomjs.org', function() {
console.log('created phantomjs.png. ☮ out!');
phantom.exit();
});
```

View File

@ -1,3 +0,0 @@
{
"copy": "not-node"
}

View File

@ -1,3 +0,0 @@
{
"copy": "qt"
}

View File

@ -1,4 +0,0 @@
{
"copy": "use-after-free",
"code": "use-after-free"
}

View File

@ -1,3 +1,6 @@
# This will error, not crash
```javascript
var phantom = this.phantom || {exit: function () {}};
var foo = {bar: {baz: 123}};
delete foo.bar;
@ -7,3 +10,4 @@ try {
console.log(err);
phantom.exit();
}
```

View File

@ -1,3 +0,0 @@
{
"copy": "null-pointer"
}

View File

@ -1,4 +0,0 @@
{
"copy": "crash-explain",
"code": "crash"
}

View File

@ -1,3 +1,10 @@
# Use After Free
- Create webpage object in JavaScript
- Close webpage in JavaScript
- Do something with webpage in JavaScript
```javascript
var phantom = this.phantom || {exit: function () {}};
var page = require('webpage').create();
// code, code, code…
@ -6,3 +13,4 @@ page.open('about:blank', function () {
console.log('☮ out!');
phantom.exit();
});
```

View File

@ -1,4 +0,0 @@
{
"copy": "js-runtime",
"code": "prototypes"
}

View File

@ -1,3 +1,6 @@
# JavaScript Runtime
```javascript
var phantom = this.phantom || {exit: function () {}};
console.log('bind:', typeof Function.prototype.bind);
console.log('9 === parseInt("09"):', 9 === parseInt('09'));
@ -8,3 +11,4 @@ console.log('filter:', typeof Array.prototype.filter);
console.log('Object.create:', typeof Object.create);
phantom.exit();
```

View File

@ -1,3 +0,0 @@
{
"copy": "code-share"
}

View File

@ -1,4 +0,0 @@
{
"copy": "umd",
"code": "backbone-umd"
}

View File

@ -1,3 +1,6 @@
# Backbone's UMD
```javascript
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
@ -12,3 +15,4 @@
}(this, function(root, Backbone, _, $) {
// Backbone…
}));
```

View File

@ -1,4 +0,0 @@
{
"copy": "only-title",
"code": "backbone"
}

View File

@ -1,3 +1,6 @@
# PhantomJS
```javascript
var phantom = phantom || {exit: function () {}};
var _ = require('../../vendor/underscore/underscore');
phantom.injectJs('../../vendor/backbone/backbone.js');
@ -5,3 +8,4 @@ console.log(_.toString());
console.log(Backbone.View.toString());
phantom.exit();
//module.exports = Backbone;
```

View File

@ -1,4 +0,0 @@
{
"copy": "testing",
"code": "some-test"
}

View File

@ -1,5 +1,9 @@
# Testing
```javascript
describe('some test', function () {
it('→ some test case', function () {
expect(1 + 1).toBe(2);
});
});
```

View File

@ -1,4 +0,0 @@
{
"copy": "testing",
"code": "test"
}

View File

@ -1,3 +1,6 @@
# Testing
```javascript
phantom.injectJs('../../vendor/jasmine/lib/jasmine-core/jasmine.js');
var consoleFns = require('../../vendor/jasmine/lib/console/console.js');
var jasmine = jasmineRequire.core(jasmineRequire);
@ -13,3 +16,4 @@ jasmine.getEnv().addReporter(new jasmine.ConsoleReporter({
phantom.injectJs('./some-test.js');
jasmine.getEnv().execute();
```

View File

@ -1,3 +0,0 @@
{
"copy": "other-awesome"
}

View File

@ -1,3 +0,0 @@
{
"copy": "fin"
}