Tuesday, June 21, 2005

Overcoming the 4,096 Byte Limit of widget.system

Update 06-22-2005 9:50pm: I have found a way that works for overcoming the nothing in the clipboard bug. Here's the modification for executeSystemCommand:

function executeSystemCommand(cmd) {
    var out;
    out = widget.system(cmd + " | wc -c", null).outputString;
    out = parseInt(out, 10);
    if (out > 0) {
        widget.system(cmd + " > output.txt", null);
        out = readInFile("output.txt");
        widget.system("/bin/rm output.txt", null);

        return out;
    }
    return null;
}


What this does is is to execute the desired command capturing the count of characters, and if the count is nothing, then we simply return null. If the count is greater than zero, we execute the command and redirect the output to a file, and then read the file using XmlHttpRequest. This gets around both the 4,096 character limit, and the empty clipboard problem, if you happen to be using /usr/bin/pbpaste.

Update 06-22-2005 7:55am: A little more testing revealed that I couldn't use the 4095 length. I adjusted it to 1, but there is still more testing that needs to be done before I can be sure about this. What I find odd is that the pbpaste command fails within widget.system when there is nothing on the clipboard. It doesn't fail in the terminal. Here's the corrected line from the executeSystemCommand function:

widget.system(cmd + " | tail -c 1", null).outputString;

Update 06-21-2005 11:35pm: I did a little more testing and found in the rare case that the clipboard is empty, the sample code has a slight bug. Here's a correction to the executeSystemCommand:

function executeSystemCommand(cmd) {
    var out;
    out = widget.system(cmd + " | tail -c 4095", null).outputString;
    if (out.length == 0) return null;
    widget.system(cmd + " > output.txt", null);
    out = readInFile("output.txt");
    widget.system("rm output.txt");
    return out;
}

I ran into the limit of widget.system while working on the next version of the Code2HTML widget. Apparently, output captured from calls to widget.system are limited to 4,096 bytes. If the command returns more than that, it crashes the widget. Lovely, just lovely. I'm not sure why the Apple engineers would do this, but what's done is done. Hopefully, they'll fix that in a future release, but until then, you can use the following JavaScript in your widgets. This bit of JavaScript is not new with me. I found this code over at Dashboard Widgets in this forum. Kudos to the original author. I did create a new JavaScript function that does a little more work than the original posting.

function executeSystemCommand(cmd) {
    widget.system(cmd + " > output.txt", null);
    var out = readInFile("output.txt");
    widget.system("rm output.txt");
    return out;
}

function readInFile(filename) {
    req = new XMLHttpRequest();
    req.open("GET", filename ,false);
    req.send(null);
    response = req.responseText;
    if (response) {
        return response;
    }
    return null
}



To use this, do something like the following:

executeSystemCommand("/usr/bin/pbpaste");

1 comment:

Dmitri said...

Yeah ! I was looking for a solution to overcome this issue and finally you give it to me !

Thank you very much :)