]> Git — Sourcephile - gargantext.git/blob - src/Gargantext/Utils/Servant.hs
Merge remote-tracking branch 'origin/dev-hackathon-fixes' into dev-merge
[gargantext.git] / src / Gargantext / Utils / Servant.hs
1 module Gargantext.Utils.Servant where
2
3 import qualified Data.ByteString.Lazy.Char8 as BSC
4 import Data.Csv (defaultEncodeOptions, encodeByNameWith, encodeDefaultOrderedByName, header, namedRecord, (.=), DefaultOrdered, EncodeOptions(..), NamedRecord, Quoting(QuoteNone), ToNamedRecord)
5 import qualified Data.Map.Strict as Map
6 import qualified Data.Text as T
7 import Gargantext.API.Ngrams.Types (mSetToList, NgramsRepoElement(..), NgramsTableMap, NgramsTerm(..), unNgramsTerm)
8 import Gargantext.Core.Types.Main (ListType(..))
9 import Network.HTTP.Media ((//), (/:))
10 import qualified Prelude
11 import Protolude
12 import Protolude.Partial (read)
13 import Servant
14
15 data CSV = CSV
16
17 instance Accept CSV where
18 contentType _ = "text" // "csv" /: ("charset", "utf-8")
19
20 instance (DefaultOrdered a, ToNamedRecord a) => MimeRender CSV [a] where
21 mimeRender _ val = encodeDefaultOrderedByName val
22
23 -- CSV:
24 -- header: status\tlabel\tforms
25 -- item: map\taccountability\taccounting|&|accoutns|&|account
26 instance MimeRender CSV NgramsTableMap where
27 -- mimeRender _ _val = encode ([] :: [(Text, Text)])
28 mimeRender _ val = encodeByNameWith encOptions (header ["status", "label", "forms"]) $ fn <$> Map.toList val
29 where
30 encOptions = defaultEncodeOptions { encDelimiter = fromIntegral (ord '\t')
31 , encQuoting = QuoteNone }
32 fn :: (NgramsTerm, NgramsRepoElement) -> NamedRecord
33 fn (NgramsTerm term, NgramsRepoElement { _nre_list, _nre_children }) =
34 namedRecord [ "status" .= toText _nre_list
35 , "label" .= term
36 , "forms" .= (T.intercalate "|&|" $ unNgramsTerm <$> mSetToList _nre_children)]
37 toText :: ListType -> Text
38 toText CandidateTerm = "candidate"
39 toText MapTerm = "map"
40 toText StopTerm = "stop"
41
42 instance Read a => MimeUnrender CSV a where
43 mimeUnrender _ bs = case BSC.take len bs of
44 "text/csv" -> return . read . BSC.unpack $ BSC.drop len bs
45 _ -> Left "didn't start with the magic incantation"
46 where
47 len :: Int64
48 len = fromIntegral $ length ("text/csv" :: Prelude.String)
49
50 --instance ToNamedRecord a => MimeRender CSV [a] where
51 -- mimeRender _ val = encode val