Work with Zip archives.
Represents a Zip archive.
An archive is comprised of entries which represent files -that may be compressed- and directories.
fromBytes : Bytes -> Maybe Zip
Read a Zip
from Bytes
.
If you have an uploaded File of an archive,
you can use File.toBytes
to read it:
import File exposing (File)
import Task exposing (Task)
import Zip exposing (Zip)
type Msg
= GotZip (Maybe Zip)
readArchive : File -> Cmd Msg
readArchive file =
file
|> File.toBytes
|> Task.map Zip.fromBytes
|> Task.perform GotZip
You can also get Bytes
from somewhere else, such as an HTTP request,
or even from within another archive.
Once you have a Zip
, you can use it to access its files and directories.
Use the Zip.Entry module to do read their content and metadata.
entries : Zip -> List Internal.Format.Entry
Get all entries in the archive.
allEntries =
Zip.entries zip
Files and directories get their own entries.
If you only care about one kind, you can use the Zip.Entry.isDirectory
function to filter them:
allFiles =
zip
|> Zip.entries
|> List.filter (not << Entry.isDirectory)
getEntry : String -> Zip -> Maybe Internal.Format.Entry
Get an entry by its absolute path.
zip |> Zip.getEntry "versions/v1.txt"
Nothing
is returned if no entry matches the path exactly.
Directory entries are typically stored in the archive with a slash at the end:
zip |> Zip.getEntry "versions" == Nothing
zip |> Zip.getEntry "versions/" == Just (Entry(..))
count : Zip -> Basics.Int
Count the number of entries in an archive.
isEmpty : Zip -> Basics.Bool
Determine if an archive is empty.
You can alter archives or create your own.
Checkout the Build section of the Zip.Entry
module to learn how to make your own entries.
empty : Zip
An empty archive with no entries.
From here, you can use insert
to add some entries.
fromEntries : List Internal.Format.Entry -> Zip
Create an archive from a list of entries.
insert : Internal.Format.Entry -> Zip -> Zip
Add a new entry to the archive.
This function replaces entries with the same path. You can conditionally add it by checking existence with the getEntry
function:
case zip |> Zip.getEntry path of
Nothing ->
-- Entry does not exist, create and add it
zip |> Zip.insert (createEntry ())
Just _ ->
-- Entry already exists, leave archive as it is
zip
filter : (Internal.Format.Entry -> Basics.Bool) -> Zip -> Zip
Only keep entries that pass a given test.
Remove entries by path:
filter (\entry -> Entry.path entry /= "sample/version.json") zip
Keep all files under 1MB:
filter (\entry -> Entry.extractedSize entry < 1048576) zip
Keep only .txt
files:
filter (Entry.path >> String.endsWith ".txt") zip
toBytes : Zip -> Bytes
Write a Zip
to Bytes
.
From here, you can download the archive, upload it to a server, etc.
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
DownloadArchive ->
( model
, model.zip
|> Zip.toBytes
|> File.Download.bytes "archive.zip" "application/zip"
)