Work with Zip archives.
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 GotZipYou 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.
List all entries in the archive.
allEntries =
Zip.ls zipFiles 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.ls
|> List.filter (not << Entry.isDirectory)Get an entry by its absolute path.
zip |> Zip.byPath "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.byPath "versions" == Nothing
zip |> Zip.byPath "versions/" == Just EntryYou can alter archives or create your own.
Checkout the Build section of the Zip.Entry module to learn how to make your own entries.
Create an archive from a list of entries.
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 byPath function:
case zip |> Zip.byPath path of
Nothing ->
-- Entry does not exist, create and add it
zip |> Zip.insert (createEntry ())
Just _ ->
-- Entry already exists, leave archive as it is
zipOnly keep entries that pass a given test.
Remove entries by path:
filter (\entry -> Entry.path entry /= "sample/version.json") zipKeep all files under 1MB:
filter (\entry -> Entry.extractedSize entry < 1048576) zipKeep only .txt files:
filter (String.endsWith ".txt" << Entry.path) zipWrite 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"
)
Represents a Zip archive.
An archive is comprised of entries which represent files -that may be compressed- and directories.