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 | Institutes | 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 "Institutes" = pure Institutes
81 parseUrlPiece "Authors" = pure Authors
82 parseUrlPiece "Trash" = pure Trash
83 parseUrlPiece _ = Left "Unexpected value of TabType"
85 instance ToParamSchema TabType
86 instance ToJSON TabType
87 instance FromJSON TabType
88 instance ToSchema TabType
89 instance Arbitrary TabType
91 arbitrary = elements [minBound .. maxBound]
93 ------------------------------------------------------------------------
94 type NgramsTerm = Text
97 NgramsElement { _ne_ngrams :: NgramsTerm
98 , _ne_list :: ListType
99 , _ne_occurrences :: Int
100 , _ne_parent :: Maybe NgramsTerm
101 , _ne_children :: Set NgramsTerm
103 deriving (Ord, Eq, Show, Generic)
104 $(deriveJSON (unPrefix "_ne_") ''NgramsElement)
106 instance ToSchema NgramsElement
107 instance Arbitrary NgramsElement where
108 arbitrary = elements [NgramsElement "sport" GraphList 1 Nothing mempty]
110 ------------------------------------------------------------------------
111 newtype NgramsTable = NgramsTable { _ngramsTable :: [NgramsElement] }
112 deriving (Ord, Eq, Generic, ToJSON, FromJSON)
114 instance Arbitrary NgramsTable where
117 [ NgramsElement "animal" GraphList 1 Nothing (Set.fromList ["dog", "cat"])
118 , NgramsElement "cat" GraphList 1 (Just "animal") mempty
119 , NgramsElement "dog" GraphList 3 (Just "animal")(Set.fromList ["dogs"])
120 , NgramsElement "dogs" StopList 4 (Just "dog") mempty
121 , NgramsElement "object" CandidateList 2 Nothing mempty
122 , NgramsElement "nothing" StopList 4 Nothing mempty
125 [ NgramsElement "organic" GraphList 3 Nothing (Set.singleton "flower")
126 , NgramsElement "flower" GraphList 3 (Just "organic") mempty
127 , NgramsElement "moon" CandidateList 1 Nothing mempty
128 , NgramsElement "cat" GraphList 2 Nothing mempty
129 , NgramsElement "sky" StopList 1 Nothing 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_ngrams :: NgramsTerm
186 , _nip_ngramsPatch :: NgramsPatch
188 deriving (Ord, Eq, Show, Generic)
189 $(deriveJSON (unPrefix "_nip_") ''NgramsIdPatch)
191 instance ToSchema NgramsIdPatch
193 instance Arbitrary NgramsIdPatch where
194 arbitrary = NgramsIdPatch <$> arbitrary <*> arbitrary
198 -- * This should be a Map NgramsId NgramsPatch
199 -- * Patchs -> Patches
200 newtype NgramsIdPatchs =
201 NgramsIdPatchs { _nip_ngramsIdPatchs :: [NgramsIdPatch] }
202 deriving (Ord, Eq, Show, Generic, Arbitrary)
203 $(deriveJSON (unPrefix "_nip_") ''NgramsIdPatchs)
204 instance ToSchema NgramsIdPatchs
206 ------------------------------------------------------------------------
207 ------------------------------------------------------------------------
210 data Versioned a = Versioned
211 { _v_version :: Version
216 -- TODO sequencs of modifications (Patchs)
217 type NgramsIdPatch = Patch NgramsId NgramsPatch
219 ngramsPatch :: Int -> NgramsPatch
220 ngramsPatch n = NgramsPatch (DM.fromList [(1, StopList)]) (Set.fromList [n]) Set.empty
222 toEdit :: NgramsId -> NgramsPatch -> Edit NgramsId NgramsPatch
223 toEdit n p = Edit n p
224 ngramsIdPatch :: Patch NgramsId NgramsPatch
225 ngramsIdPatch = fromList $ catMaybes $ reverse [ replace (1::NgramsId) (Just $ ngramsPatch 1) Nothing
226 , replace (1::NgramsId) Nothing (Just $ ngramsPatch 2)
227 , replace (2::NgramsId) Nothing (Just $ ngramsPatch 2)
230 -- applyPatchBack :: Patch -> IO Patch
231 -- isEmptyPatch = Map.all (\x -> Set.isEmpty (add_children x) && Set.isEmpty ... )
233 ------------------------------------------------------------------------
234 ------------------------------------------------------------------------
235 ------------------------------------------------------------------------
238 type TableNgramsApiGet = Summary " Table Ngrams API Get"
239 :> QueryParam "ngramsType" TabType
240 :> QueryParam "list" ListId
241 :> Get '[JSON] NgramsTable
243 type TableNgramsApi = Summary " Table Ngrams API Change"
244 :> QueryParam "list" ListId
245 :> ReqBody '[JSON] NgramsIdPatchsFeed -- Versioned ...
246 :> Put '[JSON] NgramsIdPatchsBack -- Versioned ...
248 type NgramsIdPatchsFeed = NgramsIdPatchs
249 type NgramsIdPatchsBack = NgramsIdPatchs
252 defaultList :: Connection -> CorpusId -> IO ListId
253 defaultList c cId = view node_id <$> maybe (panic noListFound) identity
255 <$> getListsWithParentId c cId
257 noListFound = "Gargantext.API.Ngrams.defaultList: no list found"
260 toLists :: ListId -> NgramsIdPatchs -> [(ListId, NgramsId, ListTypeId)]
261 -- toLists = undefined
262 toLists lId np = [ (lId,ngId,listTypeId lt) | map (toList lId) (_nip_ngramsIdPatchs np) ]
264 toList :: ListId -> NgramsIdPatch -> (ListId, NgramsId, ListTypeId)
267 toGroups :: ListId -> (NgramsPatch -> Set NgramsId) -> NgramsIdPatchs -> [NodeNgramsNgrams]
268 toGroups lId addOrRem ps = concat $ map (toGroup lId addOrRem) $ _nip_ngramsIdPatchs ps
270 toGroup :: ListId -> (NgramsPatch -> Set NgramsId) -> NgramsIdPatch -> [NodeNgramsNgrams]
271 -- toGroup = undefined
272 toGroup lId addOrRem (NgramsIdPatch ngId patch) =
273 map (\ng -> (NodeNgramsNgrams lId ngId ng (Just 1))) (Set.toList $ addOrRem patch)
277 tableNgramsPatch :: Connection -> CorpusId -> Maybe ListId -> NgramsIdPatchsFeed -> IO NgramsIdPatchsBack
278 tableNgramsPatch = undefined
280 tableNgramsPatch conn corpusId maybeList patchs = do
281 listId <- case maybeList of
282 Nothing -> defaultList conn corpusId
283 Just listId' -> pure listId'
284 _ <- ngramsGroup' conn Add $ toGroups listId _np_add_children patchs
285 _ <- ngramsGroup' conn Del $ toGroups listId _np_rem_children patchs
286 _ <- updateNodeNgrams conn (toLists listId patchs)
287 pure (NgramsIdPatchs [])
290 getTableNgramsPatch :: Connection -> CorpusId -> Maybe TabType -> Maybe ListId -> IO NgramsTable
291 getTableNgramsPatch = undefined