Skip to content

Commit

Permalink
Merge remote branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Dustin Machi committed Aug 14, 2010
2 parents 3e483d8 + 8d43747 commit 2a3bb99
Show file tree
Hide file tree
Showing 20 changed files with 175 additions and 566 deletions.
437 changes: 0 additions & 437 deletions engines/node/lib/multipart.js

This file was deleted.

22 changes: 13 additions & 9 deletions lib/jsgi/cascade.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ var Cascade = exports.Cascade = function(apps, status) {
lastResponse;
function next(){
if(i < apps.length){
when(apps[i](env), function(response){
i++;
if (response.status !== status) {
deferred.resolve(response);
}else{
lastResponse = response;
next();
}
}, deferred.reject);
try{
when(apps[i](env), function(response){
i++;
if (response.status !== status) {
deferred.resolve(response);
}else{
lastResponse = response;
next();
}
}, deferred.reject);
}catch(e){
deferred.reject(e);
}
}else{
deferred.resolve(lastResponse);
}
Expand Down
34 changes: 26 additions & 8 deletions lib/jsgi/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,28 @@ function Deserialize(mediaSelector, nextApp){
request.body[parts[0].trim()] = parts[1].trim().replace(/"/g,'');
}
});
return when(mediaModule.onFile(request.body), function(){
return when(mediaModule.saveFile(request.body), function(fileObject){
request.body = fileObject;
if(request.method == "PUT"){
request.method = "GET";
return when(nextApp(request), function(response){
request.method = "PUT";
var target = response.body;
if(target && target.save){
var metadata = target.getMetadata ? target.getMetadata() : target._metadata || (target._metadata = {});
var fileMetadata = fileObject.getMetadata() || fileObject;
fileMetadata.id = fileObject.id;
(metadata.alternates || (metadata.alternates = [])).push(fileMetadata);
return when(target.save(), function(){
var undefined;
response.body = undefined;
return response;
});
}else{
return nextApp(request);
}
});
}
return nextApp(request);
}); // funnel errors to the response
}else{
Expand All @@ -47,7 +68,7 @@ function Deserialize(mediaSelector, nextApp){
// return {status: 415, headers:{}, body: ["Unsupported Media Type"]};
}
try{
var body = requestMedia.deserialize(request.body, request);
var body = requestMedia.media.deserialize(request.body, requestMedia.parameters, request);
}catch(e){
e.status = 400;
throw e;
Expand Down Expand Up @@ -84,21 +105,18 @@ function Serialize(mediaSelector, nextApp){
var responseMedia = mediaSelector(response.body, request.headers["accept"]);
if(!responseMedia){
//TODO: List acceptable media types
var unsupportedError = new Error("The Accept header did not contain an acceptable media type");
unsupportedError.status = 406;
throw unsupportedError;
// return {status: 406, headers: {}, body:["The Accept header did not contain an acceptable media type"]};
return {status: 406, headers: {}, body:["The Accept header did not contain an acceptable media type"]};
}
var headers = response.headers;
headers.vary = (headers.vary ? headers.vary + "," : "") + "Accept" + request.variedOn;
if (!headers["content-type"] || headers['content-type']!=responseMedia.mediaType) {
headers["content-type"] = responseMedia.mediaType + "; charset=UTF-8";
headers["content-type"] = responseMedia.media.mediaType + "; charset=UTF-8";
var body = response.body;
var schema = body && body.schema;
if(schema && schema.schema){
headers["content-type"] += "; profile=" + request.scriptName + "/Class/" + schema.schema.getId(schema);
}
response.body = responseMedia.serialize(body, responseMedia, request, response);
response.body = responseMedia.media.serialize(body, responseMedia.parameters, request, response);
}
return response;
});
Expand Down
7 changes: 4 additions & 3 deletions lib/jsgi/rest-store.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ exports.RestStore = function(options){
return function(request){
var model = options.getDataModel(request);
var path = request.pathInfo.substring(1);

var scriptName = request.scriptName;
var headers = request.headers;
var metadata = {};
for(var i in headers){// for now just copy all of them, probably should do certain ones though
Expand All @@ -38,6 +38,7 @@ exports.RestStore = function(options){
if(slashIndex > -1 && model[part = path.substring(0, slashIndex)]){
model = model[part];
path = path.substring(slashIndex + 1);
scriptName += '/' + part;
}
else{
if(model[path]){
Expand Down Expand Up @@ -123,13 +124,13 @@ exports.RestStore = function(options){
else{
// call the model with the request body and the path
responseValue = model[method](request.body, metadata);
when(responseValue, function(){
when(responseValue, function(responseValue){
if(method !== "get" && responseValue){
// include a Content-Location per http://greenbytes.de/tech/webdav/draft-ietf-httpbis-p2-semantics-08.html#rfc.section.6.1
var schema = responseValue && responseValue.schema;
if(schema){
headers["content-location"] = request.scheme + "://" + request.headers.host +
request.scriptName + '/' + (schema.getId(responseValue));
scriptName + '/' + (schema.getId(responseValue));
}
}
if(promiseModule.currentContext && promiseModule.currentContext.generatedId){
Expand Down
84 changes: 51 additions & 33 deletions lib/media.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ var model = require("perstore/model"),

Media.instances = {};
Media.optimumMedia = function(source, acceptTypeHeader){
var bestMedia = null;
var bestMedia = null, bestParameters;
var bestQuality = 0;
if(acceptTypeHeader==null){
acceptTypeHeader = "*/*";
Expand All @@ -23,35 +23,17 @@ Media.optimumMedia = function(source, acceptTypeHeader){
var parts = acceptType.split(/\s*;\s*/);
var type = parts[0];
var clientQuality = 1;
for(var j = 0; j < parts.length; j++){
var parameters = {};
for(var j = 1; j < parts.length; j++){
var part = parts[j];
if(part.substring(0,2) == "q="){
clientQuality = parseFloat(part.substring(2)) || 0;
}
var equalIndex = part.indexOf("=");
parameters[part.substring(0, equalIndex)] = part.substring(equalIndex + 1);
}
clientQuality = +(parameters.q || 1);

if("*/*" == type){
for(var i in Media.instances){
checkMedia(Media.instances[i]);
}
// use alternates per http://tools.ietf.org/html/draft-ietf-http-alternates-01
var alternates;
if(source && typeof source.getMetadata === "function" && (alternates = source.getMetadata().alternates)){
if(!(alternates instanceof Array)){
alternates = [alternates];
}
alternates.forEach(function(alternate){

checkMedia({
serialize: function(){
return alternate;
},
getQuality: function(){
return 1;
},
mediaType: alternate.getMetadata()["content-type"]
});
});
for(var instanceType in Media.instances){
checkMedia(Media.instances[instanceType]);
}
/* for persvr compatibility:
for(var i in source){
Expand All @@ -71,16 +53,37 @@ Media.optimumMedia = function(source, acceptTypeHeader){
checkMedia(media);
}*/
}
// use alternates per http://tools.ietf.org/html/draft-ietf-http-alternates-01
var alternates;
if(source && ((typeof source.getMetadata === "function" && (alternates = source.getMetadata().alternates)) || (source._metadata && (alternates = source._metadata.alternates)))){
if(!(alternates instanceof Array)){
alternates = [alternates];
}
alternates.forEach(function(alternate){
var mediaType = alternate["content-type"];
if("*/*" == type || mediaType == type){;
checkMedia({
serialize: function(){
return exports.loadFile(alternate);
},
getQuality: function(){
return +(alternate.q || 0.7);
},
mediaType: mediaType
});
}
});
}
}
function checkMedia(media){
var quality = clientQuality * media.getQuality(source);
if(quality > bestQuality){
bestMedia = media;
bestParameters = parameters;
bestQuality = quality;
}
}

return bestMedia;
return bestMedia && {media: bestMedia, parameters: bestParameters};
};

exports.getColumnsToExport = function(request, item){
Expand Down Expand Up @@ -118,10 +121,25 @@ exports.setFileModel = function(value){
};
exports.fileSchema = {};

exports.onFile = function(file, directives){
file.isFile = true;
return when(exports.getFileModel().put(file, directives), function(file){
file = file.id || file;
return {$ref:file};
exports.saveFile = function(file, directives){
var metadata = {};
for(var i in file){
if(typeof file[i] == "string"){
metadata[i] = file[i];
}
}
return when(exports.getFileModel().put(file, directives), function(result){
var id = result.id || result;
result = {id: id};
Object.defineProperty(result, "getMetadata",{
value: function(){
return metadata;
},
enumerable: false
});
return result;
});
};
exports.loadFile = function(file, directives){
return exports.getFileModel().get(file.id, directives);
};
6 changes: 3 additions & 3 deletions lib/media/atom.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Media({
getQuality: function(object){
return 0.5;
},
serialize: function(object, request, response){
serialize: function(object, parameters, request, response){
return {
forEach: function(write){
var title = request.store.title || request.scriptName.substring(1);
var title = request.scriptName.substring(1);
var qs = "?" + request.queryString;
write('<?xml version="1.0" encoding="utf-8"?>\n');
write('<feed xmlns="http://www.w3.org/2005/Atom">\n');
Expand Down Expand Up @@ -60,7 +60,7 @@ Media({
}
};
},
deserialize: function(inputStream, request){
deserialize: function(inputStream, parameters, request){
throw new Error("not implemented yet");
}
});
4 changes: 2 additions & 2 deletions lib/media/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Media({
getQuality: function(object){
return 0.2;
},
serialize: function(object, request, response){
serialize: function(object){
return {
forEach: function(write){
object.forEach(function(item){
Expand All @@ -20,7 +20,7 @@ Media({
}
}
},
deserialize: function(inputStream, request){
deserialize: function(inputStream, parameters){
throw new Error("not implemented yet");
}
});
2 changes: 1 addition & 1 deletion lib/media/csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Media({
return 0.4;
},
delimiter: ",", // E.g. in Europe they use ';' as CSV delimiter
serialize: function(object, request, response){
serialize: function(object, parameters, request, response){
var self = this;
var columns; // N.B. in case of empty object we can never dump column list ;)
return {
Expand Down
4 changes: 2 additions & 2 deletions lib/media/hatom.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Media({
getQuality: function(object) {
return 0.9
},
serialize: function(object, request, response) {
serialize: function(object, parameters, request, response) {
return {
forEach: function(write) {
var title = request.store.title || request.scriptName.substring(1);
var title = request.scriptName.substring(1);
var qs = "?" + request.queryString;
write('<html><head>\n');
write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>\n');
Expand Down
16 changes: 5 additions & 11 deletions lib/media/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
* Media handler for generating HTML from Wiki markup-based doc
*/

var Media = require("media").Media,
var Media = require("../media").Media,
filesystem = require("perstore/store/filesystem").FileSystem({fsRoot: "templates"}),
transform = require("pintura/html-transform"),
Response=require("pintura/jsgi/response").Response,
resolver = require("cjsTemplate").Resolver;
transform = require("../html-transform"),
Response=require("../jsgi/response").Response,
resolver = require("cjsTemplate/cjsTemplate").Resolver;

var templateEngine = require('cjsTemplate').TemplateEngine({resolver: resolver, store: filesystem});
var templateEngine = require('cjsTemplate/cjsTemplate').TemplateEngine({resolver: resolver, store: filesystem});



Expand All @@ -21,9 +21,6 @@ Media({

if (contentType) {

// html is being requested, we're ideal
if (contentType=="text/html") { return 1; }

// we have an available transformer
if (transform && transform[contentType]) {
return 1;
Expand All @@ -35,7 +32,6 @@ Media({
//we want to be the default handler if there isn't a specific handler for a request already
return this.defaultQuality
},

serialize: function(object, mediaParams, request, response){
var template,content;

Expand All @@ -44,8 +40,6 @@ Media({
var templateId = mediaParams.template || request['scriptName'] + request['pathInfo'];
templateId = mediaParams.templateType ? templateId + "-" + mediaParams['templateType'] : templateId;

print("templateId: " + templateId);

if (!object && !response.status){
response.status = 404;
}else if ((!response.status || (response.status < 400)) && transform && meta['content-type']){
Expand Down
5 changes: 3 additions & 2 deletions lib/media/http.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Registers message/http, which allows multiple HTTP messages to be sent
* in one request (effectively facilitating multi-action transactions)
* not implemented yet
* TODO: Move to a facet, like facet/jsgi.js
*/
var Media = require("../media").Media;

Expand All @@ -10,10 +11,10 @@ Media({
getQuality: function(object){
return 0.6;
},
serialize: function(object, request, response){
serialize: function(object, parameters, request, response){
throw new Error("not implemented yet");
},
deserialize: function(inputStream, request){
deserialize: function(inputStream, parameters, request){
throw new Error("not implemented yet");
}
});
Loading

0 comments on commit 2a3bb99

Please sign in to comment.