aboutsummaryrefslogtreecommitdiffhomepage
path: root/scaffolder/src/Text/Edifact/Fetcher/Commons.hs
diff options
context:
space:
mode:
authorFrédéric Menou <frederic.menou@fretlink.com>2016-12-08 10:19:15 +0200
committerIsmaël Bouya <ismael.bouya@fretlink.com>2022-05-17 18:01:51 +0200
commita9d77a20008efe82862cc1adbfa7a6d4f09f8ff7 (patch)
treeadf3186fdccaeef19151026cdfbd38a530cf9ecb /scaffolder/src/Text/Edifact/Fetcher/Commons.hs
downloadedi-parser-master.tar.gz
edi-parser-master.tar.zst
edi-parser-master.zip
Release code as open sourceHEADmaster
Diffstat (limited to 'scaffolder/src/Text/Edifact/Fetcher/Commons.hs')
-rw-r--r--scaffolder/src/Text/Edifact/Fetcher/Commons.hs87
1 files changed, 87 insertions, 0 deletions
diff --git a/scaffolder/src/Text/Edifact/Fetcher/Commons.hs b/scaffolder/src/Text/Edifact/Fetcher/Commons.hs
new file mode 100644
index 0000000..1a6a058
--- /dev/null
+++ b/scaffolder/src/Text/Edifact/Fetcher/Commons.hs
@@ -0,0 +1,87 @@
1{-# LANGUAGE OverloadedStrings #-}
2
3module Text.Edifact.Fetcher.Commons where
4
5import Text.Edifact.Fetcher.Configuration
6import Text.Edifact.Scaffolder.Commons
7
8import Control.Monad ((>=>))
9import Control.Monad.Error.Class (MonadError, catchError)
10import Control.Monad.IO.Class (MonadIO)
11import Control.Monad.Reader (ReaderT, runReaderT)
12import Control.Monad.Trans.Class (lift)
13import Data.ByteString (ByteString)
14import Data.Char (toLower)
15import Data.Text as T (unpack, pack)
16import Data.Text.IO as TIO (readFile, writeFile)
17import Formatting
18import System.Directory (doesFileExist)
19import Text.Pandoc as Pandoc hiding (Format,
20 getOutputFile)
21import Text.Parsec (Parsec, runParser)
22
23type Fetcher = ReaderT FetchingEnv PandocIO
24
25runFetcher :: Fetcher () -> FetchingEnv -> IO ()
26runFetcher f = Pandoc.runIOorExplode . runReaderT f
27
28getOutputFile :: Format String (a -> String) -> FilePath -> a -> Fetcher FilePath
29getOutputFile f d c = do
30 home <- getSpecificationHome
31 pure (formatToString (string % "/" % string % "/" % f) home d c)
32
33getUrl :: Format String (a -> String) -> a -> Fetcher String
34getUrl f c = do
35 rev <- getTargetRevision
36 pure (formatToString ("https://service.unece.org/trade/untdid/" % fRevisionLower % f) rev c)
37
38getSpecificationHome :: Fetcher FilePath
39getSpecificationHome = do
40 home <- getHome
41 rev <- getTargetRevision
42 pure (home </> formatToString fRevision rev)
43
44htmlToFile :: String -> (ByteString -> Text) -> FilePath -> Fetcher ()
45htmlToFile url decoder outputFile = () <$ tryCacheOrHtml decoder url outputFile
46
47htmlToFileWithParser :: (Monoid a, Monoid u) => String -> (ByteString -> Text) -> FilePath -> Parsec String u a -> Fetcher a
48htmlToFileWithParser url decoder outputFile parser = do
49 specification <- tryCacheOrHtml decoder url outputFile
50 either (error . show) pure
51 (runParser parser mempty "" (T.unpack specification))
52
53tryCacheOrHtml :: (ByteString -> Text) -> String -> FilePath -> Fetcher Text
54tryCacheOrHtml decoder url path = do
55 fileExists' <- liftIO $ doesFileExist path
56 content <- if fileExists'
57 then liftIO $ TIO.readFile path
58 else readHtmlFromURL decoder url >>= writePlain def
59 content <$ liftIO (TIO.writeFile path content)
60
61readHtmlFromURL :: (ByteString -> Text) -> String -> Fetcher Pandoc
62readHtmlFromURL decoder = lift . (openURL >=> readHtml def . decoder . fst) . pack
63
64lower :: Format r (String -> r)
65lower = mapf (fmap toLower) string
66
67fRevision :: Format r (Revision -> r)
68fRevision = mapf getRevision string
69
70fRevisionLower :: Format r (Revision -> r)
71fRevisionLower = mapf getRevision lower
72
73fMessageCodeLower :: Format r (MessageCode -> r)
74fMessageCodeLower = mapf getMessageCode lower
75
76fSegmentCodeLower :: Format r (SegmentCode -> r)
77fSegmentCodeLower = mapf getSegmentCode lower
78
79fCompositeCodeLower :: Format r (CompositeCode -> r)
80fCompositeCodeLower = mapf getCompositeCode lower
81
82fSimpleCodeLower :: Format r (SimpleCode -> r)
83fSimpleCodeLower = mapf getSimpleCode lower
84
85retry :: (MonadIO m, MonadError b m) => Int -> m a -> m a
86retry n f | n > 1 = f `catchError` const (say "Retrying" >> retry (n-1) f)
87 | otherwise = f