--
-- MinIO Haskell SDK, (C) 2017-2023 MinIO, Inc.
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

module Network.Minio.XmlParser
  ( parseListBuckets,
    parseLocation,
    parseNewMultipartUpload,
    parseCompleteMultipartUploadResponse,
    parseCopyObjectResponse,
    parseListObjectsResponse,
    parseListObjectsV1Response,
    parseListUploadsResponse,
    parseListPartsResponse,
    parseErrResponse,
    parseNotification,
    parseSelectProgress,
  )
where

import qualified Data.ByteString.Lazy as LB
import qualified Data.HashMap.Strict as H
import Data.List (zip4, zip6)
import qualified Data.Text as T
import Data.Time
import Network.Minio.Data
import Network.Minio.XmlCommon
import Text.XML.Cursor hiding (bool)

-- | Parse the response XML of a list buckets call.
parseListBuckets :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m [BucketInfo]
parseListBuckets :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m [BucketInfo]
parseListBuckets LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      names :: [Text]
names = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"Bucket" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&// Text -> Axis
s3Elem' Text
"Name" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      timeStrings :: [Text]
timeStrings = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"Bucket" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&// Text -> Axis
s3Elem' Text
"CreationDate" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
times <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
timeStrings
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Text -> UTCTime -> BucketInfo
BucketInfo [Text]
names [UTCTime]
times

-- | Parse the response XML of a location request.
parseLocation :: (MonadIO m) => LByteString -> m Region
parseLocation :: forall (m :: * -> *). MonadIO m => LByteString -> m Text
parseLocation LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  let region :: Text
region = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Cursor -> [Text]
content
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> a -> Bool -> a
bool Text
"us-east-1" Text
region forall a b. (a -> b) -> a -> b
$ Text
region forall a. Eq a => a -> a -> Bool
/= Text
""

-- | Parse the response XML of an newMultipartUpload call.
parseNewMultipartUpload :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m UploadId
parseNewMultipartUpload :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m Text
parseNewMultipartUpload LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"UploadId" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

-- | Parse the response XML of completeMultipartUpload call.
parseCompleteMultipartUploadResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ETag
parseCompleteMultipartUploadResponse :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m Text
parseCompleteMultipartUploadResponse LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"ETag" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

-- | Parse the response XML of copyObject and copyObjectPart
parseCopyObjectResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m (ETag, UTCTime)
parseCopyObjectResponse :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m (Text, UTCTime)
parseCopyObjectResponse LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      mtimeStr :: Text
mtimeStr = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"LastModified" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  UTCTime
mtime <- forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime Text
mtimeStr
  forall (m :: * -> *) a. Monad m => a -> m a
return ([Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$// Text -> Axis
s3Elem' Text
"ETag" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content, UTCTime
mtime)

-- | Parse the response XML of a list objects v1 call.
parseListObjectsV1Response ::
  (MonadReader env m, HasSvcNamespace env, MonadIO m) =>
  LByteString ->
  m ListObjectsV1Result
parseListObjectsV1Response :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m ListObjectsV1Result
parseListObjectsV1Response LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] forall a. Eq a => a -> a -> Bool
== (Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextMarker :: Maybe Text
nextMarker = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextMarker" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      prefixes :: [Text]
prefixes = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      keys :: [Text]
keys = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      modTimeStr :: [Text]
modTimeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      etagsList :: [Text]
etagsList = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      -- if response xml contains empty etag response fill them with as
      -- many empty Text for the zip4 below to work as intended.
      etags :: [Text]
etags = [Text]
etagsList forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat Text
""
      sizeStr :: [Text]
sizeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
modTimes <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
modTimeStr
  [Int64]
sizes <- forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
sizeStr

  let objects :: [ObjectInfo]
objects =
        forall a b. (a -> b) -> [a] -> [b]
map (forall a b c d e f g.
(a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 Text
-> UTCTime
-> Text
-> Int64
-> HashMap Text Text
-> HashMap Text Text
-> ObjectInfo
ObjectInfo) forall a b. (a -> b) -> a -> b
$
          forall a b c d e f.
[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
zip6 [Text]
keys [UTCTime]
modTimes [Text]
etags [Int64]
sizes (forall a. a -> [a]
repeat forall k v. HashMap k v
H.empty) (forall a. a -> [a]
repeat forall k v. HashMap k v
H.empty)

  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Text -> [ObjectInfo] -> [Text] -> ListObjectsV1Result
ListObjectsV1Result Bool
hasMore Maybe Text
nextMarker [ObjectInfo]
objects [Text]
prefixes

-- | Parse the response XML of a list objects call.
parseListObjectsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListObjectsResult
parseListObjectsResponse :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m ListObjectsResult
parseListObjectsResponse LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] forall a. Eq a => a -> a -> Bool
== (Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextToken :: Maybe Text
nextToken = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextContinuationToken" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      prefixes :: [Text]
prefixes = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      keys :: [Text]
keys = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      modTimeStr :: [Text]
modTimeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      etagsList :: [Text]
etagsList = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      -- if response xml contains empty etag response fill them with as
      -- many empty Text for the zip4 below to work as intended.
      etags :: [Text]
etags = [Text]
etagsList forall a. [a] -> [a] -> [a]
++ forall a. a -> [a]
repeat Text
""
      sizeStr :: [Text]
sizeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Contents" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
modTimes <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
modTimeStr
  [Int64]
sizes <- forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
sizeStr

  let objects :: [ObjectInfo]
objects =
        forall a b. (a -> b) -> [a] -> [b]
map (forall a b c d e f g.
(a -> b -> c -> d -> e -> f -> g) -> (a, b, c, d, e, f) -> g
uncurry6 Text
-> UTCTime
-> Text
-> Int64
-> HashMap Text Text
-> HashMap Text Text
-> ObjectInfo
ObjectInfo) forall a b. (a -> b) -> a -> b
$
          forall a b c d e f.
[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [(a, b, c, d, e, f)]
zip6 [Text]
keys [UTCTime]
modTimes [Text]
etags [Int64]
sizes (forall a. a -> [a]
repeat forall k v. HashMap k v
H.empty) (forall a. a -> [a]
repeat forall k v. HashMap k v
H.empty)

  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Text -> [ObjectInfo] -> [Text] -> ListObjectsResult
ListObjectsResult Bool
hasMore Maybe Text
nextToken [ObjectInfo]
objects [Text]
prefixes

-- | Parse the response XML of a list incomplete multipart upload call.
parseListUploadsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListUploadsResult
parseListUploadsResponse :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m ListUploadsResult
parseListUploadsResponse LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] forall a. Eq a => a -> a -> Bool
== (Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      prefixes :: [Text]
prefixes = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CommonPrefixes" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Prefix" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      nextKey :: Maybe Text
nextKey = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextKeyMarker" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      nextUpload :: Maybe Text
nextUpload = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextUploadIdMarker" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadKeys :: [Text]
uploadKeys = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Key" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadIds :: [Text]
uploadIds = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"UploadId" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      uploadInitTimeStr :: [Text]
uploadInitTimeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Upload" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Initiated" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
uploadInitTimes <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
uploadInitTimeStr

  let uploads :: [(Text, Text, UTCTime)]
uploads = forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Text]
uploadKeys [Text]
uploadIds [UTCTime]
uploadInitTimes

  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool
-> Maybe Text
-> Maybe Text
-> [(Text, Text, UTCTime)]
-> [Text]
-> ListUploadsResult
ListUploadsResult Bool
hasMore Maybe Text
nextKey Maybe Text
nextUpload [(Text, Text, UTCTime)]
uploads [Text]
prefixes

parseListPartsResponse :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m ListPartsResult
parseListPartsResponse :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m ListPartsResult
parseListPartsResponse LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      hasMore :: Bool
hasMore = [Text
"true"] forall a. Eq a => a -> a -> Bool
== (Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"IsTruncated" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
      nextPartNumStr :: Maybe Text
nextPartNumStr = forall a. [a] -> Maybe a
listToMaybe forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"NextPartNumberMarker" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partNumberStr :: [Text]
partNumberStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"PartNumber" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partModTimeStr :: [Text]
partModTimeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"LastModified" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partETags :: [Text]
partETags = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"ETag" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      partSizeStr :: [Text]
partSizeStr = Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"Part" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Axis
s3Elem' Text
"Size" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content

  [UTCTime]
partModTimes <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *). MonadIO m => Text -> m UTCTime
parseS3XMLTime [Text]
partModTimeStr
  [Int64]
partSizes <- forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
partSizeStr
  [PartNumber]
partNumbers <- forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals [Text]
partNumberStr
  [Int]
nextPartNum <- forall (m :: * -> *) a. (MonadIO m, Integral a) => [Text] -> m [a]
parseDecimals forall a b. (a -> b) -> a -> b
$ forall a. Maybe a -> [a]
maybeToList Maybe Text
nextPartNumStr

  let partInfos :: [ObjectPartInfo]
partInfos =
        forall a b. (a -> b) -> [a] -> [b]
map (forall a b c d e. (a -> b -> c -> d -> e) -> (a, b, c, d) -> e
uncurry4 PartNumber -> Text -> Int64 -> UTCTime -> ObjectPartInfo
ObjectPartInfo) forall a b. (a -> b) -> a -> b
$
          forall a b c d. [a] -> [b] -> [c] -> [d] -> [(a, b, c, d)]
zip4 [PartNumber]
partNumbers [Text]
partETags [Int64]
partSizes [UTCTime]
partModTimes

  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Int -> [ObjectPartInfo] -> ListPartsResult
ListPartsResult Bool
hasMore (forall a. [a] -> Maybe a
listToMaybe [Int]
nextPartNum) [ObjectPartInfo]
partInfos

parseNotification :: (MonadReader env m, HasSvcNamespace env, MonadIO m) => LByteString -> m Notification
parseNotification :: forall env (m :: * -> *).
(MonadReader env m, HasSvcNamespace env, MonadIO m) =>
LByteString -> m Notification
parseNotification LByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot LByteString
xmldata
  Text
ns <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks forall env. HasSvcNamespace env => env -> Text
getSvcNamespace
  let s3Elem' :: Text -> Axis
s3Elem' = Text -> Text -> Axis
s3Elem Text
ns
      qcfg :: [Node]
qcfg = forall a b. (a -> b) -> [a] -> [b]
map forall node. Cursor node -> node
node forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"QueueConfiguration"
      tcfg :: [Node]
tcfg = forall a b. (a -> b) -> [a] -> [b]
map forall node. Cursor node -> node
node forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"TopicConfiguration"
      lcfg :: [Node]
lcfg = forall a b. (a -> b) -> [a] -> [b]
map forall node. Cursor node -> node
node forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Axis
s3Elem' Text
"CloudFunctionConfiguration"
  [NotificationConfig]
-> [NotificationConfig] -> [NotificationConfig] -> Notification
Notification
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall {m :: * -> *}.
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"Queue") [Node]
qcfg
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall {m :: * -> *}.
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"Topic") [Node]
tcfg
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall {m :: * -> *}.
Monad m =>
Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
"CloudFunction") [Node]
lcfg
  where
    getFilterRule :: Text -> Cursor -> FilterRule
getFilterRule Text
ns Cursor
c =
      let name :: Text
name = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
c forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Name" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          value :: Text
value = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
c forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Value" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
       in Text -> Text -> FilterRule
FilterRule Text
name Text
value
    parseNode :: Text -> Text -> Node -> m NotificationConfig
parseNode Text
ns Text
arnName Node
nodeData = do
      let c :: Cursor
c = Node -> Cursor
fromNode Node
nodeData
          itemId :: Text
itemId = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
c forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Id" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          arn :: Text
arn = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
c forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
arnName forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
          events :: [Event]
events = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Text -> Maybe Event
textToEvent (Cursor
c forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Event" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content)
          rules :: [FilterRule]
rules =
            Cursor
c
              forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Text -> Text -> Axis
s3Elem Text
ns Text
"Filter"
              forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Text -> Axis
s3Elem Text
ns Text
"S3Key"
              forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Text -> Text -> Axis
s3Elem Text
ns Text
"FilterRule"
              forall node a b.
(Cursor node -> [a]) -> (a -> b) -> Cursor node -> [b]
&| Text -> Cursor -> FilterRule
getFilterRule Text
ns
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        Text -> Text -> [Event] -> Filter -> NotificationConfig
NotificationConfig
          Text
itemId
          Text
arn
          [Event]
events
          (FilterKey -> Filter
Filter forall a b. (a -> b) -> a -> b
$ FilterRules -> FilterKey
FilterKey forall a b. (a -> b) -> a -> b
$ [FilterRule] -> FilterRules
FilterRules [FilterRule]
rules)

parseSelectProgress :: (MonadIO m) => ByteString -> m Progress
parseSelectProgress :: forall (m :: * -> *). MonadIO m => ByteString -> m Progress
parseSelectProgress ByteString
xmldata = do
  Cursor
r <- forall (m :: * -> *). MonadIO m => LByteString -> m Cursor
parseRoot forall a b. (a -> b) -> a -> b
$ ByteString -> LByteString
LB.fromStrict ByteString
xmldata
  let bScanned :: Text
bScanned = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesScanned" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      bProcessed :: Text
bProcessed = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesProcessed" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
      bReturned :: Text
bReturned = [Text] -> Text
T.concat forall a b. (a -> b) -> a -> b
$ Cursor
r forall node a. Cursor node -> (Cursor node -> [a]) -> [a]
$/ Name -> Axis
element Name
"BytesReturned" forall node a.
Axis node -> (Cursor node -> [a]) -> Cursor node -> [a]
&/ Cursor -> [Text]
content
  Int64 -> Int64 -> Int64 -> Progress
Progress
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bScanned
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bProcessed
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall (m :: * -> *) a. (MonadIO m, Integral a) => Text -> m a
parseDecimal Text
bReturned