mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 10:07:19 +00:00
Browser now syncs changes with server which syncs with the file system
A bit rough and ready, but this gives us basic support for editting tiddlers in the browser and updating the original file on the server
This commit is contained in:
parent
495ef1ada5
commit
0ac55688c4
24
js/App.js
24
js/App.js
@ -10,6 +10,7 @@ This is the main() function in the browser
|
||||
"use strict";
|
||||
|
||||
var WikiStore = require("./WikiStore.js").WikiStore,
|
||||
HttpSync = require("./HttpSync.js").HttpSync,
|
||||
Tiddler = require("./Tiddler.js").Tiddler,
|
||||
tiddlerInput = require("./TiddlerInput.js"),
|
||||
tiddlerOutput = require("./TiddlerOutput.js"),
|
||||
@ -81,6 +82,8 @@ var App = function() {
|
||||
var shadowArea = document.getElementById("shadowArea");
|
||||
this.store.shadows.addTiddlers(this.store.deserializeTiddlers("(DOM)",shadowArea));
|
||||
}
|
||||
// Reset pending events on the store so that we don't get events for the initial load
|
||||
this.store.clearEvents();
|
||||
// Bit of a hack to set up the macros
|
||||
this.store.installMacro(require("./macros/chooser.js").macro);
|
||||
this.store.installMacro(require("./macros/command.js").macro);
|
||||
@ -102,8 +105,10 @@ var App = function() {
|
||||
linkInfo.target = encodeURIComponent(linkInfo.target);
|
||||
}
|
||||
};
|
||||
// Set up navigation if we're in the browser
|
||||
// Set up for the browser
|
||||
if(this.isBrowser) {
|
||||
// Set up HttpSync
|
||||
this.httpSync = new HttpSync(this.store);
|
||||
// Open the PageTemplate
|
||||
var renderer = this.store.renderMacro("tiddler",{target: "PageTemplate"});
|
||||
renderer.renderInDom(document.body);
|
||||
@ -118,18 +123,19 @@ var App = function() {
|
||||
titleRenderer.refresh(changes);
|
||||
document.title = titleRenderer.render("text/plain");
|
||||
});
|
||||
// Set up a timer to change the value of a tiddler
|
||||
var me = this;
|
||||
window.setInterval(function() {
|
||||
me.store.addTiddler(new Tiddler({
|
||||
title: "ClockTiddler",
|
||||
text: "The time was recently " + (new Date()).toString()
|
||||
}));
|
||||
},3000);
|
||||
// Listen for navigate events that weren't caught
|
||||
document.addEventListener("tw-navigate",function (event) {
|
||||
renderer.broadcastEvent(event);
|
||||
},false);
|
||||
// Set up a timer to change the value of a tiddler
|
||||
var me = this,
|
||||
s = setInterval || window.setInterval;
|
||||
s(function() {
|
||||
me.store.addTiddler(new Tiddler({
|
||||
title: "ClockTiddler",
|
||||
text: "The time was recently " + (new Date()).toString()
|
||||
}));
|
||||
},3000);
|
||||
}
|
||||
};
|
||||
|
||||
|
35
js/HttpSync.js
Normal file
35
js/HttpSync.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*\
|
||||
title: js/HttpSync.js
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true */
|
||||
"use strict";
|
||||
|
||||
function HttpSync(store) {
|
||||
this.store = store;
|
||||
this.changeCounts = {};
|
||||
store.addEventListener("",function(changes) {
|
||||
for(var title in changes) {
|
||||
var tiddler = store.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var fieldStrings = tiddler.getFieldStrings(),
|
||||
fields = {},
|
||||
t;
|
||||
for(t=0; t<fieldStrings.length; t++) {
|
||||
fields[fieldStrings[t].name] = fieldStrings[t].value;
|
||||
}
|
||||
fields.text = tiddler.text;
|
||||
var x = new XMLHttpRequest();
|
||||
x.open("PUT",window.location.toString() + encodeURIComponent(title),true);
|
||||
x.setRequestHeader("Content-type", "application/json");
|
||||
x.send(JSON.stringify(fields));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.HttpSync = HttpSync;
|
||||
|
||||
})();
|
@ -1,5 +1,5 @@
|
||||
/*\
|
||||
title: js/FileStore.js
|
||||
title: js/LocalFileSync.js
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@ -8,17 +8,18 @@ title: js/FileStore.js
|
||||
"use strict";
|
||||
|
||||
var retrieveFile = require("./FileRetriever.js").retrieveFile,
|
||||
utils = require("./Utils.js"),
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
url = require("url"),
|
||||
util = require("util"),
|
||||
async = require("async");
|
||||
|
||||
function FileStore(dirpath,store,callback) {
|
||||
function LocalFileSync(dirpath,store,callback) {
|
||||
this.dirpath = dirpath;
|
||||
this.store = store;
|
||||
this.callback = callback;
|
||||
this.sources = {}; // A hashmap of <tiddlername>: <srcpath>
|
||||
this.changeCounts = {}; // A hashmap of <tiddlername>: <changeCount>
|
||||
var self = this;
|
||||
// Set up a queue for loading tiddler files
|
||||
this.loadQueue = async.queue(function(task,callback) {
|
||||
@ -68,8 +69,8 @@ function FileStore(dirpath,store,callback) {
|
||||
var loadCallback = function(task,tiddlers) {
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
var tiddler = tiddlers[t];
|
||||
self.sources[tiddler.title] = task.filepath;
|
||||
self.store.addTiddler(tiddler);
|
||||
self.changeCounts[tiddler.title] = self.store.getChangeCount(tiddler.title);
|
||||
}
|
||||
};
|
||||
for(var t=0; t<files.length; t++) {
|
||||
@ -83,8 +84,42 @@ function FileStore(dirpath,store,callback) {
|
||||
}
|
||||
}
|
||||
});
|
||||
// Set up a queue for saving tiddler files
|
||||
this.saveQueue = async.queue(function(task,callback) {
|
||||
var data = task.data,
|
||||
encoding = "utf8";
|
||||
if(task.binary) {
|
||||
data = new Buffer(task.data,"base64").toString("binary"),
|
||||
encoding = "binary";
|
||||
}
|
||||
fs.writeFile(self.dirpath + "/" + task.name,data,encoding,function(err) {
|
||||
callback(err);
|
||||
});
|
||||
},10);
|
||||
// Install our event listener to listen out for tiddler changes
|
||||
this.store.addEventListener("",function(changes) {
|
||||
for(var title in changes) {
|
||||
// Get the information about the tiddler
|
||||
var tiddler = self.store.getTiddler(title),
|
||||
changeCount = self.store.getChangeCount(title),
|
||||
lastChangeCount = self.changeCounts[title],
|
||||
files = [];
|
||||
// Construct a changecount record if we don't have one
|
||||
if(!lastChangeCount) {
|
||||
lastChangeCount = 0;
|
||||
self.changeCounts[title] = lastChangeCount;
|
||||
}
|
||||
// Save the tiddler if the changecount has increased
|
||||
if(changeCount > lastChangeCount) {
|
||||
files = self.store.serializeTiddlers([tiddler],"application/x-tiddler");
|
||||
for(var t=0; t<files.length; t++) {
|
||||
self.saveQueue.push(files[t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
exports.FileStore = FileStore;
|
||||
exports.LocalFileSync = LocalFileSync;
|
||||
|
||||
})();
|
@ -380,7 +380,7 @@ Recipe.tiddlerOutputter = {
|
||||
// Ordinary tiddlers are output as a <DIV>
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
var tid = this.store.getTiddler(tiddlers[t]);
|
||||
out.push(this.store.serializeTiddler("application/x-tiddler-html-div",tid),"\n");
|
||||
out.push(this.store.serializeTiddlers([tid],"application/x-tiddler-html-div")[0].data,"\n");
|
||||
}
|
||||
},
|
||||
javascript: function(out,tiddlers) {
|
||||
@ -404,7 +404,7 @@ Recipe.tiddlerOutputter = {
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
var title = tiddlers[t],
|
||||
tid = this.store.shadows.getTiddler(title);
|
||||
out.push(this.store.serializeTiddler("application/x-tiddler-html-div",tid),"\n");
|
||||
out.push(this.store.serializeTiddlers([tid],"application/x-tiddler-html-div")[0].data,"\n");
|
||||
}
|
||||
},
|
||||
title: function(out,tiddlers) {
|
||||
|
@ -1,7 +1,24 @@
|
||||
/*\
|
||||
title: js/TiddlerOutput.js
|
||||
|
||||
Functions concerned with parsing representations of tiddlers
|
||||
Serializers that output tiddlers in a variety of formats.
|
||||
|
||||
store.serializeTiddlers(tiddlers,type)
|
||||
|
||||
tiddlers: An array of tiddler objects
|
||||
type: The target output type as a file extension like `.tid` or a MIME type like `application/x-tiddler`. If `null` or `undefined` then the best type is chosen automatically
|
||||
|
||||
The serializer returns an array of information defining one or more files containing the tiddlers:
|
||||
|
||||
[
|
||||
{name: "title.tid", type: "application/x-tiddler", ext: ".tid", data: "xxxxx"},
|
||||
{name: "title.jpg", type: "image/jpeg", ext: ".jpg", binary: true, data: "xxxxx"},
|
||||
{name: "title.jpg.meta", type: "application/x-tiddler-metadata", ext: ".meta", data: "xxxxx"}
|
||||
]
|
||||
|
||||
Notes:
|
||||
* The `type` field is the type of the file, which is not necessrily the same as the type of the tiddler.
|
||||
* The `binary` field may be omitted if it is not `true`
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@ -14,96 +31,105 @@ var utils = require("./Utils.js"),
|
||||
|
||||
var tiddlerOutput = exports;
|
||||
|
||||
// Utility function to convert a tags string array into a TiddlyWiki-style quoted tags string
|
||||
var stringifyTags = function(tags) {
|
||||
var results = [];
|
||||
for(var t=0; t<tags.length; t++) {
|
||||
if(tags[t].indexOf(" ") !== -1) {
|
||||
results.push("[[" + tags[t] + "]]");
|
||||
} else {
|
||||
results.push(tags[t]);
|
||||
}
|
||||
var outputMetaDataBlock = function(tiddler) {
|
||||
var result = [],
|
||||
fields = tiddler.getFieldStrings(),
|
||||
t;
|
||||
for(t=0; t<fields.length; t++) {
|
||||
result.push(fields[t].name + ": " + fields[t].value);
|
||||
}
|
||||
return results.join(" ");
|
||||
return result.join("\n");
|
||||
};
|
||||
|
||||
/*
|
||||
Output a tiddler as a .tid file
|
||||
Output tiddlers as separate files in their native formats (ie. `.tid` or `.jpg`/`.jpg.meta`)
|
||||
*/
|
||||
var outputTiddler = function(tid) {
|
||||
var result = [],
|
||||
outputAttribute = function(name,value) {
|
||||
result.push(name + ": " + value + "\n");
|
||||
},
|
||||
fields = tid.getFields();
|
||||
for(var t in fields) {
|
||||
switch(t) {
|
||||
case "text":
|
||||
// Ignore the text field
|
||||
var outputTiddlers = function(tiddlers) {
|
||||
var result = [];
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
var tiddler = tiddlers[t],
|
||||
extension,
|
||||
binary = false;
|
||||
switch(tiddler.type) {
|
||||
case "image/jpeg":
|
||||
extension = ".jpg";
|
||||
binary = true;
|
||||
break;
|
||||
case "tags":
|
||||
// Output tags as a list
|
||||
outputAttribute(t,stringifyTags(fields.tags));
|
||||
case "image/gif":
|
||||
extension = ".gif";
|
||||
binary = true;
|
||||
break;
|
||||
case "modified":
|
||||
case "created":
|
||||
// Output dates in YYYYMMDDHHMM
|
||||
outputAttribute(t,utils.convertToYYYYMMDDHHMM(fields[t]));
|
||||
case "image/png":
|
||||
extension = ".png";
|
||||
binary = true;
|
||||
break;
|
||||
case "image/svg+xml":
|
||||
extension = ".svg";
|
||||
break;
|
||||
default:
|
||||
// Output other attributes raw
|
||||
outputAttribute(t,fields[t]);
|
||||
extension = ".tid";
|
||||
break;
|
||||
}
|
||||
if(extension === ".tid") {
|
||||
result.push({
|
||||
name: tiddler.title + ".tid",
|
||||
type: "application/x-tiddler",
|
||||
extension: ".tid",
|
||||
data: outputMetaDataBlock(tiddler) + "\n\n" + tiddler.text,
|
||||
binary: false
|
||||
});
|
||||
} else {
|
||||
result.push({
|
||||
name: tiddler.title,
|
||||
type: tiddler.type,
|
||||
extension: extension,
|
||||
data: tiddler.text,
|
||||
binary: binary
|
||||
});
|
||||
result.push({
|
||||
name: tiddler.title + ".meta",
|
||||
type: "application/x-tiddler-metadata",
|
||||
extension: ".meta",
|
||||
data: outputMetaDataBlock(tiddler),
|
||||
binary: false
|
||||
});
|
||||
}
|
||||
}
|
||||
result.push("\n");
|
||||
result.push(fields.text);
|
||||
return result.join("");
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
Output a tiddler as an HTML <DIV>
|
||||
Output an array of tiddlers as HTML <DIV>s
|
||||
out - array to push the output strings
|
||||
tid - the tiddler to be output
|
||||
The fields are in the order title, creator, modifier, created, modified, tags, followed by any others
|
||||
*/
|
||||
var outputTiddlerDiv = function(tid) {
|
||||
var result = [],
|
||||
fields = tid.getFields(),
|
||||
text = fields.text,
|
||||
outputAttribute = function(name,transform) {
|
||||
if(name in fields) {
|
||||
var value = fields[name];
|
||||
if(transform)
|
||||
value = transform(value);
|
||||
result.push(" " + name + "=\"" + value + "\"");
|
||||
delete fields[name];
|
||||
}
|
||||
};
|
||||
if(fields.text) {
|
||||
delete fields.text;
|
||||
var outputTiddlerDivs = function(tiddlers) {
|
||||
var result = [];
|
||||
for(var t=0; t<tiddlers.length; t++) {
|
||||
var tiddler = tiddlers[t],
|
||||
output = [],
|
||||
fieldStrings = tiddler.getFieldStrings();
|
||||
output.push("<div");
|
||||
for(var f=0; f<fieldStrings.length; f++) {
|
||||
output.push(" " + fieldStrings[f].name + "=\"" + fieldStrings[f].value + "\"");
|
||||
}
|
||||
output.push(">\n<pre>");
|
||||
output.push(utils.htmlEncode(tiddler.text));
|
||||
output.push("</pre>\n</div>");
|
||||
result.push({
|
||||
name: tiddler.title,
|
||||
type: "application/x-tiddler-html-div",
|
||||
extension: ".tiddler",
|
||||
data: output.join("")
|
||||
});
|
||||
}
|
||||
result.push("<div");
|
||||
// Output the standard attributes in the correct order
|
||||
outputAttribute("title");
|
||||
outputAttribute("creator");
|
||||
outputAttribute("modifier");
|
||||
outputAttribute("created", function(v) {return utils.convertToYYYYMMDDHHMM(v);});
|
||||
outputAttribute("modified", function(v) {return utils.convertToYYYYMMDDHHMM(v);});
|
||||
outputAttribute("tags", function(v) {return stringifyTags(v);});
|
||||
// Output any other attributes
|
||||
for(var t in fields) {
|
||||
outputAttribute(t,null,true);
|
||||
}
|
||||
result.push(">\n<pre>");
|
||||
result.push(utils.htmlEncode(text));
|
||||
result.push("</pre>\n</div>");
|
||||
return result.join("");
|
||||
return result;
|
||||
};
|
||||
|
||||
tiddlerOutput.register = function(store) {
|
||||
store.registerTiddlerSerializer(".tid","application/x-tiddler",outputTiddler);
|
||||
store.registerTiddlerSerializer(".tiddler","application/x-tiddler-html-div",outputTiddlerDiv);
|
||||
store.registerTiddlerSerializer(".tid","application/x-tiddler",outputTiddlers);
|
||||
store.registerTiddlerSerializer(".tiddler","application/x-tiddler-html-div",outputTiddlerDivs);
|
||||
};
|
||||
|
||||
})();
|
||||
|
@ -28,6 +28,7 @@ var WikiStore = function WikiStore(options) {
|
||||
this.parsers = {}; // Hashmap of parsers by accepted MIME type
|
||||
this.macros = {}; // Hashmap of macros by macro name
|
||||
this.caches = {}; // Hashmap of cache objects by tiddler title, each is a hashmap of named caches
|
||||
this.changeCount = {}; // Hashmap of integer changecount (>1) for each tiddler; persistent across deletions
|
||||
this.tiddlerSerializers = {}; // Hashmap of serializers by target MIME type
|
||||
this.tiddlerDeserializers = {}; // Hashmap of deserializers by accepted MIME type
|
||||
this.eventListeners = []; // Array of {filter:,listener:}
|
||||
@ -38,6 +39,22 @@ var WikiStore = function WikiStore(options) {
|
||||
});
|
||||
};
|
||||
|
||||
WikiStore.prototype.incChangeCount = function(title) {
|
||||
if(this.changeCount.hasOwnProperty(title)) {
|
||||
this.changeCount[title]++;
|
||||
} else {
|
||||
this.changeCount[title] = 1;
|
||||
}
|
||||
};
|
||||
|
||||
WikiStore.prototype.getChangeCount = function(title) {
|
||||
if(this.changeCount.hasOwnProperty(title)) {
|
||||
return this.changeCount[title];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
WikiStore.prototype.registerParser = function(type,parser) {
|
||||
if(type instanceof Array) {
|
||||
for(var t=0; t<type.length; t++) {
|
||||
@ -96,6 +113,10 @@ WikiStore.prototype.touchTiddler = function(type,title) {
|
||||
this.triggerEvents();
|
||||
};
|
||||
|
||||
WikiStore.prototype.clearEvents = function() {
|
||||
this.changedTiddlers = {};
|
||||
};
|
||||
|
||||
/*
|
||||
Trigger the execution of the event dispatcher at the next tick, if it is not already triggered
|
||||
*/
|
||||
@ -133,6 +154,7 @@ WikiStore.prototype.getTiddlerText = function(title,defaultText) {
|
||||
};
|
||||
|
||||
WikiStore.prototype.deleteTiddler = function(title) {
|
||||
this.incChangeCount(title);
|
||||
delete this.tiddlers[title];
|
||||
this.clearCache(title);
|
||||
this.touchTiddler("deleted",title);
|
||||
@ -153,6 +175,7 @@ WikiStore.prototype.addTiddler = function(tiddler) {
|
||||
if(!(tiddler instanceof Tiddler)) {
|
||||
tiddler = new Tiddler(tiddler);
|
||||
}
|
||||
this.incChangeCount(tiddler.title);
|
||||
var status = tiddler.title in this.tiddlers ? "modified" : "created";
|
||||
this.clearCache(tiddler.title);
|
||||
this.tiddlers[tiddler.title] = tiddler;
|
||||
@ -213,10 +236,11 @@ WikiStore.prototype.getShadowTitles = function() {
|
||||
return this.shadows ? this.shadows.getTitles() : [];
|
||||
};
|
||||
|
||||
WikiStore.prototype.serializeTiddler = function(type,tiddler) {
|
||||
WikiStore.prototype.serializeTiddlers = function(tiddlers,type) {
|
||||
type = type || "application/x-tiddler";
|
||||
var serializer = this.tiddlerSerializers[type];
|
||||
if(serializer) {
|
||||
return serializer(tiddler);
|
||||
return serializer(tiddlers);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ exports.macro = {
|
||||
for(var t=0; t<story.tiddlers.length; t++) {
|
||||
var storyRecord = story.tiddlers[t];
|
||||
if(storyRecord.title === event.tiddlerTitle && storyRecord.template !== template) {
|
||||
storyRecord.title = "Draft of " + event.tiddlerTitle + " at " + (new Date());
|
||||
storyRecord.title = "Draft " + (new Date()) + " of " + event.tiddlerTitle;
|
||||
storyRecord.template = template;
|
||||
var tiddler = this.store.getTiddler(event.tiddlerTitle);
|
||||
this.store.addTiddler(new Tiddler(
|
||||
|
@ -9,7 +9,7 @@ TiddlyWiki command line interface
|
||||
|
||||
var App = require("./js/App.js").App,
|
||||
WikiStore = require("./js/WikiStore.js").WikiStore,
|
||||
FileStore = require("./js/FileStore.js").FileStore,
|
||||
LocalFileSync = require("./js/LocalFileSync.js").LocalFileSync,
|
||||
Tiddler = require("./js/Tiddler.js").Tiddler,
|
||||
Recipe = require("./js/Recipe.js").Recipe,
|
||||
tiddlerInput = require("./js/TiddlerInput.js"),
|
||||
@ -47,8 +47,9 @@ var parseOptions = function(args,defaultSwitch) {
|
||||
};
|
||||
|
||||
var switches = parseOptions(Array.prototype.slice.call(process.argv,2),"dummy"),
|
||||
verbose = false,
|
||||
recipe = null,
|
||||
fileStore = null,
|
||||
localFileSync = null,
|
||||
lastRecipeFilepath = null,
|
||||
currSwitch = 0;
|
||||
|
||||
@ -111,7 +112,7 @@ var commandLineSwitches = {
|
||||
store: {
|
||||
args: {min: 1, max: 1},
|
||||
handler: function(args,callback) {
|
||||
fileStore = new FileStore(args[0],app.store,function() {
|
||||
localFileSync = new LocalFileSync(args[0],app.store,function() {
|
||||
callback(null);
|
||||
});
|
||||
}
|
||||
@ -149,7 +150,7 @@ var commandLineSwitches = {
|
||||
recipe = [];
|
||||
app.store.forEachTiddler(function(title,tiddler) {
|
||||
var filename = encodeURIComponent(tiddler.title.replace(/ /g,"_")) + ".tid";
|
||||
fs.writeFileSync(path.resolve(outdir,filename),app.store.serializeTiddler("application/x-tiddler",tiddler),"utf8");
|
||||
fs.writeFileSync(path.resolve(outdir,filename),app.store.serializeTiddlers([tiddler],"application/x-tiddler")[0].data,"utf8");
|
||||
recipe.push("tiddler: " + filename + "\n");
|
||||
});
|
||||
fs.writeFileSync(path.join(args[0],"split.recipe"),recipe.join(""));
|
||||
@ -174,11 +175,33 @@ var commandLineSwitches = {
|
||||
callback("--servewiki must be preceded by a --recipe");
|
||||
}
|
||||
var port = args.length > 0 ? args[0] : 8000;
|
||||
// Dumbly, this implementation wastes the recipe processing that happened on the --recipe switch
|
||||
http.createServer(function(request, response) {
|
||||
response.writeHead(200, {"Content-Type": "text/html"});
|
||||
response.end(recipe.cook(), "utf8");
|
||||
var path = url.parse(request.url).pathname;
|
||||
switch(request.method) {
|
||||
case "PUT":
|
||||
var data = "";
|
||||
request.on("data",function(chunk) {
|
||||
data += chunk.toString();
|
||||
});
|
||||
request.on("end",function() {
|
||||
var title = decodeURIComponent(path.substr(1));
|
||||
app.store.addTiddler(new Tiddler(JSON.parse(data),{title: title}));
|
||||
response.writeHead(204, "OK");
|
||||
response.end();
|
||||
});
|
||||
break;
|
||||
case "GET":
|
||||
if(path === "/") {
|
||||
response.writeHead(200, {"Content-Type": "text/html"});
|
||||
response.end(recipe.cook(), "utf8");
|
||||
} else {
|
||||
response.writeHead(404);
|
||||
response.end();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}).listen(port);
|
||||
process.nextTick(function() {callback(null);});
|
||||
}
|
||||
},
|
||||
servetiddlers: {
|
||||
@ -196,11 +219,13 @@ var commandLineSwitches = {
|
||||
response.end();
|
||||
}
|
||||
}).listen(port);
|
||||
process.nextTick(function() {callback(null);});
|
||||
}
|
||||
},
|
||||
verbose: {
|
||||
args: {min: 0, max: 0},
|
||||
handler: function(args,callback) {
|
||||
verbose = true;
|
||||
process.nextTick(function() {callback(null);});
|
||||
}
|
||||
},
|
||||
@ -245,6 +270,7 @@ var commandLineSwitches = {
|
||||
}
|
||||
}
|
||||
}
|
||||
process.nextTick(function() {callback(null);});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -259,6 +285,9 @@ var processNextSwitch = function() {
|
||||
if(s.args.length > csw.args.max) {
|
||||
throw "Command line switch --" + s.switchName + " should have a maximum of " + csw.args.max + " arguments";
|
||||
}
|
||||
if(verbose) {
|
||||
console.log("Processing --" + s.switchName + " " + s.args.join(" "));
|
||||
}
|
||||
csw.handler(s.args,function (err) {
|
||||
if(err) {
|
||||
throw "Error while executing option '--" + s.switchName + "' was:\n" + err;
|
||||
|
Loading…
Reference in New Issue
Block a user