IHP Api Reference
Copyright(c) digitally induced GmbH 2021
Safe HaskellSafe-Inferred

IHP.FileStorage.ControllerFunctions

Description

 
Synopsis

Documentation

storeFile :: (?context :: context, ConfigProvider context) => FileInfo LByteString -> Text -> IO StoredFile Source #

Uploads a file to a directory in the storage

See storeFileWithOptions for more advanced use cases.

Example: Save a file upload by the user to the storage

action UpdateLogoAction = do
    let file = fileOrNothing "file"
            |> fromMaybe (error "No file given")

    storedFile <- storeFile file "logos"

    let url = get #url storedFile

removeFileFromStorage :: (?context :: context, ConfigProvider context) => StoredFile -> IO (Either MinioErr ()) Source #

Permanently removes a previously stored file from storage.

Example: Delete a previously uploaded file. The objectPath and url are stored in the database in this example.

action DeleteUploadedFileAction { uploadedFileId } = do
    uploadedFile <- fetch uploadedFile
    let storedFile = StoredFile
            { path = get #objectPath uploadedFile
            , url = get #url uploadedFile
            }
    removeFileFromStorage storedFile
    deleteRecord uploadedFile
    redirectTo UploadedFilesAction

storeFileWithOptions :: (?context :: context, ConfigProvider context) => FileInfo LByteString -> StoreFileOptions -> IO StoredFile Source #

Like storeFile but with more options.

See storeFileWithOptions for more advanced use cases.

Example: Save a file to my_files directory and specify a 'Content-Disposition: attachment; filename="$filename"' header

let file = fileOrNothing "file" |> fromMaybe (error "no file given")

let options :: StoreFileOptions = def
        { directory = "my_files"
        , contentDisposition = contentDispositionAttachmentAndFileName
        }

storedFile <- storeFileWithOptions file options
let url = get #url storedFile

Example: Transform an uploaded image to a JPEG file, strip meta data and store it inside the pictures directory

let file = fileOrNothing "file" |> fromMaybe (error "no file given")

let options :: StoreFileOptions = def
        { directory = "pictures"
        , preprocess = applyImageMagick "jpg" "-strip"
        }

storedFile <- storeFileWithOptions file options
let url = get #url storedFile

storeFileFromUrl :: (?context :: context, ConfigProvider context) => Text -> StoreFileOptions -> IO StoredFile Source #

Fetches an url and uploads it to the storage.

The stored file has the content type provided by Content-Type header of the downloaded file.

Example: Copy a file from a remote server to the pictures directory

let externalUrl = "http://example/picture.jpg"

let options :: StoreFileOptions = def
        { directory = "pictures"
        }

storedFile <- storeFileFromUrl externalUrl options
let newUrl = get #url storedFile

storeFileFromPath :: (?context :: context, ConfigProvider context) => Text -> StoreFileOptions -> IO StoredFile Source #

Uploads a local file to the storage

The content type is guessed based on the file extension.

Example: Copy a local "picture.jpg" to the pictures directory inside the storage

let options :: StoreFileOptions = def
        { directory = "pictures"
        }

storedFile <- storeFileFromPath "picture.jpg" options
let newUrl = get #url storedFile

createTemporaryDownloadUrl :: (?context :: context, ConfigProvider context) => StoredFile -> IO TemporaryDownloadUrl Source #

Returns a signed url for a StoredFile. The url is valid for 7 days.

If the StaticDirStorage is used, a unsigned normal URL will be returned, as these files are public anyways.

Example: Get a signed url for a stored file using createTemporaryDownloadUrl

let file = fileOrNothing "file"
        |> fromMaybe (error "No file given")

storedFile <- storeFile file "logos"

signedUrl <- createTemporaryDownloadUrl storedFile

let url :: Text = get #url signedUrl
let expiredAt :: UTCTime = get #expiredAt signedUrl

createTemporaryDownloadUrlFromPath :: (?context :: context, ConfigProvider context) => Text -> IO TemporaryDownloadUrl Source #

Returns a signed url for a path inside the storage. The url is valid for 7 days.

If the StaticDirStorage is used, a unsigned normal URL will be returned, as these files are public anyways.

Example: Get a signed url for a path

signedUrl <- createTemporaryDownloadUrlFromPath "logos/8ed22caa-11ea-4c45-a05e-91a51e72558d"

let url :: Text = get #url signedUrl
let expiredAt :: UTCTime = get #expiredAt signedUrl

See createTemporaryDownloadUrlFromPathWithExpiredAt if you want to customize the url expiration time of 7 days.

createTemporaryDownloadUrlFromPathWithExpiredAt :: (?context :: context, ConfigProvider context) => Int -> Text -> IO TemporaryDownloadUrl Source #

Like createTemporaryDownloadUrlFromPath, but with a custom expiration time. Returns a signed url for a path inside the storage. The url is valid for 7 days.

If the StaticDirStorage is used, a unsigned normal URL will be returned, as these files are public anyways.

Example: Get a signed url for a path that expires in 5 minutes

let validInSeconds = 5 * 60
signedUrl <- createTemporaryDownloadUrlFromPathWithExpiredAt validInSeconds "logos/8ed22caa-11ea-4c45-a05e-91a51e72558d"

let url :: Text = get #url signedUrl
let expiredAt :: UTCTime = get #expiredAt signedUrl

uploadToStorage :: 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, HasField "meta" record MetaBag, SetField "meta" record MetaBag) => Proxy fieldName -> record -> IO record Source #

Saves an upload to the storage and sets the record attribute to the url.

Uses the table name of the record as the upload directory (e.g. companies when saving an attachment for a Company record).

See uploadToStorageWithOptions if you want to provide custom options.

Example: Upload a logo for a Company

action UpdateCompanyAction { companyId } = do
    company <- fetch companyId
    company
        |> fill @'["name"]
        |> uploadToStorage #logoUrl
        >>= ifValid \case
            Left company -> render EditView { .. }
            Right company -> do
                company <- company |> updateRecord
                redirectTo EditCompanyAction { .. }

uploadToStorageWithOptions :: 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, HasField "meta" record MetaBag, SetField "meta" record MetaBag) => StoreFileOptions -> Proxy fieldName -> record -> IO record Source #

Saves an upload to the storage and sets the record attribute to the url.

Example: Upload a logo for a Company and convert it to a 512x512 PNG

action UpdateCompanyAction { companyId } = do
    let uploadLogo = uploadToStorageWithOptions $ def
            { preprocess = applyImageMagick "png" "-resize '512x512^' -gravity north -extent 512x512 -quality 100% -strip"  }

    company <- fetch companyId
    company
        |> fill @'["name"]
        |> uploadLogo #logoUrl
        >>= ifValid \case
            Left company -> render EditView { .. }
            Right company -> do
                company <- company |> updateRecord
                redirectTo EditCompanyAction { .. }