From 3d8249dc7a8a34de29e92dd519d0eb317c7044bc Mon Sep 17 00:00:00 2001 From: Jermolene Date: Thu, 9 Feb 2017 15:45:39 +0000 Subject: [PATCH] Savetrails: Download before and after files for destructive modifications --- .../savetrail/config/save-filter.tid | 3 - .../savetrail/config/sync-drafts-filter.tid | 3 + plugins/tiddlywiki/savetrail/readme.tid | 11 +++- plugins/tiddlywiki/savetrail/savetrail.js | 60 +++++++++++++++---- plugins/tiddlywiki/savetrail/settings.tid | 5 -- 5 files changed, 60 insertions(+), 22 deletions(-) delete mode 100644 plugins/tiddlywiki/savetrail/config/save-filter.tid create mode 100644 plugins/tiddlywiki/savetrail/config/sync-drafts-filter.tid diff --git a/plugins/tiddlywiki/savetrail/config/save-filter.tid b/plugins/tiddlywiki/savetrail/config/save-filter.tid deleted file mode 100644 index 796c847de..000000000 --- a/plugins/tiddlywiki/savetrail/config/save-filter.tid +++ /dev/null @@ -1,3 +0,0 @@ -title: $:/config/SaveTrailPlugin/save-filter - -[is[tiddler]] -[[$:/HistoryList]] -[[$:/StoryList]] -[prefix[$:/config/]] -[prefix[$:/temp/]] -[prefix[$:/state/]] -[prefix[$:/status/]] \ No newline at end of file diff --git a/plugins/tiddlywiki/savetrail/config/sync-drafts-filter.tid b/plugins/tiddlywiki/savetrail/config/sync-drafts-filter.tid new file mode 100644 index 000000000..96323912d --- /dev/null +++ b/plugins/tiddlywiki/savetrail/config/sync-drafts-filter.tid @@ -0,0 +1,3 @@ +title: $:/config/SaveTrailPlugin/sync-drafts-filter + +[is[tiddler]has[draft.of]] \ No newline at end of file diff --git a/plugins/tiddlywiki/savetrail/readme.tid b/plugins/tiddlywiki/savetrail/readme.tid index eb096e989..fe891bfe2 100644 --- a/plugins/tiddlywiki/savetrail/readme.tid +++ b/plugins/tiddlywiki/savetrail/readme.tid @@ -1,13 +1,20 @@ title: $:/plugins/tiddlywiki/savetrail/readme -This plugin causes TiddlyWiki to continuously save the contents of each tiddler that is changed as a JSON file. Configured correctly, the browser will download the files silently in the background, and they can be used as a backup in case of accidental data loss. +This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of each tiddler that is changed through any means: + +* Confirming an edit +* Deleting tiddlers +* Imports +* Renames/relinks + +Where appropriate, separate 'before' and 'after' files are downloaded. Configured correctly, the browser will download the files silently in the background, and they can be used as a backup in case of accidental data loss. ''CAUTION'': Using this plugin will generate a //lot// of files in your downloads folder! Some points to watch: * This plugin is pretty much unusable unless your browser is set up to download files automatically, without prompting for the location * Automatic file downloading doesn't work in all browsers - in particular, Safari and Internet Explorer do not currently support the [[necessary HTML5 feature|http://caniuse.com/download]] * Be aware of the privacy implications of leaving a plaintext trail of all of your edits. You should only enable this plugin on computers that your trust and with content that is not sensitive -* The plugin uses the tiddler title plus a timestamp to generate a filename for the downloaded file, but some browsers don't respect +* The plugin uses the tiddler title plus a timestamp to generate a filename for the downloaded file, but some browsers ignore the specified title and generate their own title for each downloaded file Other points to note: diff --git a/plugins/tiddlywiki/savetrail/savetrail.js b/plugins/tiddlywiki/savetrail/savetrail.js index 19f22869c..644dfb111 100644 --- a/plugins/tiddlywiki/savetrail/savetrail.js +++ b/plugins/tiddlywiki/savetrail/savetrail.js @@ -19,19 +19,55 @@ exports.after = ["startup"]; exports.synchronous = true; // Favicon tiddler -var SAVE_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/save-filter", - ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable", - ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts"; +var ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable", + ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts", + SYNC_DRAFTS_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/sync-drafts-filter"; exports.startup = function() { $tw.savetrail = $tw.savetrail || {}; + // Create a syncer to handle autosaving $tw.savetrail.syncadaptor = new SaveTrailSyncAdaptor(); $tw.savetrail.syncer = new $tw.Syncer({ wiki: $tw.wiki, syncadaptor: $tw.savetrail.syncadaptor, - titleSyncFilter: SAVE_FILTER_TIDDLER_TITLE, + titleSyncFilter: SYNC_DRAFTS_FILTER_TIDDLER_TITLE, logging: false }); + // Add hooks for trapping user actions + $tw.hooks.addHook("th-saving-tiddler",function(tiddler) { + var oldTiddler = $tw.wiki.getTiddler(tiddler.fields.title); + if(oldTiddler) { + saveTiddlerFile(oldTiddler,{reason: "overwritten"}); + } + saveTiddlerFile(tiddler,{reason: "saved"}); + return tiddler; + }); + $tw.hooks.addHook("th-renaming-tiddler",function(newTiddler,oldTiddler) { + if(oldTiddler) { + saveTiddlerFile(oldTiddler,{reason: "deleted"}); + } + saveTiddlerFile(newTiddler,{reason: "renamed"}); + return newTiddler; + }); + $tw.hooks.addHook("th-relinking-tiddler",function(newTiddler,oldTiddler) { + if(oldTiddler) { + saveTiddlerFile(oldTiddler,{reason: "overwritten"}); + } + saveTiddlerFile(newTiddler,{reason: "relinked"}); + return newTiddler; + }); + $tw.hooks.addHook("th-importing-tiddler",function(tiddler) { + var oldTiddler = $tw.wiki.getTiddler(tiddler.fields.title); + if(oldTiddler) { + saveTiddlerFile(oldTiddler,{reason: "overwritten"}); + } + saveTiddlerFile(tiddler,{reason: "imported"}); + return tiddler; + }); + $tw.hooks.addHook("th-deleting-tiddler",function(tiddler) { + saveTiddlerFile(tiddler,{reason: "deleted"}); + return tiddler; + }); }; function SaveTrailSyncAdaptor(options) { @@ -53,10 +89,10 @@ SaveTrailSyncAdaptor.prototype.getTiddlerInfo = function(tiddler) { Save a tiddler and invoke the callback with (err,adaptorInfo,revision) */ SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) { - if($tw.wiki.getTiddlerText(ENABLE_TIDDLER_TITLE).toLowerCase() === "yes") { + if($tw.wiki.checkTiddlerText(ENABLE_TIDDLER_TITLE,"yes")) { var isDraft = $tw.utils.hop(tiddler.fields,"draft.of"); - if(!isDraft || $tw.wiki.getTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE).toLowerCase() === "yes") { - saveTiddlerFile(tiddler); + if(!isDraft || $tw.wiki.checkTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE,"yes")) { + saveTiddlerFile(tiddler,{reason: "modified"}); } } callback(null); @@ -64,8 +100,6 @@ SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) { /* Load a tiddler and invoke the callback with (err,tiddlerFields) - -We don't need to implement loading for the file system adaptor, because all the tiddler files will have been loaded during the boot process. */ SaveTrailSyncAdaptor.prototype.loadTiddler = function(title,callback) { callback(null,null); @@ -78,11 +112,13 @@ SaveTrailSyncAdaptor.prototype.deleteTiddler = function(title,callback,options) callback(null); }; -function saveTiddlerFile(tiddler) { - var illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g, +function saveTiddlerFile(tiddler,options) { + options = options || {}; + var reason = options.reason || "changed", + illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g, fixedTitle = tiddler.fields.title.replace(illegalFilenameCharacters,"_"), formattedDate = $tw.utils.stringifyDate(new Date()), - filename = fixedTitle + "." + formattedDate + ".json", + filename = fixedTitle + "." + formattedDate + "." + reason + ".json", fields = new Object(); for(var field in tiddler.fields) { fields[field] = tiddler.getFieldString(field); diff --git a/plugins/tiddlywiki/savetrail/settings.tid b/plugins/tiddlywiki/savetrail/settings.tid index 370799d4c..c11ef649a 100644 --- a/plugins/tiddlywiki/savetrail/settings.tid +++ b/plugins/tiddlywiki/savetrail/settings.tid @@ -4,8 +4,3 @@ title: $:/plugins/tiddlywiki/savetrail/settings <$checkbox tiddler="$:/config/SaveTrailPlugin/enable" field="text" checked="yes" unchecked="no"> Enable automatic saving of modified tiddlers <$checkbox tiddler="$:/config/SaveTrailPlugin/enable-drafts" field="text" checked="yes" unchecked="no"> Include automatic saving of draft tiddlers (warning: generates a lot of download files) - -[[Filter|$:/config/SaveTrailPlugin/save-filter]] used to determine tiddlers that should be autosaved: - -<$edit-text tiddler="$:/config/SaveTrailPlugin/save-filter" tag="textarea" class="tc-edit-texteditor"/> -