1
0
mirror of /repos/Prototyper.git synced 2025-12-30 06:31:32 +01:00

initial commit

This commit is contained in:
Aiko Mastboom 2013-04-16 20:30:54 +02:00
commit 9d81b82dde
13 changed files with 959 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
.hg
.idea
*.iml
.DS_Store
*.orig
*.swp
fleet.json
*.log
thing

1
README.md Normal file
View File

@ -0,0 +1 @@
README.md

35
index.js Normal file
View File

@ -0,0 +1,35 @@
var connect = require('connect');
var express = require('express');
var instance = require('./server.js');
process.title = "Prototyper";
var config = {
errors: true,
debug: false,
port: 8000,
mongo: {
server: "mongodb://silo01.local:27017/Prototyper",
options: {
server: {
maxPoolSize:10,
auto_reconnect:true
}
}
},
share: {
sockjs: {},
db: {type: 'none'}
}
};
var server = express.createServer();
server.use(connect.logger());
server.use(express.static(__dirname + '/public'));
instance(server, config);
server.listen(config.port, function (err) {
// console.log('routes',server.routes);
console.log('Server running at http://127.0.0.1:', config.port);
});

211
mongodata.js Normal file
View File

@ -0,0 +1,211 @@
var MongoClient = require('mongodb').MongoClient;
var ObjectID = require('mongodb').ObjectID;
module.exports = function (config) {
function getMongoContent(options, callback) {
config.debug && console.log('getMongoContent options', options);
MongoClient.connect(config.mongo.server, config.mongo.options, function (err, db) {
if (err) {
config.debug && console.log('ERR1 getMongoContent',err);
return callback(err);
}
db.collection(options.collection, function (err, col) {
if (err) {
config.debug && console.log('ERR2 getMongoContent',err);
return callback(err);
}
if (options.query._id && !(options.query._id instanceof Object)) {
options.query._id = new ObjectID.createFromHexString(options.query._id);
}
col.findOne(options.query, function (err, result) {
if (err) {
config.debug && console.log('ERR3 getMongoContent',err);
return callback(err);
}
if (!result) {
return callback(new Error('Data not found ' + options.collection + '/' + JSON.stringify(options.query)));
}
return callback(null, result, col);
});
});
});
}
function getMongoAttribute(options, callback) {
config.debug && console.log('getMongoAttribute options', options);
return getMongoContent(options, function (err, result) {
if (err) {
config.errors && console.log('ERR1 getMongoAttribute',err);
return callback(err);
}
var attribute_options = null;
config.debug && console.log('getMongoAttribute result', result);
if (result && result.hasOwnProperty(options.attribute)) {
attribute_options = {
collection: options.collection,
query: {_id: result[options.attribute].guid}
};
config.debug && console.log('getMongoAttribute attribute_options', attribute_options);
return getMongoContent(attribute_options, function (err, attribute_result) {
if (err) {
config.errors && console.log('ERR2 getMongoAttribute',err);
return callback(err);
}
config.debug && console.log('getMongoAttribute attribute_result', attribute_result);
return callback(err, attribute_result);
});
} else {
config.debug && console.log('getMongoAttribute try direct lookup');
attribute_options = {
collection: options.collection,
query: {
parent: result._id,
name: result.name+'.'+options.attribute
}
};
config.debug && console.log('getMongoAttribute attribute_options', attribute_options);
return getMongoContent(attribute_options, function (err, attribute_result) {
if (err) {
config.errors && console.log('ERR3 getMongoAttribute',err);
return callback(err);
}
if (attribute_result) {
config.debug && console.log('getMongoAttribute direct attribute_result', attribute_result);
return callback(err, attribute_result);
} else {
if (options.type) {
if (options.type == 'json') {
config.errors && console.log('ERR4 getMongoAttribute empty json {}');
return callback(null, '{}');
}
if (options.type == 'text') {
config.errors && console.log('ERR5 getMongoAttribute empty string');
return callback(null, '');
}
}
return callback(new Error('Data not found ' + options.collection + '/' + JSON.stringify(options.query) + '.' + options.attribute));
}
});
}
})
}
function saveData(collection, data, callback) {
if (data._id && !(data._id instanceof Object)) {
data._id = new ObjectID.createFromHexString(data._id);
}
config.debug && console.log('saving', data._id);
collection.save(data, {safe:true}, callback);
}
function setMongoContent(data, options, callback) {
config.debug && console.log('setMongoContent options', options);
MongoClient.connect(config.mongo.server, config.mongo.options, function (err, db) {
if (err) {
config.errors && console.log('ERR1 setMongoContent',err);
return callback(err);
}
db.collection(options.collection, function (err, col) {
if (err) {
config.errors && console.log('ERR2 setMongoContent',err);
return callback(err);
}
if (options.operation) {
data.version = options.operation.v;
}
if (!data._id) {
config.debug && console.log('setMongoContent lookup by query',options.query);
col.findOne(options.query, function (err, result) {
if (result){
data._id=result._id;
}
return saveData(col, data, callback);
})
} else {
return saveData(col, data, callback);
}
});
});
}
function setMongoAttribute(data, options, callback) {
config.debug && console.log('setMongoAttribute options', options);
getMongoContent(options, function (err, result, col) {
if (err) {
config.errors && console.log('ERR1 setMongoAttribute',err);
return callback(err);
}
var attribute_options = {
collection: options.collection
};
if (result.hasOwnProperty(options.attribute)) {
config.debug && console.log('getMongoAttribute parent found, get child and save');
attribute_options.query = {_id: result[options.attribute].guid};
getMongoContent(attribute_options, function (err, attribute_result, col) {
if (err) {
config.errors && console.log('ERR2 setMongoAttribute',err);
return callback(err);
}
attribute_result[options.attribute] = data;
if (options.operation) {
attribute_result.version = options.operation.v;
}
attribute_result.parent = result._id;
return saveData(col, attribute_result, callback);
});
} else {
config.debug && console.log('getMongoAttribute try direct lookup');
attribute_options = {
collection: options.collection,
query: {
parent: result._id,
name: result.name+'.'+options.attribute
}
};
config.debug && console.log('getMongoAttribute attribute_options', attribute_options);
return getMongoContent(attribute_options, function (err, attribute_result) {
if (attribute_result) {
config.debug && console.log('getMongoAttribute found lost attribute, reconnect');
result[options.attribute] = { guid: attribute_result._id };
return saveData(col, result, callback);
} else {
config.debug && console.log('getMongoAttribute field does not exist yet. need to create doc first.');
var attribute_data = {
name: result.name + '.' + options.attribute,
parent: result._id
};
attribute_data[options.attribute] = data;
if (options.operation) {
attribute_data.version = options.operation.v;
}
return saveData(col, attribute_data, function (err, attribute_result) {
if(err){
config.errors && console.log('ERR3 setMongoAttribute',err);
}
result[options.attribute] = { guid: attribute_result._id };
return saveData(col, result, callback);
})
}
});
}
})
}
return {
getMongoAttribute: getMongoAttribute,
getMongoContent: getMongoContent,
setMongoAttribute: setMongoAttribute,
setMongoContent: setMongoContent
};
};

29
package.json Normal file
View File

@ -0,0 +1,29 @@
{
"name": "Prototyper",
"version": "0.0.0",
"main": "index.js",
"private": "true",
"dependencies": {
"share": "~0.6.0",
"connect": "~2.7.5",
"express": "~2.5.11",
"mongodb": "~1.2.14",
"handlebars": "~1.0.10",
"underscore": "~1.4.4",
"less": "~1.3.3"
},
"devDependencies": {
"sockjs": "~0.3.5"
},
"repository": "",
"author": "Aiko Mastboom",
"license": "BSD",
"readmeFilename": "README.md",
"directories": {
"test": "test"
},
"description": "README.md",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}

106
preview.js Normal file
View File

@ -0,0 +1,106 @@
var Handlebars = require('handlebars');
var _ = require('underscore');
var less = require('less');
module.exports = function (config) {
var sourceHead =
'<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>\n' +
'{{#if debug}}' +
'<link href="/content/{{collection}}/{{name}}/style.css" media="all" rel="stylesheet/less" type="text/css">\n' +
'<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js"></script>\n' +
'{{else}}' +
'<link href="/content/{{collection}}/{{name}}/style.css" media="all" rel="stylesheet" type="text/css">\n' +
'{{/if}}';
var sourceBody =
'<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>\n' +
'<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>\n' +
'<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>\n' +
'<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>\n' +
'<script src="/content/{{collection}}/{{name}}/behaviour.js"></script>\n';
var templateHead = Handlebars.compile(sourceHead);
var templateBody = Handlebars.compile(sourceBody);
var getCSS = function (callback) {
contentInstance.getAllOrderedObjects('Stylesheet', function (err, dataObjects) {
if (err) {
return callback(err);
}
var stylesheets = _.map(dataObjects, function(dataObject) {
return "\n/* -- " + dataObject.get('title') + ' -- */\n\n' +
dataObject.get('body');
}).join('\n');
function lessCompilationError(stylesheets, err, callback){
stylesheets = "/*\n -- The following ERROR(s) occurred during less compilation:\n\n" +
err.message +
"\n\n -- you can add ?debug to the preview url to enable browser side less compilation." +
"\n\n0: this is line 0 */\n" +
stylesheets;
return callback(null, stylesheets);
}
try {
less.render(stylesheets, function (err, css) {
if (err) {
return lessCompilationError(stylesheets, err, callback);
}
return callback(err, css);
});
} catch (err){
return lessCompilationError(stylesheets, err, callback);
}
});
};
var getJS = function (callback) {
contentInstance.getAllOrderedObjects('Behaviour', function (err, dataObjects) {
if (err) {
return callback(err);
}
var scripts = _.map(dataObjects, function(dataObject) {
return dataObject.get('body');
}).join('\n');
callback(null, scripts);
});
};
var getPreviewHTML = function (options, content, callback) {
var html = replaceMarkers(content, templateHead(options), templateBody(options));
callback(null, html);
};
var replaceMarkers = function (html, styleMarkerReplacement, jsMarkerReplacement) {
function replace(marker, replacement) {
var regExp = new RegExp('<!--\\s*@@' + marker + '\\s*-->');
if (html.match(regExp)){
html = html.replace(regExp, replacement);
} else {
html = html.replace('</head>', '<script>if (typeof window.console !== "undefined"){console.log("WARNING: Missing <!--@@' + marker + '-->");}</script>\n</head>');
}
}
replace('ipe_style_marker', styleMarkerReplacement);
replace('ipe_js_marker', jsMarkerReplacement);
return html;
};
return {
getCSS: getCSS,
getJS: getJS,
getPreviewHTML: getPreviewHTML,
_replaceMarkers: replaceMarkers
};
};

79
public/behaviour.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css">
<title>app/main/behaviour</title>
</head>
<body>
<div id="header">
<div id="htext">
Editing <b>behaviour</b>
</div>
</div>
<div id="editor"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="lib/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="lib/ace/mode-html.js" type="text/javascript" charset="utf-8"></script>-->
<script src="lib/ace/mode-javascript.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="lib/ace/mode-css.js" type="text/javascript" charset="utf-8"></script>-->
<!--<script src="lib/ace/mode-markdown.js" type="text/javascript" charset="utf-8"></script>-->
<script src="//cdn.sockjs.org/sockjs-0.3.min.js"></script>
<!--<script src="/channel/bcsocket.js"></script>-->
<!--<script src="/socket.io/socket.io.js"></script>-->
<script src="/share/share.uncompressed.js"></script>
<script src="/share/json.js"></script>
<script src="/share/ace.js"></script>
<script>
var attribute = 'behaviour';
var editor = ace.edit("editor");
var aceMode = require("ace/mode/javascript").Mode;
var session = editor.getSession();
session.setMode(new aceMode());
sharejs.open('json:app:main','json', function (error, main) {
var indexField = null;
if (error) {
console.log('error opening app:main:json', error, main);
} else {
console.log('yes!!',main);
if (main.snapshot == null) {
main.submitOp([
{ p: [], oi: {name:'main'}, od: null }
]);
}
function openIndex() {
if (main.snapshot._id && !indexField){
indexField = 'busy';
console.log('main.snapshot._id',main.snapshot._id);
sharejs.open('text:app:'+main.snapshot._id+':'+attribute, 'text', function(error, index) {
if (error) {
console.log('error opening text:app:'+main.snapshot._id+':'+attribute, error, index);
indexField=null;
} else {
console.log('yes index!!',index);
indexField=index;
index.attach_ace(editor);
}
});
}
}
openIndex();
main.on('change', function (op) {
console.log('main:change',op,main.snapshot);
openIndex();
});
}
})
</script>
</body>
</html>

79
public/index.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css">
<title>app/main/index</title>
</head>
<body>
<div id="header">
<div id="htext">
Editing <b>index</b>
</div>
</div>
<div id="editor"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="lib/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="lib/ace/mode-html.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="lib/ace/mode-javascript.js" type="text/javascript" charset="utf-8"></script>-->
<!--<script src="lib/ace/mode-css.js" type="text/javascript" charset="utf-8"></script>-->
<!--<script src="lib/ace/mode-markdown.js" type="text/javascript" charset="utf-8"></script>-->
<script src="//cdn.sockjs.org/sockjs-0.3.min.js"></script>
<!--<script src="/channel/bcsocket.js"></script>-->
<!--<script src="/socket.io/socket.io.js"></script>-->
<script src="/share/share.uncompressed.js"></script>
<script src="/share/json.js"></script>
<script src="/share/ace.js"></script>
<script>
var attribute = 'index';
var editor = ace.edit("editor");
var aceMode = require("ace/mode/html").Mode;
var session = editor.getSession();
session.setMode(new aceMode());
sharejs.open('json:app:main','json', function (error, main) {
var indexField = null;
if (error) {
console.log('error opening app:main:json', error, main);
} else {
console.log('yes!!',main);
if (main.snapshot == null) {
main.submitOp([
{ p: [], oi: {name:'main'}, od: null }
]);
}
function openIndex() {
if (main.snapshot._id && !indexField){
indexField = 'busy';
console.log('main.snapshot._id',main.snapshot._id);
sharejs.open('text:app:'+main.snapshot._id+':'+attribute, 'text', function(error, index) {
if (error) {
console.log('error opening text:app:'+main.snapshot._id+':'+attribute, error, index);
indexField=null;
} else {
console.log('yes index!!',index);
indexField=index;
index.attach_ace(editor);
}
});
}
}
openIndex();
main.on('change', function (op) {
console.log('main:change',op,main.snapshot);
openIndex();
});
}
})
</script>
</body>
</html>

44
public/style.css Normal file
View File

@ -0,0 +1,44 @@
body {
overflow: hidden;
}
.ace_bold {
font-weight:bold;
}
.ace_italic {
font-style:italic;
}
#header {
position: fixed;
top: 0;
right: 0;
height: 30px;
width: 100%;
background-color: black;
}
#htext {
line-height: 30px;
vertical-align: middle;
padding-left: 10px;
color: white;
font-family: baskerville, palatino, 'palatino linotype', georgia,serif;
}
#editor {
margin: 0;
position: absolute;
top: 30px;
bottom: 0;
left: 0;
right: 0;
}
#htext a {
color: #aaf;
font-weight: bold;
}

79
public/style.html Normal file
View File

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css">
<title>app/main/style</title>
</head>
<body>
<div id="header">
<div id="htext">
Editing <b>style</b>
</div>
</div>
<div id="editor"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout-validation/1.0.2/knockout.validation.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="lib/ace/ace.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="lib/ace/mode-html.js" type="text/javascript" charset="utf-8"></script>-->
<!--<script src="lib/ace/mode-javascript.js" type="text/javascript" charset="utf-8"></script>-->
<script src="lib/ace/mode-css.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="lib/ace/mode-markdown.js" type="text/javascript" charset="utf-8"></script>-->
<script src="//cdn.sockjs.org/sockjs-0.3.min.js"></script>
<!--<script src="/channel/bcsocket.js"></script>-->
<!--<script src="/socket.io/socket.io.js"></script>-->
<script src="/share/share.uncompressed.js"></script>
<script src="/share/json.js"></script>
<script src="/share/ace.js"></script>
<script>
var attribute = 'style';
var editor = ace.edit("editor");
var aceMode = require("ace/mode/css").Mode;
var session = editor.getSession();
session.setMode(new aceMode());
sharejs.open('json:app:main','json', function (error, main) {
var indexField = null;
if (error) {
console.log('error opening app:main:json', error, main);
} else {
console.log('yes!!',main);
if (main.snapshot == null) {
main.submitOp([
{ p: [], oi: {name:'main'}, od: null }
]);
}
function openIndex() {
if (main.snapshot._id && !indexField){
indexField = 'busy';
console.log('main.snapshot._id',main.snapshot._id);
sharejs.open('text:app:'+main.snapshot._id+':'+attribute, 'text', function(error, index) {
if (error) {
console.log('error opening text:app:'+main.snapshot._id+':'+attribute, error, index);
indexField=null;
} else {
console.log('yes index!!',index);
indexField=index;
index.attach_ace(editor);
}
});
}
}
openIndex();
main.on('change', function (op) {
console.log('main:change',op,main.snapshot);
openIndex();
});
}
})
</script>
</body>
</html>

36
responder.js Normal file
View File

@ -0,0 +1,36 @@
var mimetypes = {
'js': 'application/javascript',
'html': 'text/html',
'text': 'text/plain',
'css': 'text/css',
'less': 'text/css'
};
var getMimeType = function (ext) {
if (mimetypes[ext]) {
return mimetypes[ext];
}
return mimetypes.text;
};
module.exports = function (options, res, next) {
var responder = function (err, result) {
console.log('err',err);
if (err) {
if (/Data not found*/.test(err.message)) {
res.status(404);
}
return next(err.message);
}
console.log('responder options',options);
var contentType = getMimeType(options.ext);
res.setHeader('Content-Type', contentType);
var content = result;
if (options.attribute) {
content = result[options.attribute];
}
res.send(content);
};
return responder;
};

251
server.js Normal file
View File

@ -0,0 +1,251 @@
var sharejs = require('share');
var mongodata = require('./mongodata.js');
var responder = require('./responder.js');
var preview = require('./preview.js');
module.exports = function (server, config) {
// Attach the sharejs REST and Socket.io interfaces to the server
sharejs.server.attach(server, config.share);
var model = server.model;
var mongodataInstance = mongodata(config);
server.get('/data/:collection/:guid/:attribute.:ext(css|less|js|html)',
function getMongoAttribute(req, res, next) {
config.debug && console.log('/data/:collection/:guid/:attribute.:ext(less|js|html)');
var options = {
collection: req.params.collection,
attribute: req.params.attribute,
ext: req.params.ext,
query: {_id:req.params.guid}
};
mongodataInstance.getMongoAttribute(options,
responder(options, res, next)
);
}
);
server.get('/data/:collection/:guid.:ext(json)',
function getMongoContent(req, res, next) {
config.debug && console.log('/data/:collection/:guid.:ext(json)');
var options = {
collection: req.params.collection,
ext: req.params.ext,
query: {_id:req.params.guid}
};
mongodataInstance.getMongoContent(options,
responder(options, res, next)
);
}
);
server.get('/content/:collection/:name/:attribute.:ext(css|less|js|html)',
function getMongoAttribute(req, res, next) {
config.debug && console.log('/content/:collection/:name/:attribute.:ext(less|js|html)');
var options = {
collection: req.params.collection,
attribute: req.params.attribute,
ext: req.params.ext,
query: {name:req.params.name}
};
mongodataInstance.getMongoAttribute(options,
responder(options, res, next)
);
}
);
server.get('/content/:collection/:name.:ext(json)',
function getMongoContent(req, res, next) {
config.debug && console.log('/content/:collection/:name.:ext(json)');
var options = {
collection: req.params.collection,
ext: req.params.ext,
query: {name:req.params.name}
};
mongodataInstance.getMongoContent(options,
responder(options, res, next)
);
}
);
function handleMongoGetResult(options) {
function handleResult(err, result) {
if (err) {
config.errors && console.log('ERR1 handleMongoGetResult.handleResult Error retrieving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
} else {
if (result) {
var operation = null;
config.debug && console.log('handleMongoGetResult options',options, result);
var data = result;
if (options.attribute) {
data = result[options.attribute];
}
var version = 0;
if (options.type == 'json') {
if (data instanceof String) {
data = JSON.parse(data);
}
operation = { op: [
{ p: [], oi: data, od: null }
], v: version };
} else if (options.type == 'text') {
operation = { op: [
{i: data, p: 0}
], v: version };
}
if (operation) {
model.applyOp(options.documentId, operation, function appliedOp(error, version) {
options.debug && console.log('getResult applyOp version', version);
if (error) {
options.error && console.log('ERR2 handleMongoGetResult', error);
}
});
}
}
}
}
return handleResult;
}
model.on('create', function populateDocument(documentId, data) {
console.log('Populating a doc in channel', documentId, data);
var splitId = documentId.split(':');
var options = {
documentId: documentId,
type: splitId[0],
collection: splitId[1],
attribute: null
};
if (splitId.length == 4) {
options.query= {_id:splitId[2]};
options.attribute = splitId[3];
mongodataInstance.getMongoAttribute(options, handleMongoGetResult(options));
} else {
options.query={name:splitId[2]};
mongodataInstance.getMongoContent(options, handleMongoGetResult(options));
}
});
function handleMongoSetResult(options, current, callback) {
function handleResult(err, result) {
if (err) {
config.errors && console.log('ERR1 handleMongoSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
return callback && callback(err);
}
config.debug && console.log('current', current, 'result',result, 'options',options);
if ((!current || !current.name) && result.name) {
var operation = { op: [
{ p: ['name'], oi: result.name, od: null }
], v: options.operation.v };
model.applyOp(options.documentId, operation, function appliedOp(error, version) {
config.debug && console.log('setResult applyOp version', version);
if (error) {
config.error && console.log('ERR2 handleMongoSetResult',error);
return callback && callback(error);
}
return callback && callback(null,version);
});
}
}
return handleResult;
}
function handleMongoAttributeSetResult(options, current, callback) {
function handleResult(err, result) {
if (err) {
config.errors && console.log('ERR1 handleMongoAttributeSetResult Error while saving document ', options.collection, JSON.stringify(options.query), options.attribute || "", err);
return callback && callback(err);
}
options.debug && console.log('current', current, 'result',result);
if (result.hasOwnProperty('_id')) {
config.debug && console.log('// new object created. need to update the parent object.');
var pieces = options.documentId.split(':');
var parentDocId = pieces[0]+ ':' + pieces[1] + ':' + pieces[2];
var operation = { op: [
{ p: [options.attribute], oi: { guid: result._id } , od: null }
], v: options.operation.v };
model.applyOp(parentDocId, operation, function appliedOp(error, version) {
config.debug && console.log('setResult applyOp parent version', version);
if (error) {
config.error && console.log('ERR2 handleMongoAttributeSetResult',error);
return callback && callback(error);
}
return callback && callback(null,version);
})
}
}
return handleResult;
}
// 'applyOp' event is fired when an operational transform is applied to to a shareDoc
// a shareDoc has changed and needs to be saved to mongo
model.on('applyOp', function persistDocument(documentId, operation, current, previous) {
config.debug && console.log('applyOp',documentId,operation,current);
var splitId = documentId.split(':');
var options = {
documentId: documentId,
type: splitId[0],
collection: splitId[1],
attribute: null,
operation: operation
};
if (splitId.length == 4) {
options.query= {_id:splitId[2]};
options.attribute = splitId[3];
var data = current;
if (options.type == 'json') {
data = JSON.stringify(current);
}
mongodataInstance.setMongoAttribute(data, options, handleMongoAttributeSetResult(options, current, function (err, result) {
if(err) {
config.errors && console.log('ERR1 applyOp', err);
}
}));
} else {
options.query={name:splitId[2]};
mongodataInstance.setMongoContent(current, options, handleMongoSetResult(options, current, function (err, result) {
if(err) {
config.errors && console.log('ERR2 applyOp', err);
}
}));
}
});
var previewInstance = preview(config);
server.get('/page/:collection/:name.:ext(html)',
function getPreviewContent(req, res, next) {
config.debug && console.log('/page/:collection/:name.:ext(html)');
var options = {
collection: req.params.collection,
ext: req.params.ext,
query: {name:req.params.name},
debug: req.query && req.query.hasOwnProperty('debug')
};
mongodataInstance.getMongoContent(options, function (err, result) {
if (err) {
responder(options, res, next)(err, result);
}
if (result) {
var attribute_parts = options.query.name.split('.');
var attribute = attribute_parts[attribute_parts.length-1];
var content = result[attribute];
options.name=attribute_parts[0];
//options.attribute=attribute;
config.debug && console.log('getPreviewContent content',content);
previewInstance.getPreviewHTML(options, content,
responder(options, res, next)
);
}
});
}
);
};

0
test/test.server.js Normal file
View File