1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-28 22:01:26 +00:00

Add support for remote commands

Makes it possible to invoke any of TW5's Node.js commands from the browser. Useful for the new pipe command, but also handy for e.g. rendering tiddlers on the server, fetching remote files, or importing local files etc

Docs to come.
This commit is contained in:
Jermolene
2018-10-14 18:34:55 +01:00
parent 4fcbaa2b12
commit f2917c3355
3 changed files with 102 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
/*\
title: $:/core/modules/server/routes/post-commands.js
type: application/javascript
module-type: route
POST /commands/
\*/
(function() {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.method = "POST";
exports.path = /^\/commands\/$/;
exports.handler = function(request,response,state) {
// Check we're enabled
console.log("wikiInfo",$tw.boot.wikiInfo)
if(!($tw.boot.wikiInfo.config || {})["allow-remote-commands"]) {
response.writeHead(404);
response.end();
return;
}
// Get the job descriptor
var jobDescriptor = JSON.parse(state.data);
console.log("JOB START:",jobDescriptor)
// Respond OK
response.writeHead(204, "OK",{
"Content-Type": "application/json"
});
// Maintain status
var setStatus = function(status,message) {
if(jobDescriptor.statusTitle) {
state.wiki.addTiddler(new $tw.Tiddler({title: jobDescriptor.statusTitle,text: status,message: message}));
}
}
setStatus("started");
// Initiate the commands
var commander = new $tw.Commander(
jobDescriptor.commands || [],
function(err) {
setStatus(err ? "error" : "ok",err ? err : undefined);
console.log("JOB END:",err)
},
state.wiki,
{output: process.stdout, error: process.stderr}
);
commander.execute();
// Return results
response.end(JSON.stringify({}),"utf8"); // Nothing useful for us to return
};
}());

View File

@@ -84,6 +84,11 @@ function Syncer(options) {
$tw.rootWidget.addEventListener("tm-server-refresh",function() {
self.handleRefreshEvent();
});
$tw.rootWidget.addEventListener("tm-execute-job",function(event) {
if(self.syncadaptor && self.syncadaptor.executeJob) {
self.syncadaptor.executeJob(event);
}
});
}
// Listen out for lazyLoad events
if(!this.disableUI) {

View File

@@ -140,6 +140,46 @@ TiddlyWebAdaptor.prototype.getCsrfToken = function() {
return csrf;
};
/*
*/
TiddlyWebAdaptor.prototype.executeJob = function(event,callback) {
var paramObject = event.paramObject || {};
// Collect the commands
var commands;
if(paramObject.commands) {
commands = $tw.utils.parseStringArray(paramObject.commands);
} else {
// Get the values of the numeric parameters and sort them by their numeric name
commands = Object.keys(paramObject).filter(function(name) {
// We just include parameters that are identical to their numeric representation
return (parseInt(name,10) + "") === name;
}).map(function(name) {
return parseInt(name,10);
}).sort().map(function(index) {
return paramObject[index + ""];
});
}
// Compose the request
var options = {
url: this.host + "commands/",
type: "POST",
data: JSON.stringify({
commands: commands,
statusTitle: paramObject.statusTitle,
outputTitle: paramObject.outputTitle,
errorTitle: paramObject.errorTitle
}),
callback: function(err,data) {
if(callback) {
callback(err,data);
}
}
};
// Send the request
this.logger.log("Executing job:",options);
$tw.utils.httpRequest(options);
};
/*
Get an array of skinny tiddler fields from the server
*/