opentok 0.0.3 → 0.0.4
raw patch · 4 files changed
+148/−19 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ OpenTok: deleteArchive :: OpenTok -> ArchiveId -> IO (Either OTError ArchiveId)
+ OpenTok: listArchives :: OpenTok -> ListArchiveOptions -> IO (Either OTError ArchiveCollection)
+ OpenTok.Archive: data ArchiveCollection
+ OpenTok.Archive: data ListArchiveOptions
+ OpenTok.Archive: delete :: Client -> ArchiveId -> IO (Either OTError ArchiveId)
+ OpenTok.Archive: instance Data.Aeson.Types.FromJSON.FromJSON OpenTok.Archive.ArchiveCollection
+ OpenTok.Archive: instance GHC.Generics.Generic OpenTok.Archive.ArchiveCollection
+ OpenTok.Archive: instance GHC.Show.Show OpenTok.Archive.ArchiveCollection
+ OpenTok.Archive: list :: Client -> ListArchiveOptions -> IO (Either OTError ArchiveCollection)
+ OpenTok.Archive: listArchiveOpts :: ListArchiveOptions
Files
- opentok.cabal +1/−1
- src/OpenTok.hs +16/−0
- src/OpenTok/Archive.hs +99/−7
- src/OpenTok/Client.hs +32/−11
opentok.cabal view
@@ -1,5 +1,5 @@ name: opentok-version: 0.0.3+version: 0.0.4 synopsis: An OpenTok SDK for Haskell description: .
src/OpenTok.hs view
@@ -10,6 +10,8 @@ , tokenOpts , startArchive , stopArchive+ , listArchives+ , deleteArchive ) where @@ -76,3 +78,17 @@ -- stopArchive :: OpenTok -> ArchiveId -> IO (Either OTError Archive) stopArchive ot = OpenTok.Archive.stop (client ot)++-- | Get a list of all archives for a project or a single session+--+-- > listArchives ot listArchiveOpts { _forSessionId = "some_session_id" }+--+listArchives :: OpenTok -> ListArchiveOptions -> IO (Either OTError ArchiveCollection)+listArchives ot = OpenTok.Archive.list (client ot)++-- | Delete an Archive+--+-- > deleteArchive ot "some_archive_id"+--+deleteArchive :: OpenTok -> ArchiveId -> IO (Either OTError ArchiveId)+deleteArchive ot = OpenTok.Archive.delete (client ot)
src/OpenTok/Archive.hs view
@@ -34,8 +34,20 @@ , duration , sessionId )+ , ListArchiveOptions+ ( _forSessionId+ , _count+ , _offset+ )+ , listArchiveOpts+ , ArchiveCollection+ ( count+ , items+ ) , start , stop+ , list+ , delete ) where @@ -150,9 +162,9 @@ @ Archive { id :: 'String',- status :: 'String',+ status :: 'ArchiveStatus', createdAt :: 'Integer',- size :: 'Float',+ size :: 'Int', partnerId :: 'Int', url :: Maybe 'String', resolution :: 'ArchiveResolution',@@ -162,7 +174,7 @@ reason :: 'String', name :: 'String', updatedAt :: 'Integer',- duration :: 'Float',+ duration :: 'Int', sessionId :: 'String' } @@@ -170,9 +182,9 @@ -} data Archive = Archive { id :: String,- status :: String,+ status :: ArchiveStatus, createdAt :: Integer,- size :: Float,+ size :: Int, partnerId :: Int, url :: Maybe String, resolution :: ArchiveResolution,@@ -180,9 +192,9 @@ hasAudio :: Bool, hasVideo :: Bool, reason :: String,- name :: String,+ name :: Maybe String, updatedAt :: Integer,- duration :: Float,+ duration :: Int, sessionId :: String } deriving (Show, Generic) @@ -206,3 +218,83 @@ case response of Right archive -> pure $ Right archive Left e -> pure $ Left $ "An error occurred in attempting to stop an archive: " <> message e+++{-|++Options for listing archives++@+ListArchiveOptions {+ _forSessionId :: `Maybe` `SessionId`,+ _count :: `Int`,+ _offset :: `Int`+}+@++-}+data ListArchiveOptions = ListArchiveOptions {+ _forSessionId :: Maybe SessionId,+ _offset :: Int,+ _count :: Int+}++{-|+Default List Archive options++@+ListArchiveOptions+ { _forSessionId = `Nothing`+ , _offset = 0+ , _count = 50+}+@++-}+listArchiveOpts :: ListArchiveOptions+listArchiveOpts = ListArchiveOptions {+ _forSessionId = Nothing,+ _offset = 0,+ _count = 50+}++{-|++An OpenTok Archive Collection++@+ArchiveCollection {+ count :: 'Int'+ items :: ['Archive']+ id :: 'String'+}+@++-}+data ArchiveCollection = ArchiveCollection {+ count :: Int,+ items :: [Archive]+} deriving (Generic, Show)++instance FromJSON ArchiveCollection++list :: Client -> ListArchiveOptions -> IO (Either OTError ArchiveCollection)+list c opts = do+ let sessionQuery = maybe "" (\sid -> "sessionId=" <> sid <> "&") (_forSessionId opts)+ let pagingQuery = "offset=" <> (show $ _offset opts) <> "&count=" <>( show $ _count opts)+ let query = "?" <> sessionQuery <> pagingQuery+ let path = "/v2/project/" <> _apiKey c <> "/archive" <> query+ response <- get c path :: IO (Either ClientError ArchiveCollection)+ case response of+ Right archive -> pure $ Right archive+ Left e -> pure $ Left $ "An error occurred in retrieving an archive list: " <> message e++delete :: Client -> ArchiveId -> IO (Either OTError ArchiveId)+delete c aid = do+ let path = "/v2/project/" <> _apiKey c <> "/archive/" <> aid+ response <- del c path :: IO (Either ClientError String)+ case response of+ Right _ -> pure $ Right $ "Successfully deleted archive " <> aid+ Left e -> case statusCode e of+ 409 -> pure $ Left "Archive has status other than uploaded, available or deleted."+ _ -> pure $ Left $ message e
src/OpenTok/Client.hs view
@@ -7,9 +7,10 @@ ( Client(Client, _apiKey, _secret) , ClientError(statusCode, message) , Path- , emptyOptions , post , postWithBody+ , get+ , del ) where @@ -18,7 +19,6 @@ import Control.Arrow ( left ) import Control.Lens.Combinators import Control.Lens.Operators--- import Control.Monad.Trans.Either ( eitherT ) import Control.Monad.Time import Control.Monad.Trans.Except import Crypto.JWT@@ -97,13 +97,6 @@ signJWT key claims = runExceptT $ signClaims key (newJWSHeader ((), HS256)) claims -data EmptyOptions = EmptyOptions deriving (Generic)-instance ToJSON EmptyOptions---- | A dummy type used when not passing any options to request-emptyOptions :: Maybe EmptyOptions-emptyOptions = Nothing- createJWT :: Client -> IO (Either ClientError SignedJWT) createJWT client = do claims <- mkClaims (_apiKey client)@@ -124,7 +117,6 @@ buildV1Headers :: SignedJWT -> RequestHeaders buildV1Headers jwt = drop 1 $ buildHeaders jwt - -- | Execute an API request execute :: (FromJSON a) => Request -> IO (Either ClientError a) execute req = do@@ -133,11 +125,21 @@ let body = responseBody response let sc = getResponseStatusCode response case sc of- 200 -> pure $ left (\_ -> decodeError sc) (eitherDecode body)+ 200 -> pure $ left (\m -> (decodeError sc) { message = m }) (eitherDecode body) _ -> pure $ Left $ maybe (decodeError sc) (ClientError sc . _message) (decode body :: Maybe APIError) +-- | Execute an API request to delete a resource+deleteResource :: Request -> IO (Either ClientError String)+deleteResource req = do+ manager <- newManager tlsManagerSettings+ response <- httpLbs req manager+ let sc = getResponseStatusCode response+ case sc of+ 204 -> pure $ Right "Ok"+ _ -> pure $ Left $ ClientError sc "Failed to delete resource"+ buildRequest :: Path -> SignedJWT -> IO Request buildRequest p jwt = do initialRequest <- parseRequest $ "https://api.opentok.com" <> p@@ -164,3 +166,22 @@ request <- buildRequest p jwt execute $ request { requestBody = RequestBodyLBS $ encode b } +-- | Make a GET request with a body+get :: (FromJSON a) => Client -> Path -> IO (Either ClientError a)+get client p = do+ eitherJWT <- createJWT client+ case eitherJWT of+ Left e -> pure $ Left $ e+ Right jwt -> do+ request <- buildRequest p jwt+ execute $ request { method = "GET" }++-- | Make a GET request with a body+del :: Client -> Path -> IO (Either ClientError String)+del client p = do+ eitherJWT <- createJWT client+ case eitherJWT of+ Left e -> pure $ Left $ e+ Right jwt -> do+ request <- buildRequest p jwt+ deleteResource $ request { method = "DELETE" }