module Aws.S3.Commands.DeleteObjects where
import Aws.Core
import Aws.S3.Core
import qualified Crypto.Hash as CH
import qualified Data.Map as M
import Data.Maybe
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import qualified Network.HTTP.Conduit as HTTP
import qualified Network.HTTP.Types as HTTP
import qualified Text.XML as XML
import qualified Text.XML.Cursor as Cu
import Text.XML.Cursor (($/), (&|))
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Char8 ()
import Control.Applicative ((<$>))
data DeleteObjects
= DeleteObjects {
dosBucket :: Bucket
, dosObjects :: [(Object, Maybe T.Text)]
, dosQuiet :: Bool
, dosMultiFactorAuthentication :: Maybe T.Text
}
deriving (Show)
deleteObjects :: Bucket -> [T.Text] -> DeleteObjects
deleteObjects bucket objs =
DeleteObjects {
dosBucket = bucket
, dosObjects = zip objs $ repeat Nothing
, dosQuiet = True
, dosMultiFactorAuthentication = Nothing
}
data DeleteObjectsResponse
= DeleteObjectsResponse {
dorDeleted :: [DORDeleted]
, dorErrors :: [DORErrors]
}
deriving (Show)
data DORDeleted
= DORDeleted {
ddKey :: T.Text
, ddVersionId :: Maybe T.Text
, ddDeleteMarkerVersionId :: Maybe T.Text
}
deriving (Show)
data DORErrors
= DORErrors {
deKey :: T.Text
, deCode :: T.Text
, deMessage :: T.Text
}
deriving (Show)
instance SignQuery DeleteObjects where
type ServiceConfiguration DeleteObjects = S3Configuration
signQuery DeleteObjects {..} = s3SignQuery S3Query
{
s3QMethod = Post
, s3QBucket = Just $ T.encodeUtf8 dosBucket
, s3QSubresources = HTTP.toQuery [("delete" :: B.ByteString, Nothing :: Maybe B.ByteString)]
, s3QQuery = []
, s3QContentType = Nothing
, s3QContentMd5 = Just $ CH.hashlazy dosBody
, s3QObject = Nothing
, s3QAmzHeaders = maybeToList $ (("x-amz-mfa", ) . T.encodeUtf8) <$> dosMultiFactorAuthentication
, s3QOtherHeaders = []
, s3QRequestBody = Just $ HTTP.RequestBodyLBS dosBody
}
where dosBody = XML.renderLBS XML.def XML.Document {
XML.documentPrologue = XML.Prologue [] Nothing []
, XML.documentRoot = root
, XML.documentEpilogue = []
}
root = XML.Element {
XML.elementName = "Delete"
, XML.elementAttributes = M.empty
, XML.elementNodes = quietNode dosQuiet : (objectNode <$> dosObjects)
}
objectNode (obj, mbVersion) = XML.NodeElement XML.Element {
XML.elementName = "Object"
, XML.elementAttributes = M.empty
, XML.elementNodes = keyNode obj : maybeToList (versionNode <$> mbVersion)
}
versionNode = toNode "VersionId"
keyNode = toNode "Key"
quietNode b = toNode "Quiet" $ if b then "true" else "false"
toNode name content = XML.NodeElement XML.Element {
XML.elementName = name
, XML.elementAttributes = M.empty
, XML.elementNodes = [XML.NodeContent content]
}
instance ResponseConsumer DeleteObjects DeleteObjectsResponse where
type ResponseMetadata DeleteObjectsResponse = S3Metadata
responseConsumer _ _ = s3XmlResponseConsumer parse
where parse cursor = do
dorDeleted <- sequence $ cursor $/ Cu.laxElement "Deleted" &| parseDeleted
dorErrors <- sequence $ cursor $/ Cu.laxElement "Error" &| parseErrors
return DeleteObjectsResponse {..}
parseDeleted c = do
ddKey <- force "Missing Key" $ c $/ elContent "Key"
let ddVersionId = listToMaybe $ c $/ elContent "VersionId"
ddDeleteMarkerVersionId = listToMaybe $ c $/ elContent "DeleteMarkerVersionId"
return DORDeleted {..}
parseErrors c = do
deKey <- force "Missing Key" $ c $/ elContent "Key"
deCode <- force "Missing Code" $ c $/ elContent "Code"
deMessage <- force "Missing Message" $ c $/ elContent "Message"
return DORErrors {..}
instance Transaction DeleteObjects DeleteObjectsResponse
instance AsMemoryResponse DeleteObjectsResponse where
type MemoryResponse DeleteObjectsResponse = DeleteObjectsResponse
loadToMemory = return