deepl 0.1.0.0 → 0.1.0.1
raw patch · 6 files changed
+116/−116 lines, 6 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Config: Config :: Token -> FilePath -> FilePath -> Text -> Config
- Config: [input] :: Config -> FilePath
- Config: [lang] :: Config -> Text
- Config: [output] :: Config -> FilePath
- Config: [token] :: Config -> Token
- Config: data Config
- Config: instance Data.Data.Data Config.Config
- Config: instance GHC.Show.Show Config.Config
- Config: type Token = Text
- DeepL: breaker :: Monad m => Stream (Of (ByteString, Int)) m r -> Stream (Stream (Of (ByteString, Int)) m) m r
- DeepL: deepL :: Config -> Text -> IO (Maybe Text)
- DeepL: defaultDeepL :: Config -> Text -> IO Text
- DeepL: limit :: Int
- DeepL: step :: Monad m => Stream (Of (ByteString, Int)) m r -> Stream (Of (ByteString, Int)) m (Stream (Of (ByteString, Int)) m r)
- DeepL: translateFile :: Config -> IO ()
+ DeepL.Config: Config :: Token -> FilePath -> FilePath -> Text -> Config
+ DeepL.Config: [input] :: Config -> FilePath
+ DeepL.Config: [lang] :: Config -> Text
+ DeepL.Config: [output] :: Config -> FilePath
+ DeepL.Config: [token] :: Config -> Token
+ DeepL.Config: data Config
+ DeepL.Config: instance Data.Data.Data DeepL.Config.Config
+ DeepL.Config: instance GHC.Show.Show DeepL.Config.Config
+ DeepL.Config: type Token = Text
+ DeepL.Translate: breaker :: Monad m => Stream (Of (ByteString, Int)) m r -> Stream (Stream (Of (ByteString, Int)) m) m r
+ DeepL.Translate: deepL :: Config -> Text -> IO (Maybe Text)
+ DeepL.Translate: defaultDeepL :: Config -> Text -> IO Text
+ DeepL.Translate: limit :: Int
+ DeepL.Translate: step :: Monad m => Stream (Of (ByteString, Int)) m r -> Stream (Of (ByteString, Int)) m (Stream (Of (ByteString, Int)) m r)
+ DeepL.Translate: translateFile :: Config -> IO ()
Files
- app/Main.hs +2/−2
- deepl.cabal +3/−3
- src/Config.hs +0/−16
- src/DeepL.hs +0/−95
- src/DeepL/Config.hs +16/−0
- src/DeepL/Translate.hs +95/−0
app/Main.hs view
@@ -3,8 +3,8 @@ module Main where -import Config-import DeepL (translateFile)+import DeepL.Config+import DeepL.Translate (translateFile) import Protolude import System.Console.CmdArgs ( Data
deepl.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: deepl-version: 0.1.0.0+version: 0.1.0.1 synopsis: Call DeepL to translate you files description: Please see the README on GitHub at <https://gitlab.com/global-access-public/deepl/-/blob/master/README.md> category: Web, Language@@ -21,8 +21,8 @@ library exposed-modules:- Config- DeepL+ DeepL.Config+ DeepL.Translate other-modules: Paths_deepl hs-source-dirs:
− src/Config.hs
@@ -1,16 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}--module Config where--import Data.Data (Data)-import Protolude (Text, Typeable)--type Token = Text--data Config = Config- { token :: Token- , input :: FilePath- , output :: FilePath- , lang :: Text- }- deriving (Show, Data, Typeable)
− src/DeepL.hs
@@ -1,95 +0,0 @@-{-# LANGUAGE BlockArguments #-}-{-# LANGUAGE NumericUnderscores #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE NoImplicitPrelude #-}-{-# OPTIONS_GHC -fno-cse #-}--module DeepL where--import Config (Config (..))-import qualified Control.Foldl as L-import Control.Lens (lmap, (^?), _head)-import Control.Monad.Trans.Resource (register, runResourceT)-import Data.Aeson.Lens- ( AsPrimitive (_String)- , AsValue (_Array)- , key- )-import Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as B-import Network.Wreq (FormParam ((:=)), post, responseBody)-import Protolude-import Streaming (Of (..), Stream, effect, inspect, wrap)-import qualified Streaming.ByteString.Char8 as SB-import qualified Streaming.Prelude as S-import System.IO (hClose, openBinaryFile)--defaultDeepL :: Config -> Text -> IO Text-defaultDeepL config x = fromMaybe x <$> deepL config x--deepL :: Config -> Text -> IO (Maybe Text)-deepL Config {..} x = do- r <-- post- "https://api.deepl.com/v2/translate"- [ "auth_key" := token- , "text" := x- , "target_lang" := lang- ]- pure $- r- ^? responseBody- . key "translations"- . _Array- . _head- . key "text"- . _String--limit :: Int-limit = 30_000--translateFile :: Config -> IO ()-translateFile config@Config {..} = runResourceT $ do- handleIn <- case input of- "" -> pure stdin- filePath -> do- h <- liftIO $ openBinaryFile filePath ReadMode- register $ hClose h- pure h- handleOut <- case output of- "" -> pure stdout- filePath -> do- h <- liftIO $ openBinaryFile filePath WriteMode- register $ hClose h- pure h- SB.toHandle handleOut- . SB.unlines- . S.maps (\(x :> r) -> r <$ SB.fromStrict (B.init x))- . S.mapped do- \s -> do- rs :> rest <- S.toList s- z <- liftIO $ defaultDeepL config $ decodeUtf8 . B.unlines . fmap fst $ rs- pure $ encodeUtf8 z :> rest- . breaker- . S.map- do \v -> (v, B.length v)- . S.mapped SB.toStrict- . SB.lines- $ SB.fromHandle handleIn--breaker- :: Monad m- => Stream (Of (ByteString, Int)) m r- -> Stream (Stream (Of (ByteString, Int)) m) m r-breaker s = effect $ do- x <- inspect s- pure $ case x of- Left r -> pure r- Right q -> wrap $ fmap breaker $ step $ wrap q--step- :: Monad m- => Stream (Of (ByteString, Int)) m r- -> Stream (Of (ByteString, Int)) m (Stream (Of (ByteString, Int)) m r)-step = L.purely S.breakWhen (lmap snd L.sum) (> limit)
+ src/DeepL/Config.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE DeriveDataTypeable #-}++module DeepL.Config where++import Data.Data (Data)+import Protolude (Text, Typeable)++type Token = Text++data Config = Config+ { token :: Token+ , input :: FilePath+ , output :: FilePath+ , lang :: Text+ }+ deriving (Show, Data, Typeable)
+ src/DeepL/Translate.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE BlockArguments #-}+{-# LANGUAGE NumericUnderscores #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# OPTIONS_GHC -fno-cse #-}++module DeepL.Translate where++import DeepL.Config (Config (..))+import qualified Control.Foldl as L+import Control.Lens (lmap, (^?), _head)+import Control.Monad.Trans.Resource (register, runResourceT)+import Data.Aeson.Lens+ ( AsPrimitive (_String)+ , AsValue (_Array)+ , key+ )+import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as B+import Network.Wreq (FormParam ((:=)), post, responseBody)+import Protolude+import Streaming (Of (..), Stream, effect, inspect, wrap)+import qualified Streaming.ByteString.Char8 as SB+import qualified Streaming.Prelude as S+import System.IO (hClose, openBinaryFile)++defaultDeepL :: Config -> Text -> IO Text+defaultDeepL config x = fromMaybe x <$> deepL config x++deepL :: Config -> Text -> IO (Maybe Text)+deepL Config {..} x = do+ r <-+ post+ "https://api.deepl.com/v2/translate"+ [ "auth_key" := token+ , "text" := x+ , "target_lang" := lang+ ]+ pure $+ r+ ^? responseBody+ . key "translations"+ . _Array+ . _head+ . key "text"+ . _String++limit :: Int+limit = 30_000++translateFile :: Config -> IO ()+translateFile config@Config {..} = runResourceT $ do+ handleIn <- case input of+ "" -> pure stdin+ filePath -> do+ h <- liftIO $ openBinaryFile filePath ReadMode+ register $ hClose h+ pure h+ handleOut <- case output of+ "" -> pure stdout+ filePath -> do+ h <- liftIO $ openBinaryFile filePath WriteMode+ register $ hClose h+ pure h+ SB.toHandle handleOut+ . SB.unlines+ . S.maps (\(x :> r) -> r <$ SB.fromStrict (B.init x))+ . S.mapped do+ \s -> do+ rs :> rest <- S.toList s+ z <- liftIO $ defaultDeepL config $ decodeUtf8 . B.unlines . fmap fst $ rs+ pure $ encodeUtf8 z :> rest+ . breaker+ . S.map+ do \v -> (v, B.length v)+ . S.mapped SB.toStrict+ . SB.lines+ $ SB.fromHandle handleIn++breaker+ :: Monad m+ => Stream (Of (ByteString, Int)) m r+ -> Stream (Stream (Of (ByteString, Int)) m) m r+breaker s = effect $ do+ x <- inspect s+ pure $ case x of+ Left r -> pure r+ Right q -> wrap $ fmap breaker $ step $ wrap q++step+ :: Monad m+ => Stream (Of (ByteString, Int)) m r+ -> Stream (Of (ByteString, Int)) m (Stream (Of (ByteString, Int)) m r)+step = L.purely S.breakWhen (lmap snd L.sum) (> limit)