2 Module : Gargantext.API.Ngrams
3 Description : Server API
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
13 -- get data of NgramsTable
14 -- post :: update NodeNodeNgrams
17 get ngrams filtered by NgramsType
22 {-# LANGUAGE DataKinds #-}
23 {-# LANGUAGE DeriveGeneric #-}
24 {-# LANGUAGE NoImplicitPrelude #-}
25 {-# LANGUAGE OverloadedStrings #-}
26 {-# LANGUAGE ScopedTypeVariables #-}
27 {-# LANGUAGE TemplateHaskell #-}
28 {-# LANGUAGE TypeOperators #-}
29 {-# LANGUAGE FlexibleInstances #-}
30 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
31 {-# OPTIONS -fno-warn-orphans #-}
33 module Gargantext.API.Ngrams
36 -- import Gargantext.Database.User (UserId)
37 import Data.Patch.Class (Replace, replace)
38 --import qualified Data.Map.Strict.Patch as PM
40 --import Data.Semigroup
42 import qualified Data.Set as Set
43 --import Data.Maybe (catMaybes)
44 --import qualified Data.Map.Strict as DM
45 --import qualified Data.Set as Set
46 import Control.Lens (view, (.~))
48 import Data.Aeson.TH (deriveJSON)
49 import Data.Either(Either(Left))
50 import Data.List (concat)
51 import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
53 import Data.Text (Text)
54 import Database.PostgreSQL.Simple (Connection)
55 import GHC.Generics (Generic)
56 import Gargantext.Core.Types (node_id)
57 --import Gargantext.Core.Types.Main (Tree(..))
58 import Gargantext.Core.Utils.Prefix (unPrefix)
59 import Gargantext.Database.Ngrams (NgramsId)
60 import Gargantext.Database.Node (getListsWithParentId)
61 -- import Gargantext.Database.NodeNgram -- (NodeNgram(..), NodeNgram, updateNodeNgrams, NodeNgramPoly)
62 import Gargantext.Database.NodeNgramsNgrams -- (NodeNgramsNgramsPoly(NodeNgramsNgrams))
63 import Gargantext.Prelude
64 import Gargantext.Text.List.Types (ListType(..), ListId, ListTypeId) -- ,listTypeId )
65 import Prelude (Enum, Bounded, minBound, maxBound)
66 import Servant hiding (Patch)
67 import Test.QuickCheck (elements)
68 import Test.QuickCheck.Arbitrary (Arbitrary, arbitrary)
70 ------------------------------------------------------------------------
71 --data FacetFormat = Table | Chart
72 data TabType = Docs | Terms | Sources | Authors | Trash
73 deriving (Generic, Enum, Bounded)
75 instance FromHttpApiData TabType
77 parseUrlPiece "Docs" = pure Docs
78 parseUrlPiece "Terms" = pure Terms
79 parseUrlPiece "Sources" = pure Sources
80 parseUrlPiece "Authors" = pure Authors
81 parseUrlPiece "Trash" = pure Trash
82 parseUrlPiece _ = Left "Unexpected value of TabType"
84 instance ToParamSchema TabType
85 instance ToJSON TabType
86 instance FromJSON TabType
87 instance ToSchema TabType
88 instance Arbitrary TabType
90 arbitrary = elements [minBound .. maxBound]
92 ------------------------------------------------------------------------
93 type NgramsTerm = Text
96 NgramsElement { _ne_ngrams :: NgramsTerm
97 , _ne_list :: ListType
98 , _ne_occurrences :: Int
99 , _ne_root :: Maybe NgramsTerm
100 , _ne_children :: Set NgramsTerm
102 deriving (Ord, Eq, Show, Generic)
103 $(deriveJSON (unPrefix "_ne_") ''NgramsElement)
105 instance ToSchema NgramsElement
106 instance Arbitrary NgramsElement where
107 arbitrary = elements [NgramsElement "sport" StopList 1 Nothing mempty]
109 ------------------------------------------------------------------------
110 newtype NgramsTable = NgramsTable { _ngramsTable :: [NgramsElement] }
111 deriving (Ord, Eq, Generic, ToJSON, FromJSON)
113 instance Arbitrary NgramsTable where
116 [ NgramsElement "animal" GraphList 1 Nothing (Set.fromList ["dog"])
117 , NgramsElement "dog" GraphList 3 (Just "animal")
118 (Set.fromList ["object", "cat", "nothing"])
119 , NgramsElement "object" CandidateList 2 (Just "animal") mempty
120 , NgramsElement "cat" GraphList 1 (Just "animal") mempty
121 , NgramsElement "nothing" StopList 4 (Just "animal") mempty
124 [ NgramsElement "plant" GraphList 3 Nothing
125 (Set.fromList ["flower", "moon", "cat", "sky"])
126 , NgramsElement "flower" GraphList 3 (Just "plant") mempty
127 , NgramsElement "moon" CandidateList 1 (Just "plant") mempty
128 , NgramsElement "cat" GraphList 2 (Just "plant") mempty
129 , NgramsElement "sky" StopList 1 (Just "plant") mempty
132 instance ToSchema NgramsTable
134 ------------------------------------------------------------------------
135 -- On the Client side:
136 --data Action = InGroup NgramsId NgramsId
137 -- | OutGroup NgramsId NgramsId
138 -- | SetListType NgramsId ListType
140 data PatchSet a = PatchSet
144 deriving (Eq, Ord, Show, Generic)
146 instance (Ord a, Arbitrary a) => Arbitrary (PatchSet a) where
147 arbitrary = PatchSet <$> arbitrary <*> arbitrary
149 instance ToJSON a => ToJSON (PatchSet a) where
150 toJSON = genericToJSON $ unPrefix "_"
151 toEncoding = genericToEncoding $ unPrefix "_"
153 instance (Ord a, FromJSON a) => FromJSON (PatchSet a) where
154 parseJSON = genericParseJSON $ unPrefix "_"
156 instance ToSchema a => ToSchema (PatchSet a)
158 instance ToSchema a => ToSchema (Replace a) where
159 declareNamedSchema (_ :: proxy (Replace a)) = do
160 aSchema <- declareSchemaRef (Proxy :: Proxy a)
161 return $ NamedSchema (Just "Replace") $ mempty
162 & type_ .~ SwaggerObject
164 InsOrdHashMap.fromList
168 & required .~ [ "old", "new" ]
171 NgramsPatch { _patch_children :: PatchSet NgramsElement
172 , _patch_list :: Replace ListType -- TODO Map UserId ListType
174 deriving (Ord, Eq, Show, Generic)
175 $(deriveJSON (unPrefix "_") ''NgramsPatch)
177 -- instance Semigroup NgramsPatch where
179 instance ToSchema NgramsPatch
181 instance Arbitrary NgramsPatch where
182 arbitrary = NgramsPatch <$> arbitrary <*> (replace <$> arbitrary <*> arbitrary)
185 NgramsIdPatch { _nip_ngramsId :: NgramsTerm
186 , _nip_ngramsPatch :: NgramsPatch
188 deriving (Ord, Eq, Show, Generic)
190 $(deriveJSON (unPrefix "_nip_") ''NgramsIdPatch)
192 instance ToSchema NgramsIdPatch
194 instance Arbitrary NgramsIdPatch where
195 arbitrary = NgramsIdPatch <$> arbitrary <*> arbitrary
199 -- * This should be a Map NgramsId NgramsPatch
200 -- * Patchs -> Patches
201 newtype NgramsIdPatchs =
202 NgramsIdPatchs { _nip_ngramsIdPatchs :: [NgramsIdPatch] }
203 deriving (Ord, Eq, Show, Generic, Arbitrary)
204 $(deriveJSON (unPrefix "_nip_") ''NgramsIdPatchs)
205 instance ToSchema NgramsIdPatchs
207 ------------------------------------------------------------------------
208 ------------------------------------------------------------------------
211 data Versioned a = Versioned
212 { _v_version :: Version
218 -- TODO sequencs of modifications (Patchs)
219 type NgramsIdPatch = Patch NgramsId NgramsPatch
221 ngramsPatch :: Int -> NgramsPatch
222 ngramsPatch n = NgramsPatch (DM.fromList [(1, StopList)]) (Set.fromList [n]) Set.empty
224 toEdit :: NgramsId -> NgramsPatch -> Edit NgramsId NgramsPatch
225 toEdit n p = Edit n p
226 ngramsIdPatch :: Patch NgramsId NgramsPatch
227 ngramsIdPatch = fromList $ catMaybes $ reverse [ replace (1::NgramsId) (Just $ ngramsPatch 1) Nothing
228 , replace (1::NgramsId) Nothing (Just $ ngramsPatch 2)
229 , replace (2::NgramsId) Nothing (Just $ ngramsPatch 2)
232 -- applyPatchBack :: Patch -> IO Patch
233 -- isEmptyPatch = Map.all (\x -> Set.isEmpty (add_children x) && Set.isEmpty ... )
235 ------------------------------------------------------------------------
236 ------------------------------------------------------------------------
237 ------------------------------------------------------------------------
239 type TableNgramsApi = Summary " Table Ngrams API Change"
240 :> QueryParam "list" ListId
241 :> ReqBody '[JSON] NgramsIdPatchs -- Versioned ...
242 :> Put '[JSON] NgramsIdPatchsBack -- Versioned ...
244 type TableNgramsApiGet = Summary " Table Ngrams API Get"
245 :> QueryParam "ngramsType" TabType
246 :> QueryParam "list" ListId
247 :> Get '[JSON] NgramsTable
249 type NgramsIdPatchsFeed = NgramsIdPatchs
250 type NgramsIdPatchsBack = NgramsIdPatchs
253 defaultList :: Connection -> CorpusId -> IO ListId
254 defaultList c cId = view node_id <$> maybe (panic noListFound) identity
256 <$> getListsWithParentId c cId
258 noListFound = "Gargantext.API.Ngrams.defaultList: no list found"
260 toLists :: ListId -> NgramsIdPatchs -> [(ListId, NgramsId, ListTypeId)]
264 [ (lId,ngId,listTypeId lt) | map (toList lId) (_nip_ngramsIdPatchs np) ]
267 toList :: ListId -> NgramsIdPatch -> (ListId, NgramsId, ListTypeId)
270 toGroups :: ListId -> (NgramsPatch -> Set NgramsId) -> NgramsIdPatchs -> [NodeNgramsNgrams]
271 toGroups lId addOrRem ps = concat $ map (toGroup lId addOrRem) $ _nip_ngramsIdPatchs ps
273 toGroup :: ListId -> (NgramsPatch -> Set NgramsId) -> NgramsIdPatch -> [NodeNgramsNgrams]
277 toGroup lId addOrRem (NgramsIdPatch ngId patch) =
278 map (\ng -> (NodeNgramsNgrams lId ngId ng (Just 1))) (Set.toList $ addOrRem patch)
282 tableNgramsPatch :: Connection -> CorpusId -> Maybe ListId -> NgramsIdPatchsFeed -> IO NgramsIdPatchsBack
283 tableNgramsPatch = undefined
285 tableNgramsPatch conn corpusId maybeList patchs = do
286 listId <- case maybeList of
287 Nothing -> defaultList conn corpusId
288 Just listId' -> pure listId'
289 _ <- ngramsGroup' conn Add $ toGroups listId _np_add_children patchs
290 _ <- ngramsGroup' conn Del $ toGroups listId _np_rem_children patchs
291 _ <- updateNodeNgrams conn (toLists listId patchs)
292 pure (NgramsIdPatchs [])
295 getTableNgramsPatch :: Connection -> CorpusId -> Maybe TabType -> Maybe ListId -> IO NgramsTable
296 getTableNgramsPatch = undefined