From a346888213b454fbdaf14364c7b4702e3b4b7c9e Mon Sep 17 00:00:00 2001 From: Jermolene Date: Mon, 3 Jul 2017 20:34:58 +0100 Subject: [PATCH] Add first release of AWS plugin Tools for working with Amazon Web Services: * Templates for saving a TiddlyWiki as a single JavaScript file in a ZIP file that can be executed as an AWS Lambda function. In this form, TiddlyWiki is a self contained single file containing both code and data, just like the standalone HTML file configuration * Commands that can be used to interact with AWS services, under both the Node.js and Lambda configurations of TiddlyWiki --- editions/aws/tiddlers/HelloThere.tid | 3 + editions/aws/tiddlywiki.info | 18 +++ .../plugins/Amazon Web Services Plugin.tid | 10 ++ plugins/tiddlywiki/aws/docs/commands.tid | 3 + plugins/tiddlywiki/aws/docs/help.tid | 39 ++++++ plugins/tiddlywiki/aws/docs/lambda.tid | 40 ++++++ plugins/tiddlywiki/aws/docs/readme.tid | 6 + plugins/tiddlywiki/aws/docs/setup.tid | 51 ++++++++ plugins/tiddlywiki/aws/modules/command.js | 121 ++++++++++++++++++ plugins/tiddlywiki/aws/modules/init.js | 37 ++++++ plugins/tiddlywiki/aws/modules/utils.js | 36 ++++++ plugins/tiddlywiki/aws/plugin.info | 7 + .../aws/templates/lambda/handler.tid | 26 ++++ .../tiddlywiki/aws/templates/lambda/main.tid | 19 +++ .../aws/templates/lambda/package-info.tid | 11 ++ .../tiddlywiki/aws/templates/lambda/sjcl.tid | 17 +++ .../aws/templates/lambda/tiddlers.tid | 5 + 17 files changed, 449 insertions(+) create mode 100644 editions/aws/tiddlers/HelloThere.tid create mode 100644 editions/aws/tiddlywiki.info create mode 100644 editions/tw5.com/tiddlers/plugins/Amazon Web Services Plugin.tid create mode 100644 plugins/tiddlywiki/aws/docs/commands.tid create mode 100644 plugins/tiddlywiki/aws/docs/help.tid create mode 100644 plugins/tiddlywiki/aws/docs/lambda.tid create mode 100644 plugins/tiddlywiki/aws/docs/readme.tid create mode 100644 plugins/tiddlywiki/aws/docs/setup.tid create mode 100644 plugins/tiddlywiki/aws/modules/command.js create mode 100644 plugins/tiddlywiki/aws/modules/init.js create mode 100644 plugins/tiddlywiki/aws/modules/utils.js create mode 100644 plugins/tiddlywiki/aws/plugin.info create mode 100644 plugins/tiddlywiki/aws/templates/lambda/handler.tid create mode 100644 plugins/tiddlywiki/aws/templates/lambda/main.tid create mode 100644 plugins/tiddlywiki/aws/templates/lambda/package-info.tid create mode 100644 plugins/tiddlywiki/aws/templates/lambda/sjcl.tid create mode 100644 plugins/tiddlywiki/aws/templates/lambda/tiddlers.tid diff --git a/editions/aws/tiddlers/HelloThere.tid b/editions/aws/tiddlers/HelloThere.tid new file mode 100644 index 000000000..8a6dc6c21 --- /dev/null +++ b/editions/aws/tiddlers/HelloThere.tid @@ -0,0 +1,3 @@ +title: HelloThere + +This wiki provides a starting point for working with the AWS plugin for TiddlyWiki under Node.js. diff --git a/editions/aws/tiddlywiki.info b/editions/aws/tiddlywiki.info new file mode 100644 index 000000000..52f419699 --- /dev/null +++ b/editions/aws/tiddlywiki.info @@ -0,0 +1,18 @@ +{ + "description": "Amazon Web Services edition", + "plugins": [ + "tiddlywiki/async", + "tiddlywiki/jszip", + "tiddlywiki/aws" + ], + "themes": [ + "tiddlywiki/vanilla", + "tiddlywiki/snowwhite" + ], + "build": { + "index": [ + "--rendertiddler","$:/core/save/all","index.html","text/plain"], + "lambda": [ + "--rendertiddler","$:/plugins/tiddlywiki/aws/lambdas/main","index.js","text/plain"] + } +} diff --git a/editions/tw5.com/tiddlers/plugins/Amazon Web Services Plugin.tid b/editions/tw5.com/tiddlers/plugins/Amazon Web Services Plugin.tid new file mode 100644 index 000000000..d5cc22fa5 --- /dev/null +++ b/editions/tw5.com/tiddlers/plugins/Amazon Web Services Plugin.tid @@ -0,0 +1,10 @@ +created: 20170703193252423 +modified: 20170703193353918 +tags: OfficialPlugins +title: Amazon Web Services Plugin +type: text/vnd.tiddlywiki + +The Amazon Web Services Plugin provides several tools for working with Amazon Web Services: + +* Templates for saving a TiddlyWiki as a single JavaScript file in a ZIP file that can be executed as an AWS Lambda function. In this form, TiddlyWiki is a self contained single file containing both code and data, just like the standalone HTML file configuration +* Commands that can be used to interact with AWS services, under both the Node.js and Lambda configurations of TiddlyWiki diff --git a/plugins/tiddlywiki/aws/docs/commands.tid b/plugins/tiddlywiki/aws/docs/commands.tid new file mode 100644 index 000000000..5fab718c4 --- /dev/null +++ b/plugins/tiddlywiki/aws/docs/commands.tid @@ -0,0 +1,3 @@ +title: $:/plugins/tiddlywiki/aws/commands + +{{$:/language/Help/aws}} diff --git a/plugins/tiddlywiki/aws/docs/help.tid b/plugins/tiddlywiki/aws/docs/help.tid new file mode 100644 index 000000000..b675eb64f --- /dev/null +++ b/plugins/tiddlywiki/aws/docs/help.tid @@ -0,0 +1,39 @@ +title: $:/language/Help/aws +description: Operations for working with Amazon Web Services + +! Commands + +Perform operation on Amazon Web Services + +``` +--aws [ ...] +``` + +! "s3-savetiddler" subcommand + +Save a raw tiddler to a file in an S3 bucket. + +``` +--aws s3-savetiddler <region> <bucket> <filename> <zipfilename> +``` + +* ''title'': title of the tiddler to save +* ''bucket'': name of the bucket to save the saved file +* ''filename'': filename of the saved file +* ''zipfilename'': optional; the file will be packed into a ZIP file with the specified name + +! "s3-rendertiddler" subcommand + +Save the results of rendering a tiddler to a file in an S3 bucket. + +``` +--aws s3-rendertiddler <title> <region> <bucket> <filename> <type> <template> <zipfilename> <savetype> +``` + +* ''title'': title of the tiddler to render +* ''bucket'': name of the bucket to save the rendered file +* ''filename'': filename of the rendered file +* ''type'': optional render type (defaults to "text/html") +* ''template'': optional template (defaults to directly rendering the tiddler without using a template) +* ''zipfilename'': optional; the file will be packed into a ZIP file with the specified name +* ''savetype'': optional; the MIME type for the saved file (defaults to ''type'' or "text/html") diff --git a/plugins/tiddlywiki/aws/docs/lambda.tid b/plugins/tiddlywiki/aws/docs/lambda.tid new file mode 100644 index 000000000..b053f4d12 --- /dev/null +++ b/plugins/tiddlywiki/aws/docs/lambda.tid @@ -0,0 +1,40 @@ +title: $:/plugins/tiddlywiki/aws/lambda + +! Template + +The template [[$:/plugins/tiddlywiki/aws/lambdas/main]] transcludes everything required to render a TiddlyWiki as an AWS Lambda function. + +The Lambda is build with this command: + +``` +tiddlywiki editions/aws --rendertiddler $:/plugins/tiddlywiki/aws/lambdas/main index.js text/plain +``` + +Or: + +``` +tiddlywiki editions/aws --build lambda +``` + +! Execution + +The Lambda boot code looks for an array of tiddlers to load in `event.tiddlers`, and an array of commands to execute in `event.commands`. For example: + +``` +{ + "commands": [ + "--aws","s3-rendertiddler","HelloThere","eu-west-2","my-bucket-name","rendered.html" + ], + "tiddlers": [ + { + "title": "HelloThere", + "text": "Hello from {{Platform}}." + }, + { + "title": "Platform", + "text": "TiddlyWiki" + } + ] +} + +``` diff --git a/plugins/tiddlywiki/aws/docs/readme.tid b/plugins/tiddlywiki/aws/docs/readme.tid new file mode 100644 index 000000000..3677cbb71 --- /dev/null +++ b/plugins/tiddlywiki/aws/docs/readme.tid @@ -0,0 +1,6 @@ +title: $:/plugins/tiddlywiki/aws/readme + +This plugin provides several tools for working with Amazon Web Services: + +* Templates for saving a TiddlyWiki as a single JavaScript file in a ZIP file that can be executed as an AWS Lambda function. In this form, TiddlyWiki is a self contained single file containing both code and data, just like the standalone HTML file configuration +* Commands that can be used to interact with AWS services, under both the Node.js and Lambda configurations of TiddlyWiki diff --git a/plugins/tiddlywiki/aws/docs/setup.tid b/plugins/tiddlywiki/aws/docs/setup.tid new file mode 100644 index 000000000..7a358d289 --- /dev/null +++ b/plugins/tiddlywiki/aws/docs/setup.tid @@ -0,0 +1,51 @@ +title: $:/plugins/tiddlywiki/aws/setup + +! Introduction + +!! About Amazon Web Services + +Amazon Web Services is a collection of online APIs to services that allow cloud-based applications to be built. It is a commercial service that charges usage fees, but there is a free tier that is sufficient for most personal use. + +An ordinary Amazon account can be used to sign into the AWS console at https://aws.amazon.com/console/. Here you can see a menu of the available services and use interactive dashboards to inspect and configure resources. + +! Getting Started + +!! Setup Amazon Credentials + +The main root account has super-user privileges across all the resources owned by the account. The Identity and Access Management (IAM) service allows subsidiary user accounts to be created for specific tasks. Here we create a new user account for running TiddlyWiki code: + +# Visit the AWS console at https://aws.amazon.com/console/ +# Choose ''IAM'' from the ''Services'' dropdown menu +# Choose ''Users'' from the left hand menu +# Click the ''Create New Users'' button +# Enter ''tiddlywiki'' as the first user name +# Check the box labelled //Generate an access key for each user// +# Click the ''Create'' button +# Click the ''Download Credentials'' button to download a file called "credentials.csv" +#* The file contains three values: +#*# ''User Name'': Username for +#*# ''Password'': +#*# ''Direct Signin Link'': +# Create a text file with the following content: +#> <div><pre><code>[default] +aws_access_key_id = <your access key> +aws_secret_access_key = <your secret access key> +</code></pre></div> +# Save the file as `~/.aws/credentials` (Mac/Linux) or `?` (Windows) + +!! Download or Clone TiddlyWiki Repository + +Even if you have already installed TiddlyWiki, you should create a new installation for working with the AWS plugin. + +Visit the TiddlyWiki5 repository at https://github.com/Jermolene/TiddlyWiki5. You can either download or clone a copy: + +* Download to get up and running quickly +* Clone to make it easier to upgrade in the future + +!! Install `aws-sdk` + +Open a command terminal, switch to the directory where TiddlyWiki is installed and run the following command: + +``` +npm install aws-sdk +``` diff --git a/plugins/tiddlywiki/aws/modules/command.js b/plugins/tiddlywiki/aws/modules/command.js new file mode 100644 index 000000000..a00dab292 --- /dev/null +++ b/plugins/tiddlywiki/aws/modules/command.js @@ -0,0 +1,121 @@ +/*\ +title: $:/plugins/tiddlywiki/aws/command.js +type: application/javascript +module-type: command + +--aws command + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +var async, + awsUtils; + +exports.info = { + name: "aws", + synchronous: false +}; + +var Command = function(params,commander,callback) { + async = require("$:/plugins/tiddlywiki/async/async.js"); + awsUtils = require("$:/plugins/tiddlywiki/aws/utils.js"); + this.params = params; + this.commander = commander; + this.callback = callback; +}; + +Command.prototype.execute = function() { + var self = this, + wiki = this.commander.wiki, + subCommand = this.params[0], + fn = this.subCommands[subCommand]; + if(!fn) { + return this.callback("AWS: Unknown subcommand") + } + fn.bind(this)(); + return null; +}; + +Command.prototype.subCommands = {}; + +// Render a tiddler to an S3 bucket +Command.prototype.subCommands["s3-rendertiddler"] = function() { + var self = this, + wiki = this.commander.wiki, + title = this.params[1], + region = this.params[2], + bucket = this.params[3], + filename = this.params[4], + type = this.params[5] || "text/html", + template = this.params[6], + zipfilename = this.params[7], + saveType = this.params[8] || type, + variables = {}; + // Process the template if present + if(template) { + variables.currentTiddler = title; + title = template; + } + // Render the tiddler + var text = this.commander.wiki.renderTiddler(type,title,{variables: variables}), + type = "text/plain", + encoding = ($tw.config.contentTypeInfo[type] || {encoding: "utf8"}).encoding; + // Zip it if needed + if(zipfilename) { + var JSZip = require("$:/plugins/tiddlywiki/jszip/jszip.js"), + zip = new JSZip(); + zip.file(filename,new Buffer(text,encoding)); + text = zip.generate({type: "base64"}); + type = "application/zip"; + filename = zipfilename; + } + // Save the file + async.series([ + awsUtils.putFile.bind(null,region,bucket,filename,text,saveType) + ], + function(err,results){ + self.callback(err,results); + }); + return null; +}; + +// Save a tiddler to an S3 bucket +Command.prototype.subCommands["s3-savetiddler"] = function() { + var self = this, + wiki = this.commander.wiki, + title = this.params[1], + region = this.params[2], + bucket = this.params[3], + filename = this.params[4], + zipfilename = this.params[5], + tiddler = wiki.getTiddler(title), + text = tiddler.fields.text, + type = tiddler.fields.type, + encoding = ($tw.config.contentTypeInfo[type] || {encoding: "utf8"}).encoding; + // Zip it if needed + if(zipfilename) { + var JSZip = require("$:/plugins/tiddlywiki/jszip/jszip.js"), + zip = new JSZip(); + zip.file(filename,new Buffer(text,encoding)); + text = zip.generate({type: "base64"}); + type = "application/zip"; + filename = zipfilename; + } + // Save the file + async.series([ + awsUtils.putFile.bind(null,region,bucket,filename,text,type) + ], + function(err,results){ + self.callback(err,results); + }); + return null; +}; + +exports.Command = Command; + +})(); + diff --git a/plugins/tiddlywiki/aws/modules/init.js b/plugins/tiddlywiki/aws/modules/init.js new file mode 100644 index 000000000..b0b7d3c71 --- /dev/null +++ b/plugins/tiddlywiki/aws/modules/init.js @@ -0,0 +1,37 @@ +/*\ +title: $:/plugins/tiddlywiki/aws/init.js +type: application/javascript +module-type: startup + +AWS initialisation + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +// Export name and synchronous status +exports.name = "aws-init"; +exports.before = ["startup"]; +exports.synchronous = true; + +exports.startup = function() { + var logger = new $tw.utils.Logger("aws"); + if($tw.node) { + try { + require("aws-sdk"); + } catch(e) { + logger.alert("The plugin 'tiddlywiki/aws' requires the aws-sdk to be installed. Run 'npm install aws-sdk' in the root of the TiddlyWiki repository"); + } + } + if(!$tw.modules.titles["$:/plugins/tiddlywiki/async/async.js"]) { + logger.alert("The plugin 'tiddlywiki/aws' requires the 'tiddlywiki/async' plugin to be installed"); + } + if(!$tw.modules.titles["$:/plugins/tiddlywiki/jszip/jszip.js"]) { + logger.alert("The plugin 'tiddlywiki/aws' requires the 'tiddlywiki/jszip' plugin to be installed"); + } +}; + +})(); diff --git a/plugins/tiddlywiki/aws/modules/utils.js b/plugins/tiddlywiki/aws/modules/utils.js new file mode 100644 index 000000000..1b11acb5f --- /dev/null +++ b/plugins/tiddlywiki/aws/modules/utils.js @@ -0,0 +1,36 @@ +/*\ +title: $:/plugins/tiddlywiki/aws/utils.js +type: application/javascript +module-type: library + +AWS utility functions + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +/* +Put a file to an S3 bucket +*/ +function putFile(region,bucketName,title,text,type,callback) { +console.log("Writing file",bucketName,title,type) + var AWS = require("aws-sdk"), + s3bucket = new AWS.S3({ + region: region + }), + encoding = ($tw.config.contentTypeInfo[type] || {encoding: "utf8"}).encoding, + params = { + Bucket: bucketName, + Key: title, + Body: new Buffer(text,encoding), + ContentType: type || "text/plain" + }; + s3bucket.upload(params,callback); +} + +exports.putFile = putFile; + +})(); diff --git a/plugins/tiddlywiki/aws/plugin.info b/plugins/tiddlywiki/aws/plugin.info new file mode 100644 index 000000000..08ee1fd44 --- /dev/null +++ b/plugins/tiddlywiki/aws/plugin.info @@ -0,0 +1,7 @@ +{ + "title": "$:/plugins/tiddlywiki/aws", + "description": "Tools for working with Amazon Web Services", + "author": "JeremyRuston", + "core-version": ">=5.0.0", + "list": "readme setup commands lambda" +} diff --git a/plugins/tiddlywiki/aws/templates/lambda/handler.tid b/plugins/tiddlywiki/aws/templates/lambda/handler.tid new file mode 100644 index 000000000..12e82395c --- /dev/null +++ b/plugins/tiddlywiki/aws/templates/lambda/handler.tid @@ -0,0 +1,26 @@ +title: $:/plugins/tiddlywiki/aws/lambda/handler +type: text/plain + +/* +TiddlyWiki for AWS +*/ + +exports.handler = function(event,context,callback) { + // Initialise the boot prefix + global.$tw = _bootprefix(); + // Some default package info + $tw.packageInfo = lambdaPackageInfo; + // Load any tiddlers from the package + $tw.preloadTiddlerArray(lambdaTiddlers); + // Load any tiddlers from the event + if(event.tiddlers) { + $tw.preloadTiddlerArray(event.tiddlers); + } + // Load the commands from the event + $tw.boot.argv = (event.commands || []).slice(0); + // Boot the TW5 app + _boot($tw); + $tw.boot.boot(function() { + callback(null,"TiddlyWiki execution successful"); + }); +} diff --git a/plugins/tiddlywiki/aws/templates/lambda/main.tid b/plugins/tiddlywiki/aws/templates/lambda/main.tid new file mode 100644 index 000000000..1a7b6f7aa --- /dev/null +++ b/plugins/tiddlywiki/aws/templates/lambda/main.tid @@ -0,0 +1,19 @@ +title: $:/plugins/tiddlywiki/aws/lambdas/main + +\rules only filteredtranscludeinline transcludeinline + +/* +{{ $:/core/copyright.txt }} +*/ + +{{$:/plugins/tiddlywiki/aws/lambda/tiddlers}} + +{{$:/plugins/tiddlywiki/aws/lambda/sjcl}} + +{{ $:/boot/bootprefix.js ||$:/core/templates/plain-text-tiddler}} + +{{ $:/boot/boot.js ||$:/core/templates/plain-text-tiddler}} + +{{$:/plugins/tiddlywiki/aws/lambda/package-info}} + +{{ $:/plugins/tiddlywiki/aws/lambda/handler ||$:/core/templates/plain-text-tiddler}} diff --git a/plugins/tiddlywiki/aws/templates/lambda/package-info.tid b/plugins/tiddlywiki/aws/templates/lambda/package-info.tid new file mode 100644 index 000000000..51baca713 --- /dev/null +++ b/plugins/tiddlywiki/aws/templates/lambda/package-info.tid @@ -0,0 +1,11 @@ +title: $:/plugins/tiddlywiki/aws/lambda/package-info + +\rules only filteredtranscludeinline transcludeinline codeinline macrocallinline +` +var lambdaPackageInfo = { + "version": "`<<version>>`", + "engines": { + "node": ">=0.8.2" + } +}; +` diff --git a/plugins/tiddlywiki/aws/templates/lambda/sjcl.tid b/plugins/tiddlywiki/aws/templates/lambda/sjcl.tid new file mode 100644 index 000000000..2f6237b77 --- /dev/null +++ b/plugins/tiddlywiki/aws/templates/lambda/sjcl.tid @@ -0,0 +1,17 @@ +title: $:/plugins/tiddlywiki/aws/lambda/sjcl + +\rules only filteredtranscludeinline transcludeinline + +(function() { + +var module; + +global.sjcl = (function() { + +{{ $:/library/sjcl.js ||$:/core/templates/plain-text-tiddler}} + +return sjcl; + +})(); + +})(); diff --git a/plugins/tiddlywiki/aws/templates/lambda/tiddlers.tid b/plugins/tiddlywiki/aws/templates/lambda/tiddlers.tid new file mode 100644 index 000000000..80e5898c9 --- /dev/null +++ b/plugins/tiddlywiki/aws/templates/lambda/tiddlers.tid @@ -0,0 +1,5 @@ +title: $:/plugins/tiddlywiki/aws/lambda/tiddlers + +` +var lambdaTiddlers = `<$text text=<<jsontiddlers "[all[tiddlers]]">>/>`; +`