ActiveState Community

Auto Backup Macro

Posted by rob.sigrest on 2009-01-29 15:46

Hello. I was trying to make a simple macro that would make a .bak file of whatever I was working on in C:/backups. I found an existing macro that places a .bak file in the same directory as the file, but that gets kind of old so I thought a quick save to my harddrive might be nice. This is what I have so far:

if (komodo.document.file.scheme != "file") {
    return;
}
var file = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(komodo.document.file.path);

var backupFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
backupFile.initWithPath("file:///C:/backups/" + komodo.document.file.baseName + ".bak");
if (backupFile.exists()) {
    backupFile.remove(false);
}

file.copyTo(backupFile.parent, backupFile.leafName);

if (komodo.document.file.scheme != "file") {
    return;
}
var file = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(komodo.document.file.path);

var backupFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
backupFile.initWithPath("file:///C:/backups/" + komodo.document.file.baseName + ".bak");
if (backupFile.exists()) {
    backupFile.remove(false);
}

file.copyTo(backupFile.parent, backupFile.leafName);

but it errors out with this:
Error while running in macro backuponsave:

NS_ERROR_FILE_UNRECOGNIZED_PATH: Component returned failure code: 0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH) [nsILocalFile.initWithPath]

exception[name] = NS_ERROR_FILE_UNRECOGNIZED_PATH
exception[message] = Component returned failure code: 0x80520001 (NS_ERROR_FILE_UNRECOGNIZED_PATH) [nsILocalFile.initWithPath]
exception[QueryInterface] = function QueryInterface() {
[native code]
}
exception[result] = 2152857601
exception[filename] = chrome://komodo/content/project/peMacro.js
exception[lineNumber] = 723
exception[columnNumber] = 0
exception[location] = JS frame :: chrome://komodo/content/project/peMacro.js :: anonymous :: line 723
exception[inner] = null
exception[data] = null
exception[initialize] = function initialize() {
[native code]
}

Obviously I'm having trouble with the file path. If anyone could help me out it would be much appreciated.

toddw | Thu, 2009-01-29 16:21

I'd hazard a guess that it's the second initWithPath call:

backupFile.initWithPath("file:///C:/backups/" + komodo.document.file.baseName + ".bak");
backupFile.initWithPath("file:///C:/backups/" + komodo.document.file.baseName + ".bak");

Try removing the "file:///" part and use "\" directory separators, i.e.:

backupFile.initWithPath("C:\\backups\\" + komodo.document.file.baseName + ".bak");
backupFile.initWithPath("C:\\backups\\" + komodo.document.file.baseName + ".bak");

rob.sigrest | Thu, 2009-01-29 16:24

Thanks Todd! You rock. Worked like a charm.

nathan | Fri, 2009-03-20 08:14

I've modified your macro a little bit to save the file with a timestamp so that a new copy of the file is saved every time you execute it.

I execute the macro every time I save a file.

I love having revisions of every file save (I press the save button about 5 times per minute :p) and the disk space aint an issue for me.. :)

if (komodo.document.file.scheme != "file") {
    return;
}
var file = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(komodo.document.file.path);
var backupFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
                     
var fileName = komodo.document.file.displayPath;
fileName = fileName.replace(/(\\|\:)/g,'-');

var date = new Date();
var timestamp = date.getTime();

backupFile.initWithPath("C:\\Revisions\\" + fileName + "." + timestamp + ".bak");

file.copyTo(backupFile.parent, backupFile.leafName);

if (komodo.document.file.scheme != "file") {
    return;
}
var file = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(komodo.document.file.path);
var backupFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
                     
var fileName = komodo.document.file.displayPath;
fileName = fileName.replace(/(\\|\:)/g,'-');

var date = new Date();
var timestamp = date.getTime();

backupFile.initWithPath("C:\\Revisions\\" + fileName + "." + timestamp + ".bak");

file.copyTo(backupFile.parent, backupFile.leafName);

I love Komodo Edit dearly, but it would seriously benefit from a revision management feature like the one Netbeans has :) Right now I'll stick to this tho :)

pepebe | Fri, 2009-05-15 13:21

Great Macro!

It works like a charm (ubuntu linux 8.0432bit, Komodo Edit 5.1.1).

To meet my personal needs, I have applied some changes: Rather than having a filename containing a cryptic unix timestamp...

test.html.1242372934490.bak

you will now have...

test.html.2009-04-15_10-21-26.bak

(test.html.YYYY-MM-DD_HH-MM-SS.bak)

It's easier to read for me. Though I would prefer to put a colon (:) between hours, minutes and seconds, this would not be a valid filename in Mac OS X and Windows XP. I'm open for suggestions how to style the time part more beautifully. ;)

if (komodo.document.file.scheme != "file") {
    return;
}
var file = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(komodo.document.file.path);
var backupFile = Components.classes["@mozilla.org/file/local;1"]
                     .createInstance(Components.interfaces.nsILocalFile);
                     
var fileName = komodo.document.file.displayPath;
fileName = fileName.replace(/(\\|\:)/g,'-');

var date     = new Date();

var Year     = date.getFullYear();
var Month    = date.getMonth();
var Day      = date.getDate();
var Hour     = date.getHours();
var Minute   = date.getMinutes();
var Second   = date.getSeconds();

if(Month<10) Month   = "0" + Month;
if(Day<10) Day       = "0" + Day;
if(Hour<10) Hour     = "0" + Hour;
if(Minute<10) Minute = "0" + Minute;
if(Second<10) Second = "0" + Second;

var timestamp = Year+"-"+Month+"-"+Day+"_"+Hour+"-"+Minute+"-"+Second;

backupFile.initWithPath("your path here" + fileName + "." + timestamp + ".bak");

file.copyTo(backupFile.parent, backupFile.leafName);

Another thing: Don't forget to change the "your path here" part above.

If you completely remove it, you will get a backup in the same directory as the source file.

Example:
backupFile.initWithPath(fileName + "." + timestamp + ".bak");

If you change it, the file will be saved in the respective directory INCLUDING THE FULL directory tree of the source file.

Example:

/home/project/test.html

backed-up in

"/home/backups"

will become

/home/backups/home/projects/test.html.2009-04-15_10-21-26.bak

Some advice for setting up a correct backup path:

Example Ubuntu-Linux:
backupFile.initWithPath("/home/backups/" + fileName + "." + timestamp + ".bak");

Example Windows (not tested):
backupFile.initWithPath("C:\\backups\\" + fileName + "." + timestamp + ".bak");

Question: Any idea how to get a real automatic backup every time I save a file?

Edit: Found out how to do that. It's easy. I just had to open the "Auto Backup" macro properties. Then I went to "Triggers" tag and checked "Macro should trigger on komodo event". Finally I activated the "after file" event. Voile! Komodo I love you, really.

Regards,

pepebe

pepebe | Sat, 2009-08-22 09:54

nathan (http://community.activestate.com/user/nathan/track) polished this already very useful macro into something even more powerful.

Have a look at http://community.activestate.com/forum/file-revisions-diff

Regards,

pepebe