PaymentOption

Better zip

Oct 7th, 2012
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.42 KB | None | 0 0
  1. -- VARIABLES --
  2. sSeparator = "!SPLIT!" -- The string that separates stored data in an archive.
  3. ---------------
  4.  
  5. -- Gets the desired function to be performed from the user.
  6. -- Extraction or packaging.
  7. function getMode()
  8.     write('\n' .. "Extract or package?: ")
  9.     local sMode = string.lower(read())
  10.  
  11.     if sMode == "extract" or sMode == "package" then
  12.         return sMode
  13.     else
  14.         return false
  15.     end
  16. end
  17.  
  18. function getZipPath()
  19.     local sMode = getMode()
  20.  
  21.     if sMode == "extract" then
  22.         write("Zip to extract path: ")
  23.         local sZipPath = read()
  24.  
  25.         if fs.exists(sZipPath) and not fs.isDir(sZipPath) then
  26.             write('\n' .. "Extraction path: ")
  27.             local sExtractionPath = read()
  28.  
  29.             if not fs.exists(sExtractionPath) then
  30.                  if extractZip(sZipPath, sExtractionPath) then
  31.                     print("Extraction successful.")
  32.                  else
  33.                     print("Extraction failure.")
  34.                  end
  35.             else
  36.                 error('\n' .. "Extraction path already exists.")
  37.             end
  38.         else
  39.             error('\n' .. "Zip not found.")
  40.         end
  41.     elseif sMode == "package" then
  42.         write("Directory to package path: ")
  43.         local sDirPath = read()
  44.  
  45.         if fs.isDir(sDirPath) and #(fs.list(sDirPath)) > 0 then
  46.             write('\n' .. "Packaged zip path: ")
  47.             local sPackagePath = read()
  48.  
  49.             if not fs.exists(sPackagePath) then
  50.                 if packageDirectory(sDirPath, sPackagePath) then
  51.                     print("Packaing successful.")
  52.                 else
  53.                     print("Packaging failure.")
  54.                 end
  55.             else
  56.                 error("Package path already exists.")
  57.             end
  58.         else
  59.             error('\n' .. "Directory not found, or insufficient file count.")
  60.         end
  61.     else
  62.         error("Unrecognized mode.")
  63.     end
  64. end
  65.  
  66. -- Takes a directory, reads all of the files into a table,
  67. -- then writes the files into a new file (.zip) in the following format:
  68. -- <filename>!*S*!<fileContents>
  69. function packageDirectory(sDirPath, sPackagePath)
  70.     -- Make sure that the directory exists and has files in it.
  71.     if fs.isDir(sDirPath) and #(fs.list(sDirPath)) > 0 then
  72.         -- Get a list of all of the files, and store their contents into a table.
  73.         -- Zip table format: tNewZip[n] = {sName (string), sContents (string)}
  74.         local tNewZip = {} -- The table that will store the name and contents of each file. tNewZip[n] = {sName (string), sContents (string)}
  75.         local tFiles = fs.list(sDirPath) -- All of the files that exist within the directory to be zipped.
  76.  
  77.         local fileHandle = nil -- The file handle of the current file being zipped.
  78.         local sFileContents = "" -- The contents of the current file being zipped.
  79.  
  80.         -- Run through all of the files in the directory and extract the contents and name into tNewZip.
  81.         for nFileIndex, sFileName in ipairs(tFiles) do
  82.             -- Get a handle on the current file, get its contents, then close the handle.
  83.             fileHandle = fs.open(sDirPath .. '/' .. sFileName, 'r')
  84.             sFileContents = fileHandle.readAll()
  85.             fileHandle.close()
  86.  
  87.             -- Add a new entry to the zip table.
  88.             table.insert(tNewZip, {sName = sFileName, sContents = sFileContents})
  89.         end
  90.  
  91.         -- Now that all of the files and their respective contents have been put into a table,
  92.         -- package the table into a .zip file.
  93.  
  94.         -- If the zip archive was generated successfuly, then return a successful package.
  95.         if generateZipArchive(tNewZip, sPackagePath) then
  96.             return true
  97.         -- If the zip archive was not generated successfuly, then return a failed package.
  98.         else
  99.             return false
  100.         end
  101.     -- If the directory provided doesn't exist, or doesn't have any files to package.
  102.     else
  103.         return false -- Report a failure.
  104.     end
  105. end
  106.  
  107. -- Takes a zip formatted table: tZip[n] = {sName (string), sContents (string)},
  108. -- then puts each entry in a file with a .zip extension.
  109. -- The file is structured like this:
  110. --  <filename>!*S*!<fileContents> and so on.
  111. function generateZipArchive(tZip, sZipName)
  112.     -- Make sure that the zip table given is not nil, so we won't have any exceptions.
  113.     if tZip then
  114.         -- Get a file handle on the zip file that we are creating.
  115.         -- Make sure that the file doesn't already exist.
  116.         if not fs.exists(sZipName .. '.zip') then
  117.             local zipFileHandle = fs.open('/' .. sZipName .. '.zip' , 'w') -- Get the file handle.
  118.             -- Validate the file handle.
  119.             if zipFileHandle then
  120.                 local sZippedContents = "" -- The string that will contain the properly formatted zip file contents.
  121.                 -- Loop through the table, writing each entry as:
  122.                 --  <filename>!*S*!<fileContents> in the file.
  123.                 for nFileIndex, tFileEntry in ipairs(tZip) do
  124.                     -- Concatenate the file name, then the separation string, then the file contents, then the separation string again.
  125.                     sZippedContents = sZippedContents .. tFileEntry.sName .. sSeparator .. tFileEntry.sContents .. sSeparator
  126.                 end
  127.  
  128.                 -- Now that we have the properly formatted zipped file contents in a string, simply write
  129.                 -- the string to the file, then close the file handle.
  130.                 zipFileHandle.write(sZippedContents)
  131.                 zipFileHandle.close()
  132.  
  133.                 -- Report a successful zip generation.
  134.                 return true
  135.             -- If the zip file handle is not valid, return a failure.
  136.             else
  137.                 return false
  138.             end
  139.         -- If the file we're creating already exists, either as a file or a directory, return a failure.
  140.         else
  141.             return false
  142.         end
  143.     -- If the zip table passed is non-existant, then return a failure.
  144.     else
  145.         return false
  146.     end
  147. end
  148.  
  149. -- Takes a formatted, extracted zip archive and places its contents into a directory.
  150. function createExtratedDirectory(tZip, sDirPath)
  151.     -- Create the directory then secure an identifier for our file handles.
  152.     fs.makeDir(sDirPath)
  153.     local fileHandle = nil
  154.  
  155.     -- Loop through the zip table and create a file for each entry.
  156.     for nFileIndex, tFile in ipairs(tZip) do
  157.         -- Get a handle on the current file, write its contents to aforementioned file, then close it.
  158.         fileHandle = fs.open(sDirPath .. '/' .. tFile.sName, 'w')
  159.         -- Make sure that the file handle is valid.
  160.         if fileHandle then
  161.             fileHandle.write(tFile.sContents)
  162.             fileHandle.close()
  163.         -- If the file handle is not valid, return a failed creation.
  164.         else
  165.             return false
  166.         end
  167.     end
  168.     -- Report a successful creation.
  169.     return true
  170. end
  171.  
  172. -- Takes a string and a pattern, then returns a table that contains
  173. -- entries of substrings that are separated by the passed pattern.
  174. -- Borrowed from: http://lua-users.org/wiki/SplitJoin
  175. -- Compatibility: Lua-5.1
  176. function split(str, pat)
  177.    local t = {}  -- NOTE: use {n = 0} in Lua-5.0
  178.    local fpat = "(.-)" .. pat
  179.    local last_end = 1
  180.    local s, e, cap = str:find(fpat, 1)
  181.    while s do
  182.       if s ~= 1 or cap ~= "" then
  183.      table.insert(t,cap)
  184.       end
  185.       last_end = e+1
  186.       s, e, cap = str:find(fpat, last_end)
  187.    end
  188.    if last_end <= #str then
  189.       cap = str:sub(last_end)
  190.       table.insert(t, cap)
  191.    end
  192.    return t
  193. end
  194.  
  195. -- Takes a zip file and extracts its contents into a directory.
  196. function extractZip(sZipPath, sDirPath)
  197.     -- Make sure that the zip given exists.
  198.     if fs.exists(sZipPath) and not fs.isDir(sZipPath) then
  199.         -- Make sure the directory path to extract the zip to does not exist.
  200.         if not fs.exists(sDirPath) then
  201.             -- Get a handle on the zip file, get its contents, then close the file handle.
  202.             local zipFileHandle = fs.open(sZipPath, 'r')
  203.             local sZipContents = zipFileHandle.readAll()
  204.             zipFileHandle.close()
  205.  
  206.             -- Now that we have the contents of the zip, unformat it into a table.
  207.             -- tUnzipped[n] = {sName (string), sContents (string)}
  208.             local tUnzipped_Raw = split(sZipContents, sSeparator) -- The raw split of the file.
  209.             local tUnzipped = {} -- This will be the final, formatted version of the unzipped file.
  210.             -- Loop through the raw split zip and format it into the final table.
  211.             --  Odd entries are the name of the file, while the even entries are the contents of the file.
  212.             for nIndex = 1, #tUnzipped_Raw, 2 do
  213.                 table.insert(tUnzipped, {sName = tUnzipped_Raw[nIndex], sContents = tUnzipped_Raw[nIndex + 1]})
  214.             end
  215.  
  216.             -- Now that we have the properly formatted table, create the directory.
  217.             -- If the unzipped archive was properly put into a directory, return a successful extraction.
  218.             if createExtratedDirectory(tUnzipped, sDirPath) then
  219.                 return true
  220.             -- If the unzipped archive was not properly put into a directory, return a failed extraction.
  221.             else
  222.                 return false
  223.             end
  224.         -- If the directory path to extract the zip already exists, return a failed extraction.
  225.         else
  226.             return false
  227.         end
  228.     -- If the zip given does not exist, or is a directory, return a failed extraction.
  229.     else
  230.         return false
  231.     end
  232. end
  233.  
  234. getZipPath()
Advertisement
Add Comment
Please, Sign In to add comment