mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 18:17:20 +00:00
69528093d9
Astonishingly, node.js appears to require us to do this manually…
176 lines
4.7 KiB
JavaScript
176 lines
4.7 KiB
JavaScript
/*\
|
|
title: $:/core/modules/commands/fetch.js
|
|
type: application/javascript
|
|
module-type: command
|
|
|
|
Commands to fetch external tiddlers
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
exports.info = {
|
|
name: "fetch",
|
|
synchronous: false
|
|
};
|
|
|
|
var Command = function(params,commander,callback) {
|
|
this.params = params;
|
|
this.commander = commander;
|
|
this.callback = callback;
|
|
};
|
|
|
|
Command.prototype.execute = function() {
|
|
if(this.params.length < 2) {
|
|
return "Missing subcommand and url";
|
|
}
|
|
switch(this.params[0]) {
|
|
case "raw-file":
|
|
return this.fetchFiles({
|
|
raw: true,
|
|
url: this.params[1],
|
|
transformFilter: this.params[2] || "",
|
|
callback: this.callback
|
|
});
|
|
break;
|
|
case "file":
|
|
return this.fetchFiles({
|
|
url: this.params[1],
|
|
importFilter: this.params[2],
|
|
transformFilter: this.params[3] || "",
|
|
callback: this.callback
|
|
});
|
|
break;
|
|
case "raw-files":
|
|
return this.fetchFiles({
|
|
raw: true,
|
|
urlFilter: this.params[1],
|
|
transformFilter: this.params[2] || "",
|
|
callback: this.callback
|
|
});
|
|
break;
|
|
case "files":
|
|
return this.fetchFiles({
|
|
urlFilter: this.params[1],
|
|
importFilter: this.params[2],
|
|
transformFilter: this.params[3] || "",
|
|
callback: this.callback
|
|
});
|
|
break;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
Command.prototype.fetchFiles = function(options) {
|
|
var self = this;
|
|
// Get the list of URLs
|
|
var urls;
|
|
if(options.url) {
|
|
urls = [options.url]
|
|
} else if(options.urlFilter) {
|
|
urls = $tw.wiki.filterTiddlers(options.urlFilter);
|
|
} else {
|
|
return "Missing URL";
|
|
}
|
|
// Process each URL in turn
|
|
var next = 0;
|
|
var getNextFile = function(err) {
|
|
if(err) {
|
|
return options.callback(err);
|
|
}
|
|
if(next < urls.length) {
|
|
self.fetchFile(urls[next++],options,getNextFile);
|
|
} else {
|
|
options.callback(null);
|
|
}
|
|
};
|
|
getNextFile(null);
|
|
// Success
|
|
return null;
|
|
};
|
|
|
|
Command.prototype.fetchFile = function(url,options,callback,redirectCount) {
|
|
if(redirectCount > 10) {
|
|
return callback("Error too many redirects retrieving " + url);
|
|
}
|
|
var self = this,
|
|
lib = url.substr(0,8) === "https://" ? require("https") : require("http");
|
|
lib.get(url).on("response",function(response) {
|
|
var type = (response.headers["content-type"] || "").split(";")[0],
|
|
data = [];
|
|
self.commander.write("Reading " + url + ": ");
|
|
response.on("data",function(chunk) {
|
|
data.push(chunk);
|
|
self.commander.write(".");
|
|
});
|
|
response.on("end",function() {
|
|
self.commander.write("\n");
|
|
if(response.statusCode === 200) {
|
|
self.processBody(Buffer.concat(data),type,options,url);
|
|
callback(null);
|
|
} else {
|
|
if(response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
|
|
return self.fetchFile(response.headers.location,options,callback,redirectCount + 1);
|
|
} else {
|
|
return callback("Error " + response.statusCode + " retrieving " + url)
|
|
}
|
|
}
|
|
});
|
|
response.on("error",function(e) {
|
|
console.log("Error on GET request: " + e);
|
|
callback(e);
|
|
});
|
|
});
|
|
return null;
|
|
};
|
|
|
|
Command.prototype.processBody = function(body,type,options,url) {
|
|
var self = this;
|
|
// Collect the tiddlers in a wiki
|
|
var incomingWiki = new $tw.Wiki();
|
|
if(options.raw) {
|
|
var typeInfo = type ? $tw.config.contentTypeInfo[type] : null,
|
|
encoding = typeInfo ? typeInfo.encoding : "utf8";
|
|
incomingWiki.addTiddler(new $tw.Tiddler({
|
|
title: url,
|
|
type: type,
|
|
text: body.toString(encoding)
|
|
}));
|
|
} else {
|
|
// Deserialise the file to extract the tiddlers
|
|
var tiddlers = this.commander.wiki.deserializeTiddlers(type || "text/html",body.toString("utf8"),{});
|
|
$tw.utils.each(tiddlers,function(tiddler) {
|
|
incomingWiki.addTiddler(new $tw.Tiddler(tiddler));
|
|
});
|
|
}
|
|
// Filter the tiddlers to select the ones we want
|
|
var filteredTitles = incomingWiki.filterTiddlers(options.importFilter || "[all[tiddlers]]");
|
|
// Import the selected tiddlers
|
|
var count = 0;
|
|
incomingWiki.each(function(tiddler,title) {
|
|
if(filteredTitles.indexOf(title) !== -1) {
|
|
var newTiddler;
|
|
if(options.transformFilter) {
|
|
var transformedTitle = (incomingWiki.filterTiddlers(options.transformFilter,null,self.commander.wiki.makeTiddlerIterator([title])) || [""])[0];
|
|
if(transformedTitle) {
|
|
self.commander.log("Importing " + title + " as " + transformedTitle)
|
|
newTiddler = new $tw.Tiddler(tiddler,{title: transformedTitle});
|
|
}
|
|
} else {
|
|
self.commander.log("Importing " + title)
|
|
newTiddler = tiddler;
|
|
}
|
|
self.commander.wiki.importTiddler(newTiddler);
|
|
count++;
|
|
}
|
|
});
|
|
self.commander.log("Imported " + count + " tiddlers")
|
|
};
|
|
|
|
exports.Command = Command;
|
|
|
|
})();
|