summaryrefslogtreecommitdiff
path: root/scripts/context/lua/mtx-unzip.lua
blob: 645863426dbd71b8a8f5fa9d8d2245ea971ec492 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
if not modules then modules = { } end modules ['mtx-unzip'] = {
    version   = 1.001,
    comment   = "companion to mtxrun.lua",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

-- maybe --pattern

local format = string.format

local helpinfo = [[
--list                list files in archive
--junk                flatten unzipped directory structure
--extract             extract files
]]

local application = logs.application {
    name     = "mtx-unzip",
    banner   = "Simple Unzipper 0.10",
    helpinfo = helpinfo,
}

local report = application.report

scripts          = scripts          or { }
scripts.unzipper = scripts.unzipper or { }

function scripts.unzipper.opened()
    local filename = environment.files[1]
    if filename and filename ~= "" then
        filename = file.addsuffix(filename,'zip')
        local zipfile = zip.open(filename)
        if zipfile then
            return zipfile
        end
    end
    report("no zip file: %s",filename)
    return false
end

function scripts.unzipper.list()
    local zipfile = scripts.unzipper.opened()
    if zipfile then
        local n = 0
        for k in zipfile:files() do
            if #k.filename > n then n = #k.filename end
        end
        local files, paths, compressed, uncompressed = 0, 0, 0, 0
        local template_a =   "%-"..n.."s"
        local template_b =   "%-"..n.."s  % 9i  % 9i"
        local template_c = "\n%-"..n.."s  % 9i  % 9i"
        for k in zipfile:files() do
            if k.filename:find("/$") then
                paths = paths + 1
                print(format(template_a, k.filename))
            else
                files = files + 1
                local cs, us = k.compressed_size, k.uncompressed_size
                if cs > compressed then
                    compressed = cs
                end
                if us > uncompressed then
                    uncompressed = us
                end
                print(format(template_b,k.filename,cs,us))
            end
        end -- check following pattern, n is not enough
        print(format(template_c,files .. " files, " .. paths .. " directories",compressed,uncompressed))
    end
end

function zip.loaddata(zipfile,filename)
    local f = zipfile:open(filename)
    if f then
        local data = f:read("*a")
        f:close()
        return data
    end
    return nil
end

function scripts.unzipper.extract()
    local zipfile = scripts.unzipper.opened()
    if zipfile then
        local junk = environment.arguments["j"] or environment.arguments["junk"]
        for k in zipfile:files() do
            local filename = k.filename
            if filename:find("/$") then
                if not junk then
                    lfs.mkdir(filename)
                end
            else
                local data = zip.loaddata(zipfile,filename)
                if data then
                    if junk then
                        filename = file.basename(filename)
                    end
                    io.savedata(filename,data)
                    print(filename)
                end
            end
        end
    end
end

if environment.arguments["h"] or environment.arguments["help"] then
    application.help()
elseif environment.arguments["l"] or environment.arguments["list"] then
    scripts.unzipper.list(zipfile)
elseif environment.files[1] then -- implicit --extract
    scripts.unzipper.extract(zipfile)
else
    application.help()
end