From 20e64ea2af8870361a342caaf6875525aadfa086 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 11 Sep 2014 03:40:53 +1000 Subject: [PATCH 1/4] Add support for clearing the bot memory --- source/bot.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/bot.js b/source/bot.js index db14048..4cb823f 100644 --- a/source/bot.js +++ b/source/bot.js @@ -315,6 +315,14 @@ bot.memory = { clearTimeout( this.saveIntervalId ); setTimeout( this.saveLoop.bind(this), this.saveInterval ); } + + clear : function () { + Object.iterate( localStorage, function ( key, val ) { + if ( key.startsWith('bot_') ) { + localStorage.removeItem(key); + } + }); + this.data = {}; }; bot.memory.loadAll(); From a58810d36074d85166ff28d55a0a0c30ca5f3726 Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 11 Sep 2014 03:41:12 +1000 Subject: [PATCH 2/4] Add support for exporting the bot memory to a GitHub Gist, and importing from a previous export. Also allow clearing of bot memory. --- source/plugins/export.js | 32 ++++++++++++++++++++++++++++++++ source/plugins/import.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 source/plugins/export.js create mode 100644 source/plugins/import.js diff --git a/source/plugins/export.js b/source/plugins/export.js new file mode 100644 index 0000000..ef94c78 --- /dev/null +++ b/source/plugins/export.js @@ -0,0 +1,32 @@ +(function() { + "use strict"; + + bot.addCommand({ + name : 'export', + fun : function(args) { + var req = new XMLHttpRequest(); + req.open('POST', 'https://api.github.com/gists', false); + req.send(JSON.stringify({ + files: { + 'bot.json': { + content: JSON.stringify(bot.memory.data) + } + } + })); + + if (req.status !== 201) { + var resp = ''; + if (req.responseText) { + resp = '\n' + req.responseText.match(/.{1,400}/g).join('\n'); + } + return 'Failed: ' + req.status + ': ' + req.statusText + resp; + } + + var resp = JSON.parse(req.responseText); + + return 'Exported to gist, id: `' + resp.id + '` viewable at ' + resp.html_url; + }, + permissions : { del : 'NONE', use : 'OWNER' }, + description : 'Blurts out a message with the persistent memory storage for export `/export`' + }); +})(); diff --git a/source/plugins/import.js b/source/plugins/import.js new file mode 100644 index 0000000..d254665 --- /dev/null +++ b/source/plugins/import.js @@ -0,0 +1,35 @@ +(function() { + "use strict"; + + bot.addCommand({ + name : 'import', + fun : function (args) { + if (args.trim() === 'clear') { + bot.memory.clear(); + + return 'Bot memory cleared. Please restart the bot.'; + } + + var req = new XMLHttpRequest(); + req.open('GET', 'https://api.github.com/gists/' + args, false); + req.send(null); + + if (req.status !== 200) { + var resp = ''; + if (req.responseText) { + resp = '\n' + req.responseText.match(/.{1,400}/g).join('\n'); + } + return 'Failed: ' + req.status + ': ' + req.statusText + resp; + } + + var resp = JSON.parse(req.responseText); + + bot.memory.data = JSON.parse(resp.files['bot.json'].content); + bot.memory.save(); + + return "Imported and persisted successfully. Please restart the bot."; + }, + permissions : { del : 'NONE', use : 'OWNER' }, + description : 'Imports the persistent memory described in args `/export `' + }); +})(); From 834d5624bc7cd13b29750c71288877db4fdb722f Mon Sep 17 00:00:00 2001 From: Bob Date: Thu, 11 Sep 2014 10:18:31 +1000 Subject: [PATCH 3/4] Fix typo --- source/bot.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/bot.js b/source/bot.js index 4cb823f..b6752bb 100644 --- a/source/bot.js +++ b/source/bot.js @@ -314,7 +314,7 @@ bot.memory = { saveLoop : function () { clearTimeout( this.saveIntervalId ); setTimeout( this.saveLoop.bind(this), this.saveInterval ); - } + }, clear : function () { Object.iterate( localStorage, function ( key, val ) { @@ -323,6 +323,7 @@ bot.memory = { } }); this.data = {}; + } }; bot.memory.loadAll(); From 1fb7b6e3309bef7e711145555122aa436ae41508 Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 8 Nov 2015 05:02:39 +1100 Subject: [PATCH 4/4] Fix import/export for the new headless mode (Electron), which disallows synchronous XHR. --- source/plugins/export.js | 45 ++++++++++++++++++++++++---------------- source/plugins/import.js | 45 ++++++++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/source/plugins/export.js b/source/plugins/export.js index ef94c78..9b0c940 100644 --- a/source/plugins/export.js +++ b/source/plugins/export.js @@ -1,31 +1,40 @@ (function() { "use strict"; - bot.addCommand({ - name : 'export', - fun : function(args) { - var req = new XMLHttpRequest(); - req.open('POST', 'https://api.github.com/gists', false); - req.send(JSON.stringify({ - files: { - 'bot.json': { - content: JSON.stringify(bot.memory.data) - } - } - })); - + var doExport = function(args) { + var req = new XMLHttpRequest(); + req.addEventListener('abort', function() { + args.reply('Failed: Gist request aborted by user (???)'); + }); + req.addEventListener('error', function() { + args.reply('Failed: Gist request encountered a network error'); + }); + req.addEventListener('load', function() { if (req.status !== 201) { var resp = ''; if (req.responseText) { resp = '\n' + req.responseText.match(/.{1,400}/g).join('\n'); } - return 'Failed: ' + req.status + ': ' + req.statusText + resp; + args.reply('Failed: ' + req.status + ': ' + req.statusText + resp); } - + var resp = JSON.parse(req.responseText); - - return 'Exported to gist, id: `' + resp.id + '` viewable at ' + resp.html_url; - }, + + args.reply('Exported to gist, id: `' + resp.id + '` viewable at ' + resp.html_url); + }); + req.open('POST', 'https://api.github.com/gists', true); + req.send(JSON.stringify({ + files: { + 'bot.json': { + content: JSON.stringify(bot.memory.data) + } + } + })); + }; + + bot.addCommand({ + name : 'export', + fun : doExport, permissions : { del : 'NONE', use : 'OWNER' }, description : 'Blurts out a message with the persistent memory storage for export `/export`' }); diff --git a/source/plugins/import.js b/source/plugins/import.js index d254665..5904c74 100644 --- a/source/plugins/import.js +++ b/source/plugins/import.js @@ -1,34 +1,43 @@ (function() { "use strict"; + + var doImport = function (args) { + if (args.trim() === 'clear') { + bot.memory.clear(); - bot.addCommand({ - name : 'import', - fun : function (args) { - if (args.trim() === 'clear') { - bot.memory.clear(); - - return 'Bot memory cleared. Please restart the bot.'; - } - - var req = new XMLHttpRequest(); - req.open('GET', 'https://api.github.com/gists/' + args, false); - req.send(null); - + return 'Bot memory cleared. Please restart the bot.'; + } + + var req = new XMLHttpRequest(); + req.addEventListener('abort', function() { + args.reply('Failed: Gist request aborted by user (???)'); + }); + req.addEventListener('error', function() { + args.reply('Failed: Gist request encountered a network error'); + }); + req.addEventListener('load', function() { if (req.status !== 200) { var resp = ''; if (req.responseText) { resp = '\n' + req.responseText.match(/.{1,400}/g).join('\n'); } - return 'Failed: ' + req.status + ': ' + req.statusText + resp; + args.reply('Failed: ' + req.status + ': ' + req.statusText + resp); } - + var resp = JSON.parse(req.responseText); - + bot.memory.data = JSON.parse(resp.files['bot.json'].content); bot.memory.save(); + + args.reply("Imported and persisted successfully. Please restart the bot."); + }); + req.open('GET', 'https://api.github.com/gists/' + args, true); + req.send(null); + }; - return "Imported and persisted successfully. Please restart the bot."; - }, + bot.addCommand({ + name : 'import', + fun : doImport, permissions : { del : 'NONE', use : 'OWNER' }, description : 'Imports the persistent memory described in args `/export `' });