| Copyright | (c) digitally induced GmbH 2021 |
|---|---|
| Safe Haskell | None |
| Language | Haskell2010 |
IHP.FileStorage.ControllerFunctions
Description
Synopsis
- storeFile :: (?context :: context, ConfigProvider context) => FileInfo LByteString -> Text -> IO StoredFile
- removeFileFromStorage :: (?context :: context, ConfigProvider context) => StoredFile -> IO (Either MinioErr ())
- storeFileWithOptions :: (?context :: context, ConfigProvider context) => FileInfo LByteString -> StoreFileOptions -> IO StoredFile
- storeFileFromUrl :: (?context :: context, ConfigProvider context) => Text -> StoreFileOptions -> IO StoredFile
- storeFileFromPath :: (?context :: context, ConfigProvider context) => Text -> StoreFileOptions -> IO StoredFile
- contentDispositionAttachmentAndFileName :: FileInfo LByteString -> IO (Maybe Text)
- createTemporaryDownloadUrl :: (?context :: context, ConfigProvider context) => StoredFile -> IO TemporaryDownloadUrl
- createTemporaryDownloadUrlFromPath :: (?context :: context, ConfigProvider context) => Text -> IO TemporaryDownloadUrl
- createTemporaryDownloadUrlFromPathWithExpiredAt :: (?context :: context, ConfigProvider context) => Int -> Text -> IO TemporaryDownloadUrl
- refreshTemporaryDownloadUrlFromFile :: (?modelContext :: ModelContext, ?context :: context, ConfigProvider context, CanUpdate record, HasField "signedUrl" record Text, HasField "signedUrlExpiredAt" record UTCTime, HasField "path" record Text, SetField "signedUrl" record Text, SetField "signedUrlExpiredAt" record UTCTime, SetField "path" record Text) => record -> IO record
- 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
- 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
- storage :: (?context :: context, ConfigProvider context) => FileStorage
- storagePrefix :: (?context :: ControllerContext) => Text
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 = storedFile.url
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 = uploadedFile.objectPath
, url = uploadedFile.url
}
removeFileFromStorage storedFile
deleteRecord uploadedFile
redirectTo UploadedFilesActionstoreFileWithOptions :: (?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 = storedFile.urlExample: 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 = storedFile.urlstoreFileFromUrl :: (?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 = storedFile.urlstoreFileFromPath :: (?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 = storedFile.urlcreateTemporaryDownloadUrl :: (?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 = signedUrl.url
let expiredAt :: UTCTime = signedUrl.expiredAtcreateTemporaryDownloadUrlFromPath :: (?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 = signedUrl.url let expiredAt :: UTCTime = signedUrl.expiredAt
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 = signedUrl.url let expiredAt :: UTCTime = signedUrl.expiredAt
refreshTemporaryDownloadUrlFromFile :: (?modelContext :: ModelContext, ?context :: context, ConfigProvider context, CanUpdate record, HasField "signedUrl" record Text, HasField "signedUrlExpiredAt" record UTCTime, HasField "path" record Text, SetField "signedUrl" record Text, SetField "signedUrlExpiredAt" record UTCTime, SetField "path" record Text) => record -> IO record Source #
Use the temporary download URL if the current one is not expired. Otherwise, create a new temporary download URL and update the record.
Example: Fetch an UploadedFile record (a custom record with signedUrl, signedUrlExpiredAt and path ) and use refreshTemporaryDownloadUrlFromFile
to get a fresh signed url if expired date has passed.
and update it with the signed url.
uploadedFile <- fetch uploadedFileId uploadedFile <- refreshTemporaryDownloadUrlFromFile uploadedFile
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 { .. }storage :: (?context :: context, ConfigProvider context) => FileStorage Source #
Returns the current storage configured in Config.hs
storagePrefix :: (?context :: ControllerContext) => Text Source #
Returns the prefix for the storage. This is either static/ or an empty string depending on the storage.