Permalink
Browse files

more options for caching, prettier frontend, refresh all link,

safe cache as .png in git-like folders
  • Loading branch information...
juliangruber committed Jan 16, 2013
1 parent b087611 commit 145dcab8be51513c2ab4345c94fc9dcdd3165dec
Showing with 95 additions and 92 deletions.
  1. +2 −2 README.md
  2. +6 −3 bin/review.js
  3. 0 cache/.gitkeep
  4. +7 −4 example/cache.js
  5. +3 −1 lib/review.js
  6. +8 −8 lib/snapshot.js
  7. +3 −1 package.json
  8. +37 −59 public/app.js
  9. +18 −5 public/style.css
  10. +11 −9 views/index.jade
View
@@ -85,9 +85,9 @@ Configure the resolutions to use for screenshots. Defaults to `["1200x800"]`
PhantomJS will wait for `x` milliseconds after loading the page before it takes the screenshot, so you can make sure your page is completely loaded. Defaults to `0`.
### review#cache(x)
### review#cache({ dir : 'directory', expires : 60 })
Cache rendered snapshots for `x` seconds.
Cache rendered snapshots for `expires` seconds in `dir`.
### review#listen(port)
View
@@ -4,7 +4,9 @@ var review = require('..')
var optimist = require('optimist')
var argv = optimist
.usage('Host review\nUsage: $0 [options]\n\nExample: review --sites=\'{"google":"http://google.com"}\'')
.usage(
'Host review\nUsage: $0 [options]\n\n'+
'Examples: review --sites=\'{"google":"http://google.com"}\' --cache=\'{"dir":"cache","expires":100}\'')
.demand(['sites'])
.describe('port', 'Port to listen on')
@@ -26,8 +28,8 @@ var argv = optimist
.default('wait', 0)
.alias('w', 'wait')
.describe('cache', 'Cache snapshots for x seconds')
.default('cache', false)
.describe('cache', 'Cache snapshots for x milliseconds')
.default('cache', 'false')
.alias('c', 'cache')
.describe('help', 'Print usage instructions')
@@ -41,6 +43,7 @@ review()
.sites(JSON.parse(argv.sites))
.resolutions(JSON.parse(argv.resolutions))
.wait(argv.wait)
.cache(argv.cache? { dir : __dirname + '/cache', expires : argv.cache } : false)
.listen(argv.port, function () {
console.log('-> Review on port ' + argv.port)
})
View
No changes.
View
@@ -1,10 +1,13 @@
var review = require('..')
review()
.title('Cached Review')
.sites({ localhost : 'http://localhost:3000/' })
.resolutions(['1280x1024', '800x600'])
.cache(5)
.title('Review')
.sites({ 'github' : 'https://github.com/' })
.resolutions(['1440x900', '1200x800', '640x480'])
.cache({
dir : __dirname + '/cache/',
expires : 86400
})
.listen(5000, function () {
console.log('-> Review on port 5000')
})
View
@@ -1,4 +1,5 @@
var express = require('express')
var span = require('span')
module.exports = review
@@ -101,7 +102,8 @@ function review () {
sites : _sites,
resolutions : _resolutions,
wait : wait,
cache : cache
cache : cache,
expires : cache? span(cache.expires * 1000) : null
})
}
})
View
@@ -4,6 +4,7 @@ var fs = require('fs')
var path = require('path')
var EventEmitter = require('events').EventEmitter
var crypto = require('crypto')
var mkdirp = require('mkdirp')
var app = module.exports = express()
@@ -27,7 +28,6 @@ app.cache = function (_cache) {
*/
var script = __dirname + '/../script/rasterize.js'
var cacheDir = path.join(__dirname, '/../cache/')
/**
* cache handling
@@ -55,15 +55,15 @@ app.get('/:url/:resolution/:wait', function (req, res, next) {
.update(req.params['resolution'])
.digest('hex')
var dir = hash.slice(0, 2)
var filename = cacheDir + dir + '/' + hash
var dir = path.join(cache.dir, hash.slice(0, 2))
var filename = path.join(dir, hash + '.png')
function createCash () {
function createCache () {
caching[hash] = true
snapshot(req.params, function (err, rasterized) {
if (err) return caching[hash] = false, next(err)
fs.mkdir(cacheDir + dir, function () {
mkdirp(dir, function () {
fs.writeFile(filename, rasterized, function (err) {
caching[hash] = false
if (err) return next(err)
@@ -76,12 +76,12 @@ app.get('/:url/:resolution/:wait', function (req, res, next) {
}
// refresh
if ('refresh' in req.query) return createCash()
if ('refresh' in req.query) return createCache()
// choose action based on cache file stat
fs.stat(filename, function (err, stat) {
// serve cache
if (!err && stat.mtime >= (Date.now() - cache * 1000)) {
if (!err && stat.mtime >= (Date.now() - cache.expires * 1000)) {
return res.sendfile(filename)
}
@@ -90,7 +90,7 @@ app.get('/:url/:resolution/:wait', function (req, res, next) {
return caches.once(hash, res.sendfile.bind(res, filename))
}
createCash()
createCache()
})
})
View
@@ -20,6 +20,8 @@
"dependencies": {
"optimist": "~0.3.5",
"jade": "~0.28.1",
"express": "~3.0.6"
"express": "~3.0.6",
"mkdirp": "~0.3.4",
"span": "0.0.5"
}
}
View
@@ -1,71 +1,49 @@
var images = Array.prototype.slice.apply(document.querySelectorAll('img'))
var info = document.querySelector('#info')
var loading = document.querySelector('#loading')
var loaded = 0
var reloads = 0
var allLoaded = false
var links = Array.prototype.slice.apply(document.querySelectorAll('.refresh'))
var refreshAll = document.querySelector('.refresh-all')
/**
* loading indicator
* refresh all
*/
var iv = setInterval(function () {
if (loaded == images.length) return clearInterval(iv)
loading.innerHTML += '.'
if (loading.innerHTML == '....') loading.innerHTML = ''
}, 500)
info.innerHTML = '0 / ' + images.length + ' loaded'
refreshAll.addEventListener('click', function () {
var msg = "You're about to refresh " + images.length + " snapshots. Are you sure?"
if (images.length > 10 && !confirm(msg)) return
images.forEach(refresh)
})
/**
* reload
* refresh
*/
images.forEach(function (image) {
image.addEventListener('click', function () {
reloads++
// show gray placeholder in same dimensions
var oldSrc = image.src + ''
var oldHeight = image.height
image.src = '/empty.jpg'
image.style.height = oldHeight + 'px'
setTimeout(function () {
// force reload
var newSrc = oldSrc
newSrc += newSrc.match(/\?/)
? '&reload'
: '?reload'
image.src = newSrc
function onLoad () {
image.style.height = 'auto'
image.removeEventListener('load', onLoad)
}
image.addEventListener('load', onLoad)
}, 500)
links.forEach(function (link) {
link.addEventListener('click', function () {
refresh(link.parentNode.nextSibling.childNodes[0])
})
})
/**
* loading status
*/
images.forEach(function (image) {
image.addEventListener('load', function () {
if (allLoaded) return
loaded++
info.innerHTML = (loaded-reloads) + ' / ' + images.length + ' loaded'
if ((loaded-reloads) == images.length) {
allLoaded = true
info.innerHTML = 'all loaded'
loading.innerHTML = ''
function refresh (image) {
// show gray placeholder in same dimensions
var oldSrc = image.src + ''
var oldHeight = image.height
image.src = '/empty.jpg'
image.style.height = oldHeight + 'px'
setTimeout(function () {
// force refresh
var newSrc = oldSrc
newSrc += newSrc.match(/\?/)
? '&refresh'
: '?refresh'
image.src = newSrc
function onLoad () {
image.style.height = 'auto'
image.removeEventListener('load', onLoad)
}
})
})
image.addEventListener('load', onLoad)
}, 500)
}
View
@@ -3,20 +3,33 @@ body {
padding : 20px 40px;
}
a {
cursor : pointer;
}
a.refresh-all {
color : lightblue;
font-weight : bold;
margin-left : 0.5ex;
position : relative;
top : -0.2ex;
}
a.refresh {
position : relative;
top : -0.2ex;
color : lightblue;
}
h1 span, h2 span {
color : lightgray;
}
h1 span {
font-weight : normal;
font-size : 40%;
color : lightblue;
}
#info {
margin-left : 1em;
}
img {
box-shadow: 2px 2px 25px rgba(0, 0, 0, 0.80);
-moz-box-shadow: 2px 2px 25px rgba(0, 0, 0, 0.80);
View
@@ -5,21 +5,23 @@ html
link(rel='stylesheet',href='/style.css')
body
h1= title
span#info be patient
span#loading
a.refresh-all
if cache
p Serving potentially cached screenshots. Click an image to refresh.
p Images are cached for #{expires}. Refresh at will.
else
p Be patient, images will start appearing after #{wait/1000}s. Click an image to refresh.
if wait
p Be patient, images will start appearing after #{wait/1000}s. Refresh at will.
each url, title in sites
each resolution in resolutions
h2= title
span #{resolution.name}
img(
src='/snapshot/#{url}/#{resolution.name}/#{wait}',
style="width:#{resolution.width}; max-width:#{resolution.maxWidth}"
)
span #{resolution.name}
a.refresh
a(href="#{decodeURIComponent(url)}",target="_blank")
img(
src='/snapshot/#{url}/#{resolution.name}/#{wait}',
style="width:#{resolution.width}; max-width:#{resolution.maxWidth}"
)
script(src="/app.js")

0 comments on commit 145dcab

Please sign in to comment.