gnh1201 / welsonjs

WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
https://catswords.social/@catswords_oss
GNU General Public License v3.0
229 stars 15 forks source link

[lib/archive] Support for handling compressed files #146

Open gnh1201 opened 2 months ago

gnh1201 commented 2 months ago

Summary

We plan to provide support for handling compressed files in the scripting environment. We aim to use the built-in features of the operating system as much as possible and will also support some well-known commercial tools.

In addition to the operating system's built-in APIs for compressed files, we are also looking into open-source projects such as PeaZip and 7-Zip. Commercial software like WinRAR and WinZIP are also being considered.

Related links

gnh1201 commented 2 weeks ago

I’ll let you know as soon as the initial version of lib/archive.js is ready. @pranulkbv28

pranulkbv28 commented 2 weeks ago

works. thanks

On Thu, Nov 7, 2024 at 8:02 PM Namhyeon, Go @.***> wrote:

I’ll let you know as soon as the initial version of lib/archive.js is ready. @pranulkbv28 https://github.com/pranulkbv28

— Reply to this email directly, view it on GitHub https://github.com/gnh1201/welsonjs/issues/146#issuecomment-2462386987, or unsubscribe https://github.com/notifications/unsubscribe-auth/A63NKFCNCM4V4BXX4SEAM7LZ7N2YXAVCNFSM6AAAAABPATURHKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINRSGM4DMOJYG4 . You are receiving this because you were mentioned.Message ID: @.***>

gnh1201 commented 2 weeks ago

I updated the package.json to resolve the issue where 'npm run start' was not working during testing. The project directory structure changed, and this update was missed. Please update the project to the latest version and try again. Thank you.

gnh1201 commented 2 weeks ago

If you refer to this code, it will help you write it.

// archive.js

var ArchiveObject = function() {
    this.engine = "HOW_TO_COMPRESS_AND_DECOMPRES_A_FILE";

    this.create = function(engine) {
        this.engine = engine;
    }

    this.extractTo = function(targetDirectory) {
        if (this.engine == "METHOD_1") {
            // how to extract a file with METHOD_1
        } else (this.engine == "METHOD_2") {
            // how to extract a file with METHOD_2
        } // ...
    }

    this.compressDirectory = function(sourceDirectory) {
        if (this.engine == "METHOD_1") {
            // how to compress a file with METHOD_1
        } else (this.engine == "METHOD_2") {
            // how to compress a file with METHOD_2
        } // ...
    }

    // A good practice is lib/http.js
}
pranulkbv28 commented 2 days ago

this is what I have come up with Let us discuss on this tmrw

// archive.js

const SHELL = require("lib/shell"); // Assuming a shell library for executing external tools
const OS = require("lib/system");  // For OS-specific commands

var ArchiveObject = function(engine) {
    this.engine = engine || "BUILT_IN"; // Default to built-in OS tools
    this._interface = null;

    // Initialize the archive engine
    this.create = function() {
        switch (this.engine) {
            case "BUILT_IN":
                this._interface = new BuiltInEngine();
                break;
            case "7ZIP":
                this._interface = new SevenZipEngine();
                break;
            case "WINRAR":
                this._interface = new WinRarEngine();
                break;
            default:
                throw new Error("Unsupported engine: " + this.engine);
        }
    };

    // Compress a directory
    this.compress = function(sourceDirectory, outputFile) {
        if (!this._interface) this.create();
        return this._interface.compress(sourceDirectory, outputFile);
    };

    // Decompress an archive
    this.extract = function(archiveFile, targetDirectory) {
        if (!this._interface) this.create();
        return this._interface.extract(archiveFile, targetDirectory);
    };
};

// Base interface for engines
class BaseEngine {
    compress(sourceDirectory, outputFile) {
        throw new Error("compress() not implemented.");
    }

    extract(archiveFile, targetDirectory) {
        throw new Error("extract() not implemented.");
    }
}

// Built-in OS tools
class BuiltInEngine extends BaseEngine {
    compress(sourceDirectory, outputFile) {
        const osName = OS.getOS();
        if (osName === "Windows") {
            // Example for Windows using PowerShell
            return SHELL.exec(`Compress-Archive -Path "${sourceDirectory}\\*" -DestinationPath "${outputFile}"`);
        } else if (osName === "Linux" || osName === "Darwin") {
            // Example for Linux/Mac using tar
            return SHELL.exec(`tar -czf "${outputFile}" -C "${sourceDirectory}" .`);
        }
        throw new Error("Unsupported OS for BuiltInEngine.");
    }

    extract(archiveFile, targetDirectory) {
        const osName = OS.getOS();
        if (osName === "Windows") {
            // Example for Windows using PowerShell
            return SHELL.exec(`Expand-Archive -Path "${archiveFile}" -DestinationPath "${targetDirectory}"`);
        } else if (osName === "Linux" || osName === "Darwin") {
            // Example for Linux/Mac using tar
            return SHELL.exec(`tar -xzf "${archiveFile}" -C "${targetDirectory}"`);
        }
        throw new Error("Unsupported OS for BuiltInEngine.");
    }
}

// 7-Zip engine
class SevenZipEngine extends BaseEngine {
    compress(sourceDirectory, outputFile) {
        const command = `7z a "${outputFile}" "${sourceDirectory}\\*"`;
        return SHELL.exec(command);
    }

    extract(archiveFile, targetDirectory) {
        const command = `7z x "${archiveFile}" -o"${targetDirectory}"`;
        return SHELL.exec(command);
    }
}

// WinRAR engine
class WinRarEngine extends BaseEngine {
    compress(sourceDirectory, outputFile) {
        const command = `WinRAR a "${outputFile}" "${sourceDirectory}\\*"`;
        return SHELL.exec(command);
    }

    extract(archiveFile, targetDirectory) {
        const command = `WinRAR x "${archiveFile}" "${targetDirectory}"`;
        return SHELL.exec(command);
    }
}

// Factory function for creating an ArchiveObject
function createArchiveObject(engine) {
    const archive = new ArchiveObject(engine);
    archive.create();
    return archive;
}

// Example Usage
const archive = createArchiveObject("7ZIP");
archive.compress("C:\\MyFolder", "C:\\MyArchive.zip");
archive.extract("C:\\MyArchive.zip", "C:\\ExtractedFolder");
gnh1201 commented 2 days ago

I’ve reviewed your code and am glad to see the effort you’ve put into studying.

However, if you plan to use inheritance, please note that the engine we use restricts the use of the class keyword, so you’ll need to adopt an alternative approach.

Instead of using class {a} extends {b}, you’ll need to implement class inheritance through prototype.

Here’s an example:

var STD = require("lib/std");

var SomethingEventableObject = function() {
    this.hello = "world";
};
SomethingEventableObject.prototype = new STD.EventTarget(); 
SomethingEventableObject.prototype.constructor = SomethingEventableObject;

For a practical example of this being used, you can refer to lib/chrome.js.

Thank you.

gnh1201 commented 13 hours ago

A demonstration on file compression and decompression is expected to be scheduled soon, likely on December 3. Please prepare thoroughly for it. Thank you!

pranulkbv28 commented 6 hours ago

Will do, thanks for the heads up.

On Wed, Nov 27, 2024 at 11:55 AM Namhyeon, Go @.***> wrote:

A demonstration on file compression and decompression is expected to be scheduled soon, likely on December 3. Please prepare thoroughly for it. Thank you!

— Reply to this email directly, view it on GitHub https://github.com/gnh1201/welsonjs/issues/146#issuecomment-2503008860, or unsubscribe https://github.com/notifications/unsubscribe-auth/A63NKFHRE7AC6NTQRCCKDJL2CVQWZAVCNFSM6AAAAABPATURHKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMBTGAYDQOBWGA . You are receiving this because you were mentioned.Message ID: @.***>