1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-23 10:07:19 +00:00

Savetrails: Download before and after files for destructive modifications

This commit is contained in:
Jermolene 2017-02-09 15:45:39 +00:00
parent 97e995e0c7
commit 3d8249dc7a
5 changed files with 60 additions and 22 deletions

View File

@ -1,3 +0,0 @@
title: $:/config/SaveTrailPlugin/save-filter
[is[tiddler]] -[[$:/HistoryList]] -[[$:/StoryList]] -[prefix[$:/config/]] -[prefix[$:/temp/]] -[prefix[$:/state/]] -[prefix[$:/status/]]

View File

@ -0,0 +1,3 @@
title: $:/config/SaveTrailPlugin/sync-drafts-filter
[is[tiddler]has[draft.of]]

View File

@ -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:

View File

@ -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);

View File

@ -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>
<$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)</$checkbox>
[[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"/>