haskell-aliyun-0.1.0.0: Network/Aliyun/Types.hs
{-# LANGUAGE OverloadedStrings #-}
module Network.Aliyun.Types
( Owner(..)
, BucketList(..)
, BucketFile(..)
, Bucket(..)
, BucketContent(..)
, BucketACL(..)
, DeleteResult(..)
, CopyResult(..)
) where
import qualified Prelude as P
import BasicPrelude
import Safe (readMay)
import Control.Applicative ((<|>))
import qualified Data.Text as T
import qualified Data.Vector as V
import Data.Aeson.Types (typeMismatch, Parser)
import Data.Aeson (FromJSON(parseJSON), Value(..), (.:), (.:?))
import Data.Time.Clock (UTCTime(UTCTime))
import Data.Time.Format (parseTime)
import System.Locale (defaultTimeLocale)
data Owner = Owner
{ ownerId :: !Text
, ownerName :: !Text
} deriving (Show)
instance FromJSON Owner where
parseJSON (Object o) =
Owner <$> o .: "ID" <*> o .: "DisplayName"
parseJSON o =
typeMismatch "Object" o
data BucketList = BucketList
{ bucketOwner :: !Owner
, bucketList :: ![(Text, UTCTime)]
} deriving (Show)
instance FromJSON BucketList where
parseJSON (Object o) = do
root <- o .: "ListAllMyBucketsResult"
let getBuckets = root .: "Buckets" >>= (.: "Bucket")
BucketList <$> (root .: "Owner" >>= parseJSON)
<*> ( (getBuckets >>= pList pBucket)
<|> pure []
)
where
pBucket (Object a) =
(,) <$> a .: "Name"
<*> (pTime <$> a .: "CreationDate")
pBucket a = typeMismatch "Object [BucketList.bucketList[i]]" a
parseJSON a = typeMismatch "BucketList" a
data BucketFile = BucketFile
{ fileKey :: !Text
, fileLastModified :: !UTCTime
, fileETag :: !Text
, fileType :: !Text
, fileSize :: !Integer -- to support very large file
, fileStorage :: !Text
, fileOwner :: !Owner
} deriving (Show)
instance FromJSON BucketFile where
parseJSON (Object o) =
BucketFile <$> o .: "Key"
<*> (pTime <$> o .: "LastModified")
<*> o .: "ETag"
<*> o .: "Type"
<*> (o .: "Size" >>= strRead (readMay . T.unpack))
<*> o .: "StorageClass"
<*> o .: "Owner"
parseJSON a = typeMismatch "Object" a
data Bucket = Bucket
{ bucketName :: !Text
, bucketPrefix :: !Text
, bucketMarker :: !Text
, bucketMaxKeys :: !Int
, bucketDelimiter :: !Text
, bucketIsTruncated :: !Bool
, bucketNextMarker :: !(Maybe Text)
, bucketContents :: ![BucketFile]
, bucketDirectories :: ![Text]
} deriving (Show)
instance FromJSON Bucket where
parseJSON (Object o) = do
r <- o .: "ListBucketResult"
let getCommonPrefixes = r .: "CommonPrefixes" >>= (.: "Prefix")
Bucket <$> r .: "Name"
<*> r .: "Prefix"
<*> r .: "Marker"
<*> (r .: "MaxKeys" >>= strRead (readMay . T.unpack))
<*> r .: "Delimiter"
<*> (r .: "IsTruncated" >>= strBool)
<*> r .:? "NextMarker"
<*> ( (r .: "Contents" >>= pList parseJSON)
<|> pure []
)
<*> ( (getCommonPrefixes >>= pList parseJSON)
<|> pure []
)
parseJSON a = typeMismatch "Object" a
data BucketContent = ContentFile !BucketFile
| ContentDirectory !Text !UTCTime
deriving (Show)
data BucketACL = BucketACL
{ bucketACLOwner :: !Owner
, bucketACLs :: ![Text]
} deriving (Show)
instance FromJSON BucketACL where
parseJSON (Object o) = do
r <- o .: "AccessControlPolicy"
let getAcls = r .: "AccessControlList" >>= (.: "Grant")
BucketACL <$> (r .: "Owner" >>= parseJSON)
<*> ( (getAcls >>= pList parseJSON)
<|> pure []
)
parseJSON a = typeMismatch "Object" a
newtype DeleteResult = DeleteResult [Text]
deriving (Show)
instance FromJSON DeleteResult where
parseJSON (Object a) = do
r <- a .: "DeleteResult"
DeleteResult <$> ( (r .: "Deleted" >>= pList pKey)
<|> pure []
)
where
pKey (Object o) = o .: "Key"
pKey o = typeMismatch "Object" o
parseJSON o = typeMismatch "Object" o
data CopyResult = CopyResult
{ copyLastModified :: !UTCTime
, copyETag :: !Text
} deriving (Show)
instance FromJSON CopyResult where
parseJSON (Object o) = do
r <- o .: "CopyObjectResult"
CopyResult <$> (pTime <$> r .: "LastModified")
<*> r .: "ETag"
parseJSON o = typeMismatch "Object" o
-- parser utils
strRead :: (FromJSON a) => (Text -> Maybe a) -> Value -> Parser a
strRead conv o = case o of
String s ->
maybe (fail $ "convert failed:"++T.unpack s)
pure
(conv s)
_ -> parseJSON o
strBool :: Value -> Parser Bool
strBool = strRead conv
where
conv "true" = Just True
conv "false" = Just False
conv _ = Nothing
pList :: (Value -> Parser a) -> Value -> Parser [a]
pList p (Array a) = mapM p (V.toList a)
pList p a = (:[]) <$> p a
pTime :: String -> UTCTime
pTime s = fromMaybe (UTCTime (toEnum 0) 0) $ parseTime defaultTimeLocale "%FT%T.000Z" s