voicebase 0.1.1.2 → 0.1.1.3
raw patch · 6 files changed
+275/−183 lines, 6 filesdep +filepathdep +optparse-applicativedep −optionsnew-uploader
Dependencies added: filepath, optparse-applicative
Dependencies removed: options
Files
- app/Main.hs +49/−26
- src/Json/ProgressTypes.hs +22/−21
- src/Json/SubmitMediaTypes.hs +22/−21
- src/Json/TranscriptTypes.hs +53/−52
- src/VoicebaseClient.hs +110/−47
- voicebase.cabal +19/−16
app/Main.hs view
@@ -1,35 +1,58 @@ {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} module Main where -import Network.Mime(defaultMimeLookup)-import VoicebaseClient-import Options-import qualified Data.ByteString.Lazy as LBS+import Data.Aeson (encode)+import qualified Data.ByteString.Lazy as LBS+import qualified Data.ByteString.Lazy.Char8 as C8LBS+import Data.Monoid ((<>))+import qualified Data.Text as Text+import Network.Mime (defaultMimeLookup)+import Options.Applicative+import System.FilePath (splitFileName)+import VoicebaseClient -data MainOptions = MainOptions- { - token :: Maybe BearerToken,- targetFile :: Maybe FilePath+data Options = Options+ {+ bearToken :: BearerToken,+ file :: FilePath } -instance Options MainOptions where- defineOptions = pure MainOptions- <*> simpleOption "bearer-token" Nothing- "The bearer token obtained from voicebase"- <*> simpleOption "file" Nothing- "The file to be posted"++sample :: Parser Options+sample = Options+ <$> strOption+ ( long "bearer-token"+ <> metavar "TOKEN"+ <> help "The bearer token obtained from voicebase" )+ <*> strOption+ ( long "file"+ <> metavar "PATH"+ <> help "The file to be posted" )+ main :: IO ()-main = runCommand $ \opts args -> do- case token opts of- Just bearToken -> case targetFile opts of - Just file -> withBearAndFile bearToken file- Nothing -> putStrLn "file required"- Nothing -> putStrLn "bearer token required"+main = execParser opts >>= withBearAndFile+ where+ opts = info (sample <**> helper)+ ( fullDesc+ <> progDesc "Transcribe a file with voicebase"+ <> header "Voicebase transcriber!" ) -withBearAndFile :: BearerToken -> FilePath -> IO() -withBearAndFile bearToken file = do - -- result <- transcribeFile bearToken file - bytes <- LBS.readFile file- result <- transcribeBytes bearToken (LazyByteFile bytes (defaultMimeLookup "f.mp3"))- putStrLn . show $ result+defaultConfiguration = Configuration {+ channels = Just Channels {+ left = Speaker "Agent"+ , right = Speaker "Caller"+ },+ language = EnglishAus+}++withBearAndFile :: Options -> IO()+withBearAndFile Options{..} = do+ bytes <- LBS.readFile file+ result <- transcribeBytes defaultConfiguration bearToken (LazyByteFile bytes filename)+ case result of+ Left error -> print error+ Right r -> C8LBS.putStrLn $ encode $ r+ where+ filename = defaultMimeLookup . Text.pack . snd . splitFileName $ file
src/Json/ProgressTypes.hs view
@@ -1,33 +1,34 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE DeriveGeneric #-} -- | Auto generated module by json-autotype module Json.ProgressTypes where -import System.Exit (exitFailure, exitSuccess)-import System.IO (stderr, hPutStrLn)-import qualified Data.ByteString.Lazy.Char8 as BSL-import Data.ByteString.Lazy-import System.Environment (getArgs)-import Control.Monad (forM_, mzero, join) import Control.Applicative+import Control.Monad (forM_, join, mzero)+import Data.Aeson (FromJSON (..), ToJSON (..),+ Value (..), eitherDecode,+ object, pairs, (.:), (.:?),+ (.=)) import Data.Aeson.AutoType.Alternative-import Data.Aeson(eitherDecode, Value(..), FromJSON(..), ToJSON(..),- pairs,- (.:), (.:?), (.=), object)+import Data.ByteString.Lazy+import qualified Data.ByteString.Lazy.Char8 as BSL import Data.Monoid-import Data.Text (Text)+import Data.Text (Text) import qualified GHC.Generics+import System.Environment (getArgs)+import System.Exit (exitFailure, exitSuccess)+import System.IO (hPutStrLn, stderr) -- | Workaround for https://github.com/bos/aeson/issues/287. o .:?? val = fmap join (o .:? val) -data Tasks = Tasks { +data Tasks = Tasks { } deriving (Show,Eq,GHC.Generics.Generic) @@ -42,10 +43,10 @@ -data Progress = Progress { +data Progress = Progress { progressStatus :: Text,- progressJobId :: Text,- progressTasks :: Tasks+ progressJobId :: Text,+ progressTasks :: Tasks } deriving (Show,Eq,GHC.Generics.Generic) @@ -59,10 +60,10 @@ toEncoding (Progress {..}) = pairs ("status" .= progressStatus<>"jobId" .= progressJobId<>"tasks" .= progressTasks) -data TopLevel = TopLevel { - topLevelStatus :: Text,+data TopLevel = TopLevel {+ topLevelStatus :: Text, topLevelProgress :: Progress,- topLevelMediaId :: Text+ topLevelMediaId :: Text } deriving (Show,Eq,GHC.Generics.Generic)
src/Json/SubmitMediaTypes.hs view
@@ -1,33 +1,34 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE DeriveGeneric #-} -- | Auto generated module by json-autotype module Json.SubmitMediaTypes where -import System.Exit (exitFailure, exitSuccess)-import System.IO (stderr, hPutStrLn)-import qualified Data.ByteString.Lazy.Char8 as BSL-import Data.ByteString.Lazy-import System.Environment (getArgs)-import Control.Monad (forM_, mzero, join) import Control.Applicative+import Control.Monad (forM_, join, mzero)+import Data.Aeson (FromJSON (..), ToJSON (..),+ Value (..), eitherDecode,+ object, pairs, (.:), (.:?),+ (.=)) import Data.Aeson.AutoType.Alternative-import Data.Aeson(eitherDecode, Value(..), FromJSON(..), ToJSON(..),- pairs,- (.:), (.:?), (.=), object)+import Data.ByteString.Lazy+import qualified Data.ByteString.Lazy.Char8 as BSL import Data.Monoid-import Data.Text (Text)+import Data.Text (Text) import qualified GHC.Generics+import System.Environment (getArgs)+import System.Exit (exitFailure, exitSuccess)+import System.IO (hPutStrLn, stderr) -- | Workaround for https://github.com/bos/aeson/issues/287. o .:?? val = fmap join (o .:? val) -data Self = Self { +data Self = Self { selfHref :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -42,7 +43,7 @@ toEncoding (Self {..}) = pairs ("href" .= selfHref) -data Links = Links { +data Links = Links { linksSelf :: Self } deriving (Show,Eq,GHC.Generics.Generic) @@ -57,7 +58,7 @@ toEncoding (Links {..}) = pairs ("self" .= linksSelf) -data Metadata = Metadata { +data Metadata = Metadata { } deriving (Show,Eq,GHC.Generics.Generic) @@ -72,10 +73,10 @@ -data TopLevel = TopLevel { - topLevelStatus :: Text,- topLevelMediaId :: Text,- topLevelLinks :: Links,+data TopLevel = TopLevel {+ topLevelStatus :: Text,+ topLevelMediaId :: Text,+ topLevelLinks :: Links, topLevelMetadata :: Metadata } deriving (Show,Eq,GHC.Generics.Generic)
src/Json/TranscriptTypes.hs view
@@ -1,33 +1,34 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE DeriveGeneric #-} -- | Auto generated module by json-autotype module Json.TranscriptTypes where -import System.Exit (exitFailure, exitSuccess)-import System.IO (stderr, hPutStrLn)-import qualified Data.ByteString.Lazy.Char8 as BSL-import Data.ByteString.Lazy-import System.Environment (getArgs)-import Control.Monad (forM_, mzero, join) import Control.Applicative+import Control.Monad (forM_, join, mzero)+import Data.Aeson (FromJSON (..), ToJSON (..),+ Value (..), eitherDecode,+ object, pairs, (.:), (.:?),+ (.=)) import Data.Aeson.AutoType.Alternative-import Data.Aeson(eitherDecode, Value(..), FromJSON(..), ToJSON(..),- pairs,- (.:), (.:?), (.=), object)+import Data.ByteString.Lazy+import qualified Data.ByteString.Lazy.Char8 as BSL import Data.Monoid-import Data.Text (Text)+import Data.Text (Text) import qualified GHC.Generics+import System.Environment (getArgs)+import System.Exit (exitFailure, exitSuccess)+import System.IO (hPutStrLn, stderr) -- | Workaround for https://github.com/bos/aeson/issues/287. o .:?? val = fmap join (o .:? val) -data LatestTopics = LatestTopics { - latestTopicsTopics :: [(Maybe Value)],+data LatestTopics = LatestTopics {+ latestTopicsTopics :: [(Maybe Value)], latestTopicsRevision :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -37,7 +38,7 @@ parseJSON _ = mzero -data Topics = Topics { +data Topics = Topics { topicsLatestTopics :: LatestTopics } deriving (Show,Eq,GHC.Generics.Generic) @@ -47,7 +48,7 @@ parseJSON _ = mzero -data Tasks = Tasks { +data Tasks = Tasks { } deriving (Show,Eq,GHC.Generics.Generic) @@ -55,10 +56,10 @@ parseJSON (Object v) = return Tasks parseJSON _ = mzero -data Progress = Progress { +data Progress = Progress { progressStatus :: Text,- progressJobId :: Text,- progressTasks :: Tasks+ progressJobId :: Text,+ progressTasks :: Tasks } deriving (Show,Eq,GHC.Generics.Generic) @@ -67,7 +68,7 @@ parseJSON _ = mzero -data Job = Job { +data Job = Job { jobProgress :: Progress } deriving (Show,Eq,GHC.Generics.Generic) @@ -77,7 +78,7 @@ parseJSON _ = mzero -data T = T { +data T = T { tUnknown :: [Text] } deriving (Show,Eq,GHC.Generics.Generic) @@ -87,10 +88,10 @@ parseJSON _ = mzero -data WordsKeyElt = WordsKeyElt { +data WordsKeyElt = WordsKeyElt { wordsKeyEltRelevance :: Text,- wordsKeyEltT :: T,- wordsKeyEltName :: Text+ wordsKeyEltT :: T,+ wordsKeyEltName :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -99,8 +100,8 @@ parseJSON _ = mzero -data LatestKeywords = LatestKeywords { - latestKeywordsGroups :: [(Maybe Value)],+data LatestKeywords = LatestKeywords {+ latestKeywordsGroups :: [(Maybe Value)], latestKeywordsWordsKey :: [WordsKeyElt], latestKeywordsRevision :: Text } deriving (Show,Eq,GHC.Generics.Generic)@@ -111,7 +112,7 @@ parseJSON _ = mzero -data Keywords = Keywords { +data Keywords = Keywords { keywordsLatestKeywords :: LatestKeywords } deriving (Show,Eq,GHC.Generics.Generic) @@ -121,8 +122,8 @@ parseJSON _ = mzero -data Length = Length { - lengthDescriptive :: Text,+data Length = Length {+ lengthDescriptive :: Text, lengthMilliseconds :: Double } deriving (Show,Eq,GHC.Generics.Generic) @@ -132,8 +133,8 @@ parseJSON _ = mzero -data Metadata = Metadata { - metadataLength :: Length,+data Metadata = Metadata {+ metadataLength :: Length, metadataContentType :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -143,7 +144,7 @@ parseJSON _ = mzero -data WordsTranscriptsElt = WordsTranscriptsElt { +data WordsTranscriptsElt = WordsTranscriptsElt { wordsTranscriptsEltW :: Text, wordsTranscriptsEltM :: (Maybe (Text:|:[(Maybe Value)])), wordsTranscriptsEltP :: Double,@@ -158,12 +159,12 @@ parseJSON _ = mzero -data LatestTranscripts = LatestTranscripts { - latestTranscriptsEngine :: Text,- latestTranscriptsConfidence :: Double,- latestTranscriptsName :: Text,+data LatestTranscripts = LatestTranscripts {+ latestTranscriptsEngine :: Text,+ latestTranscriptsConfidence :: Double,+ latestTranscriptsName :: Text, latestTranscriptsWordsTranscripts :: [WordsTranscriptsElt],- latestTranscriptsRevision :: Text+ latestTranscriptsRevision :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -172,7 +173,7 @@ parseJSON _ = mzero -data Transcripts = Transcripts { +data Transcripts = Transcripts { transcriptsLatestTranscripts :: LatestTranscripts } deriving (Show,Eq,GHC.Generics.Generic) @@ -182,15 +183,15 @@ parseJSON _ = mzero -data Media = Media { - mediaStatus :: Text,- mediaTopics :: Topics,- mediaMediaId :: Text,- mediaDateCreated :: Text,- mediaJob :: Job,- mediaKeywords :: Keywords,- mediaMetadata :: Metadata,- mediaTranscripts :: Transcripts,+data Media = Media {+ mediaStatus :: Text,+ mediaTopics :: Topics,+ mediaMediaId :: Text,+ mediaDateCreated :: Text,+ mediaJob :: Job,+ mediaKeywords :: Keywords,+ mediaMetadata :: Metadata,+ mediaTranscripts :: Transcripts, mediaDateFinished :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -200,7 +201,7 @@ parseJSON _ = mzero -data Self = Self { +data Self = Self { selfHref :: Text } deriving (Show,Eq,GHC.Generics.Generic) @@ -210,7 +211,7 @@ parseJSON _ = mzero -data Links = Links { +data Links = Links { linksSelf :: Self } deriving (Show,Eq,GHC.Generics.Generic) @@ -220,7 +221,7 @@ parseJSON _ = mzero -data Transcript = Transcript { +data Transcript = Transcript { topLevelMedia :: Media, topLevelLinks :: Links } deriving (Show,Eq,GHC.Generics.Generic)
src/VoicebaseClient.hs view
@@ -1,49 +1,107 @@+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-} -- | Main module for doing the requests to the voicebase api: http://voicebase.readthedocs.io/en/v2-beta/ module VoicebaseClient (- transcribe, - transcribeFile, - transcribeBytes, - transcribeParse, - BearerToken, + transcribe,+ transcribeFile,+ transcribeBytes,+ transcribeParse,+ BearerToken, Error(..),- LazyByteFile(..)+ LazyByteFile(..),+ Configuration(..),+ Channels(..),+ Speaker(..),+ Language(..) ) where -import Control.Lens-import Control.Monad-import Control.Applicative+import Control.Applicative+import Control.Lens hiding ((.=))+import Control.Monad -import Data.Maybe-import Data.Monoid-import Data.Text.Encoding as TE-import Data.Bifunctor+import Data.Bifunctor+import Data.Maybe+import Data.Monoid+import Data.Text.Encoding as TE -import qualified Data.ByteString.Char8 as BS-import qualified Data.ByteString.Lazy.Char8 as C8LBS-import qualified Data.ByteString.Lazy as LBS-import Data.Text (Text, unpack)+import qualified Data.ByteString.Char8 as BS+import qualified Data.ByteString.Lazy as LBS+import qualified Data.ByteString.Lazy.Char8 as C8LBS+import Data.Text (Text, unpack) -import Data.Aeson(Value, eitherDecode, FromJSON(parseJSON))-import Data.Aeson.Types(parseEither)-import Network.Wreq-import Network.Mime(MimeType)-import qualified Network.Wreq.Session as Sess-import Network.HTTP.Client.OpenSSL-import Network.HTTP.Client (defaultManagerSettings, managerResponseTimeout, responseTimeoutMicro)-import OpenSSL.Session (context)+import Data.Aeson (FromJSON (parseJSON), ToJSON (..),+ Value, eitherDecode, encode,+ object, (.=))+import Data.Aeson.Types (parseEither)+import Network.HTTP.Client (defaultManagerSettings,+ managerResponseTimeout,+ responseTimeoutMicro)+import Network.HTTP.Client.OpenSSL+import Network.Mime (MimeType)+import Network.Wreq+import qualified Network.Wreq.Session as Sess+import OpenSSL.Session (context) -import qualified Json.SubmitMediaTypes as Submit-import qualified Json.ProgressTypes as Progress-import qualified Json.TranscriptTypes as Transcript+import GHC.Generics+import qualified Json.ProgressTypes as Progress+import qualified Json.SubmitMediaTypes as Submit+import qualified Json.TranscriptTypes as Transcript -import System.IO(fixIO)+import System.IO (fixIO) -- | get your bearer token at http://voicebase.readthedocs.io/en/v2-beta/how-to-guides/hello-world.html#token type BearerToken = String +data Configuration = Configuration {+ channels :: Maybe Channels+ , language :: Language+} deriving Generic++data Channels = Channels {+ left :: Speaker+ , right :: Speaker+} deriving Generic++data Speaker = Speaker {+ speaker :: Text+} deriving Generic++instance ToJSON Channels+instance ToJSON Speaker++instance ToJSON Configuration where+ toJSON Configuration{..} = let+ ingest c = [+ "ingest" .= object [+ "channels" .= c+ ]+ ]+ in object [+ "configuration" .= (object . concat) [+ ["language" .= language]+ , maybe [] ingest channels+ ]+ ]++-- https://voicebase.readthedocs.io/en/v2-beta/how-to-guides/languages.html+data Language =+ Dutch | EnglishUS | EnglishUK | EnglishAus | French | German | Italian | Portuguese | SpanishLatinAmerican | SpanishSpain++instance ToJSON Language where+ toJSON Dutch = "nl-NL"+ toJSON EnglishUS = "en-US"+ toJSON EnglishUK = "en-UK"+ toJSON EnglishAus = "en-AU"+ toJSON French = "fr-FR"+ toJSON German = "de-DE"+ toJSON Italian = "it-IT"+ toJSON Portuguese = "pt-BR"+ toJSON SpanishLatinAmerican = "es-LA"+ toJSON SpanishSpain = "es-ES"+ data Error = UnkownResponse | ParseError String deriving(Show) @@ -56,37 +114,42 @@ makeOpts token = withAuthorization token defaults withAuthorization :: BearerToken -> Options -> Options-withAuthorization token options = options & manager .~ Left (opensslManagerSettings context) +withAuthorization token options = options & manager .~ Left (opensslManagerSettings context) & manager .~ Left (defaultManagerSettings { managerResponseTimeout = timeout} ) & header "Authorization" .~ [(BS.pack ("Bearer " ++ token))] -- | transcribes the audio file and puts it into a Transcript-transcribeParse :: BearerToken -> FilePath -> IO(Either Error Transcript.Transcript)-transcribeParse token filepath = fmap (join . second (first ParseError . parseEither parseJSON)) (transcribeFile token filepath)+transcribeParse :: Configuration -> BearerToken -> FilePath -> IO(Either Error Transcript.Transcript)+transcribeParse config token filepath = fmap (join . second (first ParseError . parseEither parseJSON)) (transcribeFile config token filepath) inputName = "media"--- | Given a bearer token, and a filepath to an audio file, this function will +-- | Given a bearer token, and a filepath to an audio file, this function will -- | eventually return a transcript or times out after 10 seconds -- | Throws HttpExceptionRequest, IOException (file not found)-transcribeFile :: BearerToken -> FilePath -> IO(Either Error Value)-transcribeFile bearerToken filePath = transcribe bearerToken defaults (- [partFileSource inputName filePath]- )+transcribeFile :: Configuration -> BearerToken -> FilePath -> IO(Either Error Value)+transcribeFile config bearerToken filePath = transcribe bearerToken defaults+ [+ partFileSource inputName filePath,+ partLBS "configuration" $ encode $ config+ ] -- | In case of a bytestring, we also need to mimetype to decode the send string data LazyByteFile = LazyByteFile {- content :: LBS.ByteString,+ content :: LBS.ByteString, mimetype :: MimeType -- to get this Jappie used defaultMimeLookup "f.mp3" } -- | Transcribe a bytestring -- | Throws HttpExceptionRequest-transcribeBytes :: BearerToken -> LazyByteFile -> IO(Either Error Value)-transcribeBytes bearerToken (LazyByteFile content mimetype) = - transcribe bearerToken defaults (- [partLBS inputName content & partContentType .~ Just mimetype & partFileName .~ Just ""]- )+transcribeBytes :: Configuration -> BearerToken -> LazyByteFile -> IO(Either Error Value)+transcribeBytes config bearerToken (LazyByteFile content mimetype) =+ transcribe bearerToken defaults+ [partLBS inputName content &+ partContentType ?~ mimetype &+ partFileName ?~ "",+ partLBS "configuration" $ encode $ config+ ] --- | Generic transcribe, agnostic of options, will add ssl, +-- | Generic transcribe, agnostic of options, will add ssl, -- | the bearer token and a timeout to the options. -- | Throws HttpExceptionRequest transcribe :: BearerToken -> Options -> [Part] -> IO(Either Error Value)@@ -95,11 +158,11 @@ response <- Sess.postWith (withAuthorization token options) session url parts case Submit.parse (response ^. responseBody) of Left error -> return $ Left $ ParseError error- Right parsed -> do + Right parsed -> do -- wait for the service to complete waitResult <- pollStatus token session (Submit.topLevelMediaId parsed) case waitResult of- Right _ -> first ParseError . eitherDecode <$> (requestTranscript token session (Submit.topLevelMediaId parsed)) + Right _ -> first ParseError . eitherDecode <$> (requestTranscript token session (Submit.topLevelMediaId parsed)) Left error -> return $ Left $ error @@ -109,7 +172,7 @@ pollStatus' :: BearerToken -> Sess.Session -> Text -> Text -> IO (Either Error ()) pollStatus' token session mediaId "pending" = do response <- Sess.getWith (makeOpts token) session (url <> "/" <> (unpack mediaId) <> "/progress")- case Progress.parse (response ^. responseBody) of + case Progress.parse (response ^. responseBody) of Left error -> return $ Left $ ParseError error Right parsed -> pollStatus' token session mediaId ((Progress.progressStatus . Progress.topLevelProgress) $ parsed) pollStatus' token session mediaId "started" = pollStatus' token session mediaId "pending"
voicebase.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 0bf46ba02ab7110dda3260615d5a5c1276107dfee40f80886e1617603765075b+-- hash: 8847ee36a75d0d55c1a5b2f816d29aa06f25672f2b8b9e257df8fc88a5eaf6a1 name: voicebase-version: 0.1.1.2+version: 0.1.1.3 synopsis: Upload audio files to voicebase to get a transcription description: voicebase bindings for <http://voicebase.readthedocs.io/en/v2-beta/> category: API@@ -22,6 +22,13 @@ README.md library+ exposed-modules:+ Json.ProgressTypes+ Json.SubmitMediaTypes+ Json.TranscriptTypes+ VoicebaseClient+ other-modules:+ Paths_voicebase hs-source-dirs: src build-depends:@@ -36,39 +43,35 @@ , mime-types , text , wreq- exposed-modules:- Json.ProgressTypes- Json.SubmitMediaTypes- Json.TranscriptTypes- VoicebaseClient- other-modules:- Paths_voicebase default-language: Haskell2010 executable voicebase main-is: Main.hs+ other-modules:+ Paths_voicebase hs-source-dirs: app ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends:- base >=4.7 && <5+ aeson+ , base >=4.7 && <5 , bytestring+ , filepath , mime-types- , options+ , optparse-applicative , voicebase- other-modules:- Paths_voicebase default-language: Haskell2010 test-suite voicebase-test type: exitcode-stdio-1.0 main-is: Spec.hs+ other-modules:+ Paths_voicebase hs-source-dirs: test ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends:- base >=4.7 && <5+ aeson+ , base >=4.7 && <5 , voicebase- other-modules:- Paths_voicebase default-language: Haskell2010