2 Module : Gargantext.API.Node.Update
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
12 {-# LANGUAGE TemplateHaskell #-}
13 {-# LANGUAGE TypeOperators #-}
14 {-# OPTIONS_GHC -fno-warn-orphans #-}
16 module Gargantext.API.Node.Update
19 import Control.Lens (view)
21 import Data.Maybe (Maybe(..), fromMaybe)
23 import GHC.Generics (Generic)
24 import Gargantext.API.Admin.Orchestrator.Types (JobLog(..), AsyncJobs)
25 import Gargantext.API.Admin.Types (HasSettings)
26 import Gargantext.API.Ngrams.List (reIndexWith)
27 --import Gargantext.API.Ngrams.Types (TabType(..))
28 import Gargantext.API.Prelude (GargServer, simuLogs)
29 import Gargantext.Core.Methods.Distances (GraphMetric(..))
30 import Gargantext.Core.Types.Main (ListType(..))
31 import Gargantext.Core.Viz.Graph.API (recomputeGraph)
32 import Gargantext.Core.Viz.Graph.Tools (PartitionMethod(..))
33 import Gargantext.Core.Viz.Phylo (PhyloSubConfig(..), subConfig2config)
34 import Gargantext.Core.Viz.Phylo.API.Tools (flowPhyloAPI)
35 import Gargantext.Database.Action.Flow.Pairing (pairing)
36 import Gargantext.Database.Action.Flow.Types (FlowCmdM)
37 import Gargantext.Database.Action.Metrics (updateNgramsOccurrences, updateContextScore)
38 import Gargantext.Database.Admin.Types.Hyperdata
39 import Gargantext.Database.Admin.Types.Node
40 import Gargantext.Database.Query.Table.Node (defaultList, getNode)
41 import Gargantext.Database.Query.Table.Node.UpdateOpaleye (updateHyperdata)
42 import Gargantext.Database.Schema.Ngrams (NgramsType(NgramsTerms))
43 import Gargantext.Database.Schema.Node (node_parent_id)
44 import Gargantext.Prelude (Bool(..), Ord, Eq, (<$>), ($), liftBase, (.), printDebug, pure, show, cs, (<>), panic, (<*>))
45 import Prelude (Enum, Bounded, minBound, maxBound)
47 import Servant.Job.Async (JobFunction(..), serveJobsAPI)
48 import Test.QuickCheck (elements)
49 import Test.QuickCheck.Arbitrary
50 import qualified Data.Set as Set
51 import qualified Gargantext.API.Metrics as Metrics
52 import qualified Gargantext.API.Ngrams.Types as NgramsTypes
53 import qualified Gargantext.Utils.Aeson as GUA
55 ------------------------------------------------------------------------
56 type API = Summary " Update node according to NodeType params"
57 :> AsyncJobs JobLog '[JSON] UpdateNodeParams JobLog
59 ------------------------------------------------------------------------
60 data UpdateNodeParams = UpdateNodeParamsList { methodList :: !Method }
62 | UpdateNodeParamsGraph { methodGraphMetric :: !GraphMetric
63 , methodGraphClustering :: !PartitionMethod
66 | UpdateNodeParamsTexts { methodTexts :: !Granularity }
68 | UpdateNodeParamsBoard { methodBoard :: !Charts }
70 | LinkNodeReq { nodeType :: !NodeType
73 | UpdateNodePhylo { config :: !PhyloSubConfig }
76 ----------------------------------------------------------------------
77 data Method = Basic | Advanced | WithModel
78 deriving (Generic, Eq, Ord, Enum, Bounded)
80 ----------------------------------------------------------------------
81 data Granularity = NewNgrams | NewTexts | Both
82 deriving (Generic, Eq, Ord, Enum, Bounded)
84 ----------------------------------------------------------------------
85 data Charts = Sources | Authors | Institutes | Ngrams | All
86 deriving (Generic, Eq, Ord, Enum, Bounded)
88 ------------------------------------------------------------------------
89 api :: UserId -> NodeId -> GargServer API
92 JobFunction (\p log'' ->
95 printDebug "updateNode" x
97 in updateNode uId nId p (liftBase . log')
100 updateNode :: (HasSettings env, FlowCmdM env err m)
106 updateNode uId nId (UpdateNodeParamsGraph metric method) logStatus = do
108 logStatus JobLog { _scst_succeeded = Just 1
109 , _scst_failed = Just 0
110 , _scst_remaining = Just 1
111 , _scst_events = Just []
114 _ <- recomputeGraph uId nId method (Just metric) True
116 pure JobLog { _scst_succeeded = Just 2
117 , _scst_failed = Just 0
118 , _scst_remaining = Just 0
119 , _scst_events = Just []
122 updateNode _uId nid1 (LinkNodeReq nt nid2) logStatus = do
123 logStatus JobLog { _scst_succeeded = Just 1
124 , _scst_failed = Just 0
125 , _scst_remaining = Just 1
126 , _scst_events = Just []
129 NodeAnnuaire -> pairing nid2 nid1 Nothing -- defaultList
130 NodeCorpus -> pairing nid1 nid2 Nothing -- defaultList
131 _ -> panic $ "[G.API.N.Update.updateNode] NodeType not implemented"
132 <> cs (show nt <> " nid1: " <> show nid1 <> " nid2: " <> show nid2)
134 pure JobLog { _scst_succeeded = Just 2
135 , _scst_failed = Just 0
136 , _scst_remaining = Just 0
137 , _scst_events = Just []
140 -- | `Advanced` to update graphs
141 updateNode _uId lId (UpdateNodeParamsList Advanced) logStatus = do
142 logStatus JobLog { _scst_succeeded = Just 1
143 , _scst_failed = Just 0
144 , _scst_remaining = Just 2
145 , _scst_events = Just []
147 corpusId <- view node_parent_id <$> getNode lId
149 logStatus JobLog { _scst_succeeded = Just 2
150 , _scst_failed = Just 0
151 , _scst_remaining = Just 1
152 , _scst_events = Just []
155 _ <- case corpusId of
157 _ <- Metrics.updatePie cId (Just lId) NgramsTypes.Authors Nothing
158 _ <- Metrics.updateTree cId (Just lId) NgramsTypes.Institutes MapTerm
159 _ <- Metrics.updatePie cId (Just lId) NgramsTypes.Sources Nothing
163 pure JobLog { _scst_succeeded = Just 3
164 , _scst_failed = Just 0
165 , _scst_remaining = Just 0
166 , _scst_events = Just []
169 updateNode _uId lId (UpdateNodeParamsList _mode) logStatus = do
170 logStatus JobLog { _scst_succeeded = Just 1
171 , _scst_failed = Just 0
172 , _scst_remaining = Just 2
173 , _scst_events = Just []
175 corpusId <- view node_parent_id <$> getNode lId
177 logStatus JobLog { _scst_succeeded = Just 2
178 , _scst_failed = Just 0
179 , _scst_remaining = Just 1
180 , _scst_events = Just []
183 _ <- case corpusId of
185 _ <- reIndexWith cId lId NgramsTerms (Set.singleton MapTerm)
186 _ <- updateNgramsOccurrences cId (Just lId)
190 pure JobLog { _scst_succeeded = Just 3
191 , _scst_failed = Just 0
192 , _scst_remaining = Just 0
193 , _scst_events = Just []
196 updateNode _userId phyloId (UpdateNodePhylo config) logStatus = do
197 logStatus JobLog { _scst_succeeded = Just 1
198 , _scst_failed = Just 0
199 , _scst_remaining = Just 2
200 , _scst_events = Just []
203 corpusId' <- view node_parent_id <$> getNode phyloId
205 let corpusId = fromMaybe (panic "") corpusId'
207 phy <- flowPhyloAPI (subConfig2config config) corpusId
209 logStatus JobLog { _scst_succeeded = Just 2
210 , _scst_failed = Just 0
211 , _scst_remaining = Just 1
212 , _scst_events = Just []
215 _ <- updateHyperdata phyloId (HyperdataPhylo Nothing (Just phy))
217 pure JobLog { _scst_succeeded = Just 3
218 , _scst_failed = Just 0
219 , _scst_remaining = Just 0
220 , _scst_events = Just []
224 updateNode _uId tId (UpdateNodeParamsTexts _mode) logStatus = do
225 logStatus JobLog { _scst_succeeded = Just 1
226 , _scst_failed = Just 0
227 , _scst_remaining = Just 2
228 , _scst_events = Just []
230 corpusId <- view node_parent_id <$> getNode tId
231 lId <- defaultList $ fromMaybe (panic "[G.A.N.Update] updateNode/UpdateNodeParamsTexts: no defaultList") corpusId
233 logStatus JobLog { _scst_succeeded = Just 2
234 , _scst_failed = Just 0
235 , _scst_remaining = Just 1
236 , _scst_events = Just []
239 _ <- case corpusId of
241 _ <- reIndexWith cId lId NgramsTerms (Set.singleton MapTerm)
242 _ <- updateNgramsOccurrences cId (Just lId)
243 _ <- updateContextScore cId (Just lId)
244 _ <- Metrics.updateChart cId (Just lId) NgramsTypes.Docs Nothing
245 -- printDebug "updateContextsScore" (cId, lId, u)
249 pure JobLog { _scst_succeeded = Just 3
250 , _scst_failed = Just 0
251 , _scst_remaining = Just 0
252 , _scst_events = Just []
259 updateNode _uId _nId _p logStatus = do
260 simuLogs logStatus 10
262 ------------------------------------------------------------------------
263 -- TODO unPrefix "pn_" FromJSON, ToJSON, ToSchema, adapt frontend.
264 instance FromJSON UpdateNodeParams where
265 parseJSON = genericParseJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
267 instance ToJSON UpdateNodeParams where
268 toJSON = genericToJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
270 instance ToSchema UpdateNodeParams
271 instance Arbitrary UpdateNodeParams where
273 l <- UpdateNodeParamsList <$> arbitrary
274 g <- UpdateNodeParamsGraph <$> arbitrary <*> arbitrary
275 t <- UpdateNodeParamsTexts <$> arbitrary
276 b <- UpdateNodeParamsBoard <$> arbitrary
279 instance FromJSON Method
280 instance ToJSON Method
281 instance ToSchema Method
282 instance Arbitrary Method where
283 arbitrary = elements [ minBound .. maxBound ]
285 instance FromJSON Granularity
286 instance ToJSON Granularity
287 instance ToSchema Granularity
288 instance Arbitrary Granularity where
289 arbitrary = elements [ minBound .. maxBound ]
291 instance FromJSON Charts
292 instance ToJSON Charts
293 instance ToSchema Charts
294 instance Arbitrary Charts where
295 arbitrary = elements [ minBound .. maxBound ]
297 ------------------------------------------------------------------------