summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2012-07-05 16:52:59 +0200
committerTrygve Laugstøl <trygvis@inamo.no>2012-07-05 16:52:59 +0200
commitc43cb51021be5fc4c33c7de1635f045108773497 (patch)
treef0925021e6cbd59f4bff7a3aef6c78febdc3aa7c
parentc8246e7eaf81e08b6481122f577d29a1a0cacab1 (diff)
downloadcollection-json-explorer-c43cb51021be5fc4c33c7de1635f045108773497.tar.gz
collection-json-explorer-c43cb51021be5fc4c33c7de1635f045108773497.tar.bz2
collection-json-explorer-c43cb51021be5fc4c33c7de1635f045108773497.tar.xz
collection-json-explorer-c43cb51021be5fc4c33c7de1635f045108773497.zip
o Implementing support for deleting items.
-rw-r--r--app.js1
-rw-r--r--public/javascripts/gui.js11
-rw-r--r--routes/index.js91
-rw-r--r--views/data.jade116
4 files changed, 144 insertions, 75 deletions
diff --git a/app.js b/app.js
index 3558bca..875cea8 100644
--- a/app.js
+++ b/app.js
@@ -26,6 +26,7 @@ app.configure('development', function(){
app.get('/', routes.index);
app.get('/render', routes.render);
+app.get('/delete', routes.delete);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
diff --git a/public/javascripts/gui.js b/public/javascripts/gui.js
index f235f6d..e69de29 100644
--- a/public/javascripts/gui.js
+++ b/public/javascripts/gui.js
@@ -1,11 +0,0 @@
-$(document).ready(function() {
- /* Needed if the static top navbar is being used.
- * Add data-offset='60' to <body> as well.
- var offset = 60;
- $('#navbar ul li a').click(function(event) {
- event.preventDefault();
- $($(this).attr('href'))[0].scrollIntoView();
- scrollBy(0, -offset);
- });
- */
-});
diff --git a/routes/index.js b/routes/index.js
index e84f15d..73f82ab 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -1,34 +1,70 @@
var collection_json = require('collection_json')
, http = require('http')
, url = require('url')
+ , util = require('util')
, _ = require('underscore');
function urlgenerator(req) {
var host = req.headers.host;
return {
- render: function(u) {
- return 'http://' + host + '/render?url=' + encodeURIComponent(u)}
+ render: function(u) { return 'http://' + host + '/render?url=' + encodeURIComponent(u)},
+ delete: function(referer, u) { return 'http://' + host + '/delete?referer=' + encodeURIComponent(referer) + '&url=' + encodeURIComponent(u)},
+ isUrl: function(u) {
+ try {
+ var x = url.parse(u);
+ return _.isString(x.protocol) && _.isString(x.host) && _.isString(path);
+ }
+ catch(e) {
+ return false;
+ }
+ }
};
}
-exports.index = function(req, res){
+function sendErr(req, res, err, httpResponse) {
+ res.render('data', {
+ urlgenerator: urlgenerator(req),
+ url: req.query.url, referer: req.query.referer,
+ err: err,
+ httpResponse: httpResponse
+ });
+}
+
+exports.index = function(req, res) {
res.render('index', {
host: req.headers.host
});
};
-exports.render = function(req, res) {
- function sendErr(req, err, statusCode, status, headers, rawBody) {
+exports.delete = function(req, res) {
+ var options = url.parse(req.query.url, false);
+ options.method = 'DELETE';
+ function done(message, httpResponse) {
res.render('data', {
urlgenerator: urlgenerator(req),
- url: req.query.url,
- err: err,
- statusCode: statusCode,
- status: status,
- headers: headers,
- rawBody: rawBody
+ url: req.query.url, referer: req.query.referer,
+ httpResponse: httpResponse
});
}
+ http.request(options, function(httpResponse) {
+ httpResponse.setEncoding('utf8');
+ var body = '';
+ httpResponse.on('data', function (chunk) {
+ body += chunk;
+ }).on('end', function (chunk) {
+ done(undefined, {
+ statusCode: httpResponse.statusCode,
+ status: '',
+ headers: httpResponse.headers,
+ body: body
+ });
+ });
+ }).on('error', function(e) {
+ done(util.inspect(e));
+ }).end();
+}
+
+exports.render = function(req, res) {
var u = url.parse(req.query.url, true);
var params = _.reduce(req.query, function(q, value, key) {
if(!key.match(/^param-/)) {
@@ -38,39 +74,25 @@ exports.render = function(req, res) {
return q;
}, {});
u.query = _.extend({}, u.query, params);
- fetchCollection(url.format(u), function(err, statusCode, status, headers, body) {
+ fetchCollection(url.format(u), function(err, httpResponse) {
if(err) {
- sendErr(req, err, statusCode, status, headers, body);
+ sendErr(req, res, err, httpResponse);
return;
}
var parsedBody;
try {
- parsedBody = JSON.parse(body);
+ parsedBody = JSON.parse(httpResponse.body);
} catch(e) {
- sendErr(req, 'Unable to parse JSON: ' + e, statusCode, status, headers, body);
+ sendErr(req, res, 'Unable to parse JSON: ' + e, httpResponse);
return;
}
var collection = collection_json.fromObject(parsedBody).collection;
- var isUrl = function(u) {
- try {
- var x = url.parse(u);
- return _.isString(x.protocol) && _.isString(x.host) && _.isString(path);
- }
- catch(e) {
- return false;
- }
- };
res.render('data', {
- isUrl: isUrl,
urlgenerator: urlgenerator(req),
- url: req.query.url,
+ url: req.query.url, referer: req.query.referer,
params: params,
collection: collection,
- statusCode: statusCode,
- status: status,
- headers: headers,
- headers: headers,
- rawBody: body,
+ httpResponse: httpResponse,
formattedBody: JSON.stringify(parsedBody, null, ' ')
});
});
@@ -88,7 +110,12 @@ function fetchCollection(u, cb) {
body += chunk;
});
res.on('end', function (chunk) {
- cb(undefined, res.stausCode, "", res.headers, body);
+ cb(undefined, {
+ statusCode: res.statusCode,
+ status: '',
+ headers: res.headers,
+ body: body
+ });
});
}).on('error', function() {
cb('Unable to fetch ' + u);
diff --git a/views/data.jade b/views/data.jade
index edaa4d6..75a382a 100644
--- a/views/data.jade
+++ b/views/data.jade
@@ -29,7 +29,7 @@ block link
block href
dt rel
dd
- if isUrl(link.rel)
+ if urlgenerator.isUrl(link.rel)
a(href=link.rel) #{link.rel}
else
| #{link.rel}
@@ -44,21 +44,23 @@ block link
block meta
div(class='row-fluid')
div(class='span12')
- p
- - var href=collection.href
- dl
- dt version
- dd #{collection.version}
- dt href
- dd: block href
+ - var href=collection.href
+ dl
+ dt version
+ dd #{collection.version}
+ dt href
+ dd: block href
div(class='row-fluid')
div(class='span12')
p
- a(class='btn btn-primary', href=urlgenerator.render(href)) Explore
- |
- a(class='btn btn-primary', href=href) Raw
- |
+ if href
+ a(class='btn btn-primary', href=urlgenerator.render(href)) Explore
+ |
+ a(class='btn btn-primary', href=href) Raw
+ |
+ a(class='btn btn-danger', href=urlgenerator.delete(url, href)) Delete
+ |
form(action='http://redbot.org')
input(type='text', name='uri', value=url, type='hidden')
input(type='text', name='req_hdr', value='Accept: application/vnd.collection+json', type='hidden')
@@ -81,13 +83,18 @@ block items
else
// p The feed has #{collection.items.length} items.
each item, i in collection.items
+ - var href=item.href
h2(id='item-#{i+1}') Item ##{i+1}
- div
- a(class='btn btn-primary btn-mini', href=urlgenerator.render(href)) Explore
- |
- a(class='btn btn-primary btn-mini', href=href) Raw
+ if href
+ div(class='fluid-row')
+ div(class='span12')
+ p
+ a(class='btn btn-primary btn-mini', href=urlgenerator.render(href)) Explore
+ |
+ a(class='btn btn-primary btn-mini', href=href) Raw
+ |
+ a(class='btn btn-danger btn-mini', href=urlgenerator.delete(url, href)) Delete
- - var href=item.href
dl
dt href
dd: block href
@@ -128,16 +135,49 @@ block queries
div(class='controls')
input(type='submit') Execute
-block http_response
+block error
div(class='row-fluid')
+ if typeof collection.error == 'undefined'
+ p Collection didn't include an error condition.
+ else
+ dl
+ dt title
+ dd
+ if collection.error.title
+ | #{collection.error.title}
+ else
+ i No title
+ dt code
+ dd
+ if collection.error.code
+ | #{collection.error.code}
+ else
+ i No code
+ dt message
+ dd
+ if collection.error.message
+ | #{collection.error.message}
+ else
+ i No message
+
+block httpResponse
+ div(class='row-fluid')
+ dl
+ dt URL
+ dd: a(href=urlgenerator.render(url)) #{url}
+ if typeof referer != 'undefined'
+ dt Referer
+ dd: a(href=urlgenerator.render(referer)) #{referer}
pre
table
- each value, key in headers
+ tr
+ td(colspan='2') #{httpResponse.statusCode} #{httpResponse.status}
+ each value, key in httpResponse.headers
tr
td #{key}:
td #{value}
|
- | #{rawBody}
+ | #{httpResponse.body}
block navbar
div(class='navbar navbar-fixed-top')
@@ -166,9 +206,10 @@ block sidebar
div(id='navbar', class='sidebar-nav sidebar-nav-fixed')
ul(class='nav nav-list')
if typeof err != 'undefined'
- li(class='nav-header'): a(href='#error') Error
- else
- li(class='nav-header'): a(href='#meta') Meta
+ li(class='nav-header'): a(href='#server-error') Server Error
+
+ if typeof collection != 'undefined'
+ li(class='nav-header active'): a(href='#meta') Meta
each link, i in collection.links
li: a(href='#link-' + (i + 1))
mixin get_name(link, 'Link', i)
@@ -176,23 +217,27 @@ block sidebar
each item, i in collection.items
li: a(href='#item-' + (i + 1)) ##{i + 1}
li(class='nav-header'): a(href='#queries') Queries
+ li(class='nav-header'): a(href='#error') Error
each query, i in collection.queries
li: a(href='#query-' + (i + 1))
mixin get_name(query, 'Query', i)
li(class='nav-header'): a(href='#formatted-body') Formatted Body
- li(class='nav-header'): a(href='#http-response') HTTP Response
+
+ if typeof httpResponse != 'undefined'
+ li(class='nav-header'): a(href='#http-response') HTTP Response
block inner_content
if typeof err != 'undefined'
- section(id='error')
+ section(id='server-error')
div(class='page-header')
- h1 Error
+ h1 Server Error
div(class='row-fluid')
p Error rendering: #{url}
a(class='btn btn-primary btn-mini', href=urlgenerator.render(url)) Retry
p= err
- else
+
+ if typeof collection != 'undefined'
section(id='meta')
div(class='page-header')
h1 Meta
@@ -207,15 +252,22 @@ block inner_content
div(class='page-header')
h1 Queries
block queries
+ section(id='error')
+ div(class='page-header')
+ h1 Error
+ block error
section(id='formatted-body')
div(class='page-header')
h1 Formatted Body
- pre= formattedBody
+ div(class='row-fluid')
+ div(class='span12')
+ pre= formattedBody
- section(id='http-response')
- div(class='page-header')
- h1 HTTP Response
- block http_response
+ if typeof httpResponse != 'undefined'
+ section(id='http-response')
+ div(class='page-header')
+ h1 HTTP Response
+ block httpResponse
block content
div(class='row-fluid')