1 module Gargantext.Utils.Servant where
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
12 import Protolude.Partial (read)
17 instance Accept CSV where
18 contentType _ = "text" // "csv" /: ("charset", "utf-8")
20 instance (DefaultOrdered a, ToNamedRecord a) => MimeRender CSV [a] where
21 mimeRender _ val = encodeDefaultOrderedByName val
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
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
36 , "forms" .= (T.intercalate "|&|" $ unNgramsTerm <$> mSetToList _nre_children)]
37 toText :: ListType -> Text
38 toText CandidateTerm = "candidate"
39 toText MapTerm = "map"
40 toText StopTerm = "stop"
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"
48 len = fromIntegral $ length ("text/csv" :: Prelude.String)
50 --instance ToNamedRecord a => MimeRender CSV [a] where
51 -- mimeRender _ val = encode val