{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
module Data.CAS.ContentHashable.S3 where
import qualified Aws
import qualified Aws.S3 as S3
import Control.Monad ((>=>))
import Control.Monad.Trans.Resource (runResourceT)
import Data.Aeson
import Data.CAS.ContentHashable
import Data.Constraint
import Data.Reflection
import GHC.Generics (Generic)
import Network.HTTP.Conduit (newManager,
tlsManagerSettings)
data ObjectInBucket obj = ObjectInBucket
{ _oibBucket :: S3.Bucket
, _oibObject :: obj
} deriving (Show, Generic)
oibBucket :: Functor f => (S3.Bucket -> f S3.Bucket) -> ObjectInBucket obj -> f (ObjectInBucket obj)
oibBucket f oib = rebuild <$> f (_oibBucket oib)
where rebuild b = oib{_oibBucket=b}
oibObject :: Functor f => (a -> f b) -> ObjectInBucket a -> f (ObjectInBucket b)
oibObject f oib = rebuild <$> f (_oibObject oib)
where rebuild o = oib{_oibObject=o}
instance FromJSON (ObjectInBucket S3.Object)
instance ToJSON (ObjectInBucket S3.Object)
class ObjectReference a where
objectReference :: a -> S3.Object
instance ObjectReference S3.Object where
objectReference = id
instance ObjectReference S3.ObjectInfo where
objectReference = S3.objectKey
instance (Given Aws.Configuration)
=> ContentHashable IO (ObjectInBucket S3.Object) where
contentHashUpdate ctx a = let
s3cfg = Aws.defServiceConfig :: S3.S3Configuration Aws.NormalQuery
in do
mgr <- newManager tlsManagerSettings
S3.GetObjectResponse { S3.gorMetadata = md } <- runResourceT $
Aws.pureAws given s3cfg mgr $
S3.getObject (_oibBucket a) (_oibObject a)
flip contentHashUpdate (_oibBucket a)
>=> flip contentHashUpdate (_oibObject a)
>=> flip contentHashUpdate (S3.omETag md)
$ ctx
instance (Given Aws.Configuration)
:=> ContentHashable IO (ObjectInBucket S3.Object) where
ins = Sub Dict
instance Monad m => ContentHashable m (ObjectInBucket S3.ObjectInfo) where
contentHashUpdate ctx a =
flip contentHashUpdate (_oibBucket a)
>=> flip contentHashUpdate (S3.objectKey $ _oibObject a)
>=> flip contentHashUpdate (S3.objectETag $ _oibObject a)
$ ctx
instance (Given Aws.Configuration)
:=> ContentHashable IO (ObjectInBucket S3.ObjectInfo) where
ins = Sub Dict