Advertisement
jesusthekiller

jZIP

Jun 25th, 2013
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.85 KB | None | 0 0
  1. --[[
  2.     Project info:
  3.    
  4.     Name: jZip
  5.     Creator: Jesusthekiller
  6.     Language: Lua (CC)
  7.     Website: None
  8.     License: GNU GPL
  9.         License file can be fount at www.jesusthekiller.com/license-gpl.html
  10.     Version: 1.2
  11. ]]--
  12.  
  13. --[[
  14.     Changelog:
  15.       1.0:
  16.         Initial Release
  17.       1.1:
  18.         jZIP API
  19.       1.2:
  20.         jZIP API fix
  21. ]]--
  22.  
  23. --[[
  24.     LICENSE:
  25.    
  26.     jZip
  27.     Copyright (c) 2013 Jesusthekiller
  28.     This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  29.     This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  30.     See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
  31. ]]--
  32.  
  33. local function usage()
  34.     print("Usage:")
  35.     print("  zip <u|unzip> <zip file>")
  36.     print("  zip <z|zip> <name> <output file> <file 1> [file 2 [...]]")
  37.     print("  zip loadapi")
  38.     print("    It will load zip API - use shell.run('zip', 'loadapi') instead of os.loadAPI('zip').")
  39. end
  40.  
  41. -- API:
  42. local function decode(text)
  43.     local s = ""
  44.     for k, char in ipairs({ text:byte(1, #text) }) do
  45.         s = s..string.char(char+8)
  46.     end
  47.     return s
  48. end
  49.  
  50. local function code(text)
  51.     local s = ""
  52.     for k, char in ipairs({ text:byte(1, #text) }) do
  53.         s = s..string.char(char-8)
  54.     end
  55.     return s
  56. end
  57.  
  58. local oerror = error
  59. local function error(str, mode)
  60.     return oerror("[ZIP API] "..str, mode)
  61. end
  62.  
  63. local function getDir(path)
  64.     local dir, file, tab = "", "", {}
  65.    
  66.     for t in path:gmatch("[^/]+") do
  67.         table.insert(tab, t)
  68.     end
  69.    
  70.     file = table.remove(tab, #tab)
  71.    
  72.     for k, v in ipairs(tab) do
  73.         dir = dir.."/"..v
  74.     end
  75.    
  76.     return file, (dir == "") and "/" or dir
  77. end
  78.  
  79. local function confirm(text)
  80.     print(text)
  81.    
  82.     local e, k
  83.     repeat
  84.         e, k = os.pullEvent("key")
  85.     until k == keys.y or k == keys.n
  86.    
  87.     coroutine.yield()
  88.    
  89.     return (k == keys.y) and true or false
  90. end
  91.  
  92. local function unzip(file)
  93.     local f = fs.open(file, "r") or error("File '"..file.."' does not exist!", 0)
  94.    
  95.     -- Read file
  96.     local c = f.readAll()
  97.    
  98.     -- Close
  99.     f.close()
  100.    
  101.     -- Split into table and decode
  102.     local t = {}
  103.     for token in decode(c):gmatch("[^\n]+") do
  104.         table.insert(t, token)
  105.     end
  106.    
  107.     -- Check if it is zip file
  108.     h = table.remove(t, 1)
  109.     if h ~= "`ZIP`" then
  110.         error("File is not ZIP file or it is corrupted", 0)
  111.     end
  112.    
  113.     -- Print name
  114.     print("Unpacking "..tostring(table.remove(t, 1)))
  115.    
  116.     -- Loop unpacking process
  117.     while true do
  118.         -- Raw full path
  119.         local rawfullpath = table.remove(t, 1)
  120.        
  121.         -- Break if end of file
  122.         if not rawfullpath then
  123.             break
  124.         end
  125.        
  126.         -- Get and print file path
  127.         local fullpath = shell.dir().."/"..rawfullpath
  128.         print("  File "..fullpath)
  129.        
  130.         -- Resolve path
  131.         local file, dir = getDir(fullpath)
  132.        
  133.         -- Create dir
  134.         if fs.exists(dir) and not fs.isDir(dir) then
  135.             if not confirm("File "..dir.." exists. Overwrite? [y/n]") then error("This file has to be overwritten to unpack this zip!", 0) end
  136.         end
  137.        
  138.         if not fs.exists(dir) then
  139.             fs.makeDir(dir)
  140.         end
  141.        
  142.         -- Open file
  143.         if fs.exists(fullpath) then
  144.             if not confirm("File "..fullpath.." exists. Overwrite? [y/n]") then error("This file has to be overwritten to unpack this zip!", 0) end
  145.             fs.delete(fullpath) -- It it's dir
  146.         end
  147.        
  148.         local f = fs.open(fullpath, "w")
  149.        
  150.         -- Unpack file
  151.         local line = table.remove(t, 1)
  152.         while line ~= "`STOP`" and line do
  153.             f.writeLine(line)
  154.             line = table.remove(t, 1)
  155.         end
  156.        
  157.         f.close()
  158.     end
  159.    
  160.     print("Done!")
  161. end
  162.  
  163. local function fileRead(path)
  164.     local f = fs.open(path, "r") or error("Can not open file "..path, 0)
  165.     local s = f.readAll()
  166.     f.close()
  167.    
  168.     return code(s)
  169. end
  170.  
  171. local function file(fout, path, out)
  172.     -- Code write func
  173.     local function codeWrite(str)
  174.         fout.write(code(str)..string.char(2))
  175.     end
  176.    
  177.     if fs.exists(path) then
  178.         if fs.isDir(path) and (not string.find(path, "/rom")) then
  179.             -- Loop trough all dirs
  180.             for k, v in ipairs(fs.list(path)) do
  181.                 file(fout, path.."/"..v, out)
  182.             end
  183.         elseif (not string.find(path, "/"..out)) and (not string.find(path, "/rom")) then
  184.             print("  Doing "..path)
  185.             codeWrite(path)
  186.             fout.write(fileRead(path)..string.char(2))
  187.             codeWrite("`STOP`")
  188.             print("    File "..path.." done!")
  189.         else
  190.             print("###WARNING### TRIED TO COMPRESS OUTPUT/BANNED FILE/FOLDER (?) - "..path)
  191.         end
  192.     else
  193.         error("File "..path.." does not exist!", 0)
  194.     end
  195. end
  196.  
  197. local function fzip(...)
  198.     -- Error checks
  199.     local pars = {...}
  200.     local name = table.remove(pars, 1) or error("No name specified!", 0)
  201.     local out = table.remove(pars, 1) or error("No output file specified!", 0)
  202.    
  203.     if fs.exists(out) then
  204.         if not confirm("File "..out.." exists. Overwrite? [y/n]") then
  205.             return
  206.         end
  207.        
  208.         fs.delete(out)
  209.     end
  210.    
  211.     -- Open out file
  212.     local f = fs.open(out, "w")
  213.    
  214.     -- Code write func
  215.     local function codeWrite(str)
  216.         f.write(code(str)..string.char(2))
  217.     end
  218.    
  219.     -- Write headers
  220.     codeWrite("`ZIP`")
  221.     codeWrite(name)
  222.    
  223.     for k, v in ipairs(pars) do
  224.         local fullpath = shell.dir().."/"..v or error("It should have not happened...", 0)
  225.         if fs.exists(fullpath) then
  226.             file(f, fullpath, out)
  227.         else
  228.             f.close()
  229.             error("File "..fullpath.." does not exist!", 0)
  230.         end
  231.     end
  232.     f.close()
  233.    
  234.     print("Done!")
  235. end
  236.  
  237. local args = {...}
  238. args[1] = args[1] or ""
  239. args[1] = args[1]:lower()
  240.  
  241. if args[1] == "u" or args[1] == "unzip" then
  242.     assert(args[2], "No file specified!")
  243.     unzip(args[2])
  244. elseif args[1] == "z" or args[1] == "zip" then
  245.     table.remove(args, 1)
  246.     fzip(unpack(args))
  247. elseif args[1] == "loadapi" then
  248.     -- Globals
  249.     zip = {}
  250.     zip.zip = fzip
  251.     zip.unzip = unzip
  252. else
  253.     usage()
  254. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement