Copyright | (c) digitally induced GmbH 2020 |
---|---|
Safe Haskell | None |
This modules provides high-level file and image upload functionality.
All uploaded files are saved to the uploads
directory. Given e.g. an User entity with id = 550e8400-e29b-11d4-a716-446655440000
, the file is saved to /uploads/users/550e8400-e29b-11d4-a716-446655440000/picture.jpg
. If the directory does not exists, it will be created.
Synopsis
- fileOrNothing :: (?context :: ControllerContext) => ByteString -> Maybe (FileInfo ByteString)
- filesByName :: (?context :: ControllerContext) => ByteString -> [FileInfo ByteString]
- data ImageUploadOptions = ImageUploadOptions {}
- uploadImageWithOptions :: forall (fieldName :: Symbol) record (tableName :: Symbol). (?context :: ControllerContext, SetField fieldName record (Maybe Text), KnownSymbol fieldName, HasField "id" record (Id (NormalizeModel record)), Show (PrimaryKey (GetTableName (NormalizeModel record))), tableName ~ GetTableName record, KnownSymbol tableName) => ImageUploadOptions -> Proxy fieldName -> record -> IO record
- uploadImageFile :: forall (fieldName :: Symbol) record (tableName :: Symbol). (?context :: ControllerContext, SetField fieldName record (Maybe Text), KnownSymbol fieldName, HasField "id" record (Id (NormalizeModel record)), Show (PrimaryKey (GetTableName (NormalizeModel record))), tableName ~ GetTableName record, KnownSymbol tableName) => Text -> Proxy fieldName -> record -> IO record
- uploadPng :: forall (fieldName :: Symbol) record. (?context :: ControllerContext, SetField fieldName record (Maybe Text), HasField "id" record (Id' (GetTableName (GetModelByTableName (GetTableName record)))), Show (PrimaryKey (GetTableName (GetModelByTableName (GetTableName record)))), KnownSymbol fieldName, KnownSymbol (GetTableName record)) => Proxy fieldName -> record -> IO record
- uploadSVG :: forall (fieldName :: Symbol) record. (?context :: ControllerContext, SetField fieldName record (Maybe Text), HasField "id" record (Id' (GetTableName (GetModelByTableName (GetTableName record)))), Show (PrimaryKey (GetTableName (GetModelByTableName (GetTableName record)))), KnownSymbol fieldName, KnownSymbol (GetTableName record)) => Proxy fieldName -> record -> IO record
Documentation
fileOrNothing :: (?context :: ControllerContext) => ByteString -> Maybe (FileInfo ByteString) Source #
Returns a file upload from the request as a ByteString.
Returns Nothing
when the file is not found in the request body.
Example:
Given a form like this:
<form method="POST" action={SubmitMarkdownAction}> <input type="file" name="markdown" accept="text/markdown, text/plain" > </form>
The file can be accessed within the action like this:
action SubmitMarkdownAction = do let content :: Text = fileOrNothing "markdown" |> fromMaybe (error "no file given") |> (.fileContent) |> cs -- content is a LazyByteString, so we use `cs` to convert it to Text
See filesByName
if multiple files can be uploaded by the user in a single form submission.
See storeFile
to upload the file to S3 or similar cloud storages.
filesByName :: (?context :: ControllerContext) => ByteString -> [FileInfo ByteString] Source #
Like fileOrNothing
but allows uploading multiple files in the same request
Example:
For uploading multiple files we need to set the multiple attribute on the file input:
<form method="POST" action={SubmitMarkdownAction}> <input type="file" name="markdown" accept="text/markdown, text/plain" multiple > </form>
When the user selects multiple files, we can access them like this:
action SubmitMarkdownAction = do let contents :: [Text] = filesByName "markdown" |> map (.fileContent) |> map cs -- content is a LazyByteString, so we use `cs` to convert it to Text
Use forEach
to store multiple files inside the cloud storage:
action SubmitMarkdownAction = do let markdownFiles = filesByName "markdown" forEach markdownFiles \file -> do storeFile file "notes" pure ()
data ImageUploadOptions Source #
Options to be used together with uploadImageWithOptions
Example:
ImageUploadOptions { convertTo = "jpg", imageMagickOptions = "-resize '1024x1024^' -gravity north -extent 1024x1024 -quality 85% -strip" }
ImageUploadOptions | |
|
uploadImageWithOptions :: forall (fieldName :: Symbol) record (tableName :: Symbol). (?context :: ControllerContext, SetField fieldName record (Maybe Text), KnownSymbol fieldName, HasField "id" record (Id (NormalizeModel record)), Show (PrimaryKey (GetTableName (NormalizeModel record))), tableName ~ GetTableName record, KnownSymbol tableName) => ImageUploadOptions -> Proxy fieldName -> record -> IO record Source #
Saves an uploaded image file to the uploads
directory and writes the relative path to the given record attribute.
Given e.g. an User entity with id = 550e8400-e29b-11d4-a716-446655440000
, the file is saved to /uploads/users/550e8400-e29b-11d4-a716-446655440000/picture.jpg
.
Before saving, the image is converted using imagemagick. You can supply custom image magick options using the options attribute.
If the upload directory does not exists, it will be created.
Example: Uploading a user profile picture
let profilePictureOptions = ImageUploadOptions { convertTo = "jpg" , imageMagickOptions = "-resize '1024x1024^' -gravity north -extent 1024x1024 -quality 85% -strip" } user |> fill @["firstname", "lastname", "pictureUrl"] |> uploadImageWithOptions profilePictureOptions #pictureUrl >>= ifValid \case Left user -> render EditView { .. } Right user -> do user <- user |> updateRecord redirectTo EditUserAction { .. }
The uploaded image path is now stored in #pictureUrl.
uploadImageFile :: forall (fieldName :: Symbol) record (tableName :: Symbol). (?context :: ControllerContext, SetField fieldName record (Maybe Text), KnownSymbol fieldName, HasField "id" record (Id (NormalizeModel record)), Show (PrimaryKey (GetTableName (NormalizeModel record))), tableName ~ GetTableName record, KnownSymbol tableName) => Text -> Proxy fieldName -> record -> IO record Source #
Saves an uploaded image file to the uploads
directory.
Given e.g. an User entity with id = 550e8400-e29b-11d4-a716-446655440000
, the file is saved to /uploads/users/550e8400-e29b-11d4-a716-446655440000/picture.jpg
.
No transformation or validation is applied to the given uploaded file. If you need this, take a look at uploadImageWithOptions
.
Example: Uploading a user profile picture
let profilePictureOptions = ImageUploadOptions { convertTo = "jpg" , imageMagickOptions = "-resize '1024x1024^' -gravity north -extent 1024x1024 -quality 85% -strip" } user |> fill @["firstname", "lastname", "pictureUrl"] |> uploadImageFile "png" #pictureUrl >>= ifValid \case Left user -> render EditView { .. } Right user -> do user <- user |> updateRecord redirectTo EditUserAction { .. }
uploadPng :: forall (fieldName :: Symbol) record. (?context :: ControllerContext, SetField fieldName record (Maybe Text), HasField "id" record (Id' (GetTableName (GetModelByTableName (GetTableName record)))), Show (PrimaryKey (GetTableName (GetModelByTableName (GetTableName record)))), KnownSymbol fieldName, KnownSymbol (GetTableName record)) => Proxy fieldName -> record -> IO record Source #
Saves an uploaded png file. No validation or transformation applied.
See uploadImageFile
for details.
uploadSVG :: forall (fieldName :: Symbol) record. (?context :: ControllerContext, SetField fieldName record (Maybe Text), HasField "id" record (Id' (GetTableName (GetModelByTableName (GetTableName record)))), Show (PrimaryKey (GetTableName (GetModelByTableName (GetTableName record)))), KnownSymbol fieldName, KnownSymbol (GetTableName record)) => Proxy fieldName -> record -> IO record Source #
Saves an uploaded svg file. No validation or transformation applied.
See uploadImageFile
for details.