Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[code.haxe.org] Other - Zip files #41

Open
utterances-bot opened this issue Jan 17, 2020 · 10 comments
Open

[code.haxe.org] Other - Zip files #41

utterances-bot opened this issue Jan 17, 2020 · 10 comments

Comments

@utterances-bot
Copy link

Zip files - Other - Haxe programming language cookbook

The haxe.zip package allows to zip and unzip files and directories using Haxe. This example shows how to use it.

https://code.haxe.org/category/other/haxe-zip.html

Copy link

Works fine on Windows, but on Linux created zip is broken and cannot be opened.

Copy link
Member

Which target? Works fine for me at least on cpp, neko and php

@CrazyFlasher
Copy link

CrazyFlasher commented Jan 18, 2020

I am using hxp.
Here is a full source of script.
As I said, works fine on Windows, but on Linux gives broken zip.

Code sample
import haxe.io.Path;
import sys.io.FileOutput;
import utils.FileUtils;
import sys.io.File;
import haxe.zip.Reader;
import haxe.zip.Writer;
import haxe.zip.Entry;
import sys.FileSystem;
import hxp.HXML;
import hxp.Script;

/**
* Compresses PNGs in directory using pngquant.
* Usage: haxelib run hxp CompressPNGs.hx -Din=<path to input folder>
*
* -Din - path to input directory
* -Dq - quality (0-100) (optional)
* -Dzip - will compress pngs inside zip archives (optional)
**/
class CompressPNGs extends Script
{
    private var input:String;

    private var quality:String = "0-90";
    private var checkZip:Bool = false;

    public function new()
    {
        super();

        if (!defines.exists("in"))
        {
            trace("Path to input directory is not specified!");
            trace("Define it as flag -Din=path_to_dir...");
            Sys.exit(1);
        }
        if (!defines.exists("q"))
        {
            trace("Quality no specified. Using default: 0-90...");
        } else
        {
            quality = Std.string(defines.get("q"));
        }
        if (defines.exists("zip"))
        {
            checkZip = true;

            trace("Will check inside zip files also...");
        }

        input = Path.join([workingDirectory, defines.get("in")]);

        compressDir(input);
    }

    private function compressDir(path:String):Void
    {
        if (FileSystem.exists(path) && FileSystem.isDirectory(path))
        {
            for (filePath in FileSystem.readDirectory(path))
            {
                var p:String = Path.join([path, filePath]);

                if (FileSystem.isDirectory(p))
                {
                    compressDir(p);
                } else
                {
                    if (isPNG(filePath))
                    {
                        compressFile(p);
                    }else
                    if (isZIP(filePath) && checkZip)
                    {
                        trace("Unpacking zip file: " + p);

                        var reader:Reader = new Reader(File.read(p, true));
                        var list:List<Entry> = reader.read();

                        var dir:String = p + "_temp/";
                        FileUtils.deleteWithFiles(dir);
                        FileSystem.createDirectory(dir);

                        for (entry in list)
                        {
                            Reader.unzip(entry);

                            var filePath:String = Path.join([dir, entry.fileName]);
                            File.saveBytes(filePath, entry.data);

                            if (isPNG(entry.fileName))
                            {
                                compressFile(filePath);
                            }
                        }

                        // create the output file
                        var out:FileOutput = File.write(p, true);
                        // write the zip file
                        var writer:Writer = new Writer(out);
                        writer.write(getEntries(dir));

                        FileUtils.deleteWithFiles(dir);
                    }
                }
            }
        }
    }

    // recursive read a directory, add the file entries to the list
    private function getEntries(dir:String, entries:List<haxe.zip.Entry> = null, inDir:Null<String> = null)
    {
        if (entries == null) entries = new List<haxe.zip.Entry>();
        if (inDir == null) inDir = dir;
        for (file in sys.FileSystem.readDirectory(dir))
        {
            var path = haxe.io.Path.join([dir, file]);
            if (sys.FileSystem.isDirectory(path))
            {
                getEntries(path, entries, inDir);
            } else
            {
                var bytes:haxe.io.Bytes = haxe.io.Bytes.ofData(sys.io.File.getBytes(path).getData());
                var entry:haxe.zip.Entry = {
//                    fileName: file.toString(),
                    fileName: StringTools.replace(path, inDir, ""),
                    fileSize: bytes.length,
                    fileTime: Date.now(),
                    compressed: false,
                    dataSize: 0,
                    data: bytes,
                    crc32: haxe.crypto.Crc32.make(bytes)
                };
                entries.push(entry);
            }
        }
        return entries;
    }

    private function compressFile(path:String):Void
    {
        trace("Compress file: " + path);

        var result:Int = new HXML({
//            cmds: ["pngquant " + path + " --ext .png --force --speed 1 --posterize ARGB4444 --quality " + quality]
//            cmds: ["pngquant " + path + " --ext .png --force --speed 1 --nofs --quality " + quality]
            cmds: ["pngquant " + path + " --ext .png --force --speed 1 --posterize ARGB4444 --quality " + quality]
        }).build();
    }

    private function isPNG(fileName:String):Bool
    {
        return fileName.substr(fileName.length - 4) == ".png";
    }

    private function isZIP(fileName:String):Bool
    {
        return fileName.substr(fileName.length - 4) == ".zip";
    }
}

@RealyUniqueName
Copy link
Member

Afaik hxp uses neko. It works for me with pure neko without hxp. That may be a hxp bug.

@Gama11
Copy link
Member

Gama11 commented Jan 20, 2020

On Haxe 4 it uses eval:

Using HXP works on Haxe 4 (using eval internally) or Haxe 3 (using Neko).

Copy link
Member

Checked it. Works on eval too.

Copy link
Member

markknol commented Aug 18, 2020

Does anyone know if we can create compressed zips too?
Zipping a file with 7-Zip results in smaller size, because they use compression.

@cedx
Copy link

cedx commented Dec 10, 2020

@markknol Just before entries.push(entry); ...

haxe.zip.Tools.compress(entry, 9);

Copy link

condigital commented May 21, 2021

Unzip Function

static function unzip(archivo:String, donde:String) {
	var zipfileBytes = File.getBytes(archivo);
	var bytesInput = new BytesInput(zipfileBytes);
	var reader = new Reader(bytesInput);
	var entries:List<Entry> = reader.read();
	for (_entry in entries) {
		var data = Reader.unzip(_entry);
		if (_entry.fileName.substring(_entry.fileName.lastIndexOf('/') + 1) == '' && _entry.data.toString() == '') {
			sys.FileSystem.createDirectory(donde + _entry.fileName);
		} else {
			var f = File.write(donde + _entry.fileName, true);
			f.write(data);
			f.close();
		}
	}
}

@matrefeytontias
Copy link

matrefeytontias commented Sep 3, 2021

Interp on win64 needs out.close() or the resulting zip file will be forever held by haxe.exe (and also show up as having no contents despite having the correct size). This is not a problem for running a script since haxe.exe usually exits instantly, but when running with, say, VS Code, the haxe instance stays up and this causes problems. Tested with an hxml file with --run in it ; I assume this means interp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants