Quick flip compressed file to folder in place

Made this to automate the process of extracting a zip file to a subfolder and removing the zip file. The standard commands for this will, if using the twirl-out tree view, cause the resulting subfolder to be extracted to the lister path. But this version reads its full path, dumps the contents to a folder with the same name as the zip file and in the same path as the parent folder, then deletes the zip file only if the extraction process returns a code 1 ("success"). I have this tied to a button on a toolbar at the bottom of my lister.

// =============================================================================
// Script Name: Extract to Subfolder and Delete Safe
// Contact:     Berkeley Goodloe, oozy-lingo-switch@duck.com
// License:     Open / Unlicensed (Public Domain)
//
// Description:
// Inspects selected compressed archives and extracts their contents into a new
// subfolder bearing the archive's base name, located directly within the parent
// directory of the file (resolving paths correctly across tabs, collections,
// and Flat View).
//
// Safety:
// The original archive is only deleted (sent to Recycle Bin) if the extraction
// operation completes synchronously with a success code (1). If extraction
// fails, is cancelled, or encounters corruption, the archive is preserved.
// =============================================================================

function OnInit(initData) {
    initData.name = "Extract to Subfolder and Delete Safe";
    initData.version = "1.0";
    initData.desc = "Safely extracts selected archives into a matching subfolder in their parent directory, then deletes the archive.";
    initData.url = "mailto:oozy-lingo-switch@duck.com";
    initData.default_enable = true;
    initData.min_version = "13.0";

    var cmd = initData.AddCommand();
    cmd.name = "ExtractToSubAndDeleteSafe";
    cmd.method = "OnExtractToSubAndDeleteSafe";
    cmd.desc = "Extract archive to subfolder in parent directory and delete archive";
    cmd.label = "Extract to Subfolder and Delete Safe";
}

function OnExtractToSubAndDeleteSafe(scriptCmdData) {
    var cmd = scriptCmdData.func.command;
    var tab = scriptCmdData.func.sourcetab;

    cmd.deselect = false;

    if (tab.selected_files.count === 0) {
        return;
    }

    // Supported archive extensions
    var archivePattern = /\.(zip|7z|rar|tar|gz|bz2|xz|zst|tgz|cbz|cbr)$/i;

    for (var e = new Enumerator(tab.selected_files); !e.atEnd(); e.moveNext()) {
        var item = e.item();

        if (item.is_dir || !archivePattern.test(item.ext)) {
            continue;
        }

        var parentPath = String(item.path);

        cmd.ClearFiles();
        cmd.AddFile(item);

        // Run extraction synchronously into parentPath\<archive_stem>\
        var extractSuccess = cmd.RunCommand('Copy EXTRACT=sub TO="' + parentPath + '"');

        // Delete only if extraction returned 1 (success)
        if (extractSuccess === 1) {
            cmd.ClearFiles();
            cmd.AddFile(item);
            cmd.RunCommand('Delete QUIET');
        }
    }
}
1 Like

How did you test the safety measures?

Sorry for the delay in reply. I tested this a couple ways: 1) I made a corrupted .zip file by simply making a text file, renaming it a zip file, then seeing if the script tried to delete the file even though the extract process failed. I also did a version with a password protected zip file, ran the script, cancelled at the password prompt, and checked to see if it deleted the file.

Although it's not in this final version, I was also using the script log to monitor the success code output. I had the command

DOpus.Output("Archive: " + item.name + " | Result code: " + extractSuccess);

...in there right before the delete command at the end of the script.