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.EnvTypes (GargJob(..), Env)
25 import Gargantext.API.Admin.Orchestrator.Types (JobLog(..), AsyncJobs)
26 import Gargantext.API.Admin.Types (HasSettings)
27 import Gargantext.API.Ngrams.List (reIndexWith)
28 --import Gargantext.API.Ngrams.Types (TabType(..))
29 import Gargantext.API.Prelude (GargM, GargError, simuLogs)
30 import Gargantext.Core.Methods.Similarities (GraphMetric(..))
31 import Gargantext.Core.Types.Main (ListType(..))
32 import Gargantext.Core.Viz.Graph.API (recomputeGraph)
33 import Gargantext.Core.Viz.Graph.Tools (PartitionMethod(..), BridgenessMethod(..))
34 import Gargantext.Core.Viz.Graph.Types (Strength)
35 import Gargantext.Core.Viz.Phylo (PhyloSubConfig(..), subConfig2config)
36 import Gargantext.Core.Viz.Phylo.API.Tools (flowPhyloAPI)
37 import Gargantext.Database.Action.Flow.Pairing (pairing)
38 import Gargantext.Database.Action.Flow.Types (FlowCmdM)
39 import Gargantext.Database.Action.Metrics (updateNgramsOccurrences, updateContextScore)
40 import Gargantext.Database.Admin.Types.Hyperdata
41 import Gargantext.Database.Admin.Types.Node
42 import Gargantext.Database.Query.Table.Node (defaultList, getNode)
43 import Gargantext.Database.Query.Table.Node.UpdateOpaleye (updateHyperdata)
44 import Gargantext.Database.Schema.Ngrams (NgramsType(NgramsTerms))
45 import Gargantext.Database.Schema.Node (node_parent_id)
46 import Gargantext.Prelude (Bool(..), Ord, Eq, (<$>), ($), {-printDebug,-} pure, show, cs, (<>), panic, (<*>))
47 import Gargantext.Utils.Jobs (serveJobsAPI, jobHandleLogger)
48 import Prelude (Enum, Bounded, minBound, maxBound)
50 import Test.QuickCheck (elements)
51 import Test.QuickCheck.Arbitrary
52 import qualified Data.Set as Set
53 import qualified Gargantext.API.Metrics as Metrics
54 import qualified Gargantext.API.Ngrams.Types as NgramsTypes
55 import qualified Gargantext.Utils.Aeson as GUA
57 ------------------------------------------------------------------------
58 type API = Summary " Update node according to NodeType params"
59 :> AsyncJobs JobLog '[JSON] UpdateNodeParams JobLog
61 ------------------------------------------------------------------------
62 data UpdateNodeParams = UpdateNodeParamsList { methodList :: !Method }
64 | UpdateNodeParamsGraph { methodGraphMetric :: !GraphMetric
65 , methodGraphClustering :: !PartitionMethod
66 , methodGraphBridgeness :: !BridgenessMethod
67 , methodGraphEdgesStrength :: !Strength
68 , methodGraphNodeType1 :: !NgramsType
69 , methodGraphNodeType2 :: !NgramsType
72 | UpdateNodeParamsTexts { methodTexts :: !Granularity }
74 | UpdateNodeParamsBoard { methodBoard :: !Charts }
76 | LinkNodeReq { nodeType :: !NodeType
79 | UpdateNodePhylo { config :: !PhyloSubConfig }
82 ----------------------------------------------------------------------
83 data Method = Basic | Advanced | WithModel
84 deriving (Generic, Eq, Ord, Enum, Bounded)
86 ----------------------------------------------------------------------
87 data Granularity = NewNgrams | NewTexts | Both
88 deriving (Generic, Eq, Ord, Enum, Bounded)
90 ----------------------------------------------------------------------
91 data Charts = Sources | Authors | Institutes | Ngrams | All
92 deriving (Generic, Eq, Ord, Enum, Bounded)
94 ------------------------------------------------------------------------
95 api :: UserId -> NodeId -> ServerT API (GargM Env GargError)
97 serveJobsAPI UpdateNodeJob $ \jHandle p ->
100 -- printDebug "updateNode" x
101 jobHandleLogger jHandle x
102 in updateNode uId nId p log'
104 updateNode :: (HasSettings env, FlowCmdM env err m)
110 updateNode uId nId (UpdateNodeParamsGraph metric partitionMethod bridgeMethod strength nt1 nt2) logStatus = do
112 logStatus JobLog { _scst_succeeded = Just 1
113 , _scst_failed = Just 0
114 , _scst_remaining = Just 1
115 , _scst_events = Just []
117 -- printDebug "Computing graph: " method
118 _ <- recomputeGraph uId nId partitionMethod bridgeMethod (Just metric) (Just strength) nt1 nt2 True
119 -- printDebug "Graph computed: " method
121 pure JobLog { _scst_succeeded = Just 2
122 , _scst_failed = Just 0
123 , _scst_remaining = Just 0
124 , _scst_events = Just []
127 updateNode _uId nid1 (LinkNodeReq nt nid2) logStatus = do
128 logStatus JobLog { _scst_succeeded = Just 1
129 , _scst_failed = Just 0
130 , _scst_remaining = Just 1
131 , _scst_events = Just []
134 NodeAnnuaire -> pairing nid2 nid1 Nothing -- defaultList
135 NodeCorpus -> pairing nid1 nid2 Nothing -- defaultList
136 _ -> panic $ "[G.API.N.Update.updateNode] NodeType not implemented"
137 <> cs (show nt <> " nid1: " <> show nid1 <> " nid2: " <> show nid2)
139 pure JobLog { _scst_succeeded = Just 2
140 , _scst_failed = Just 0
141 , _scst_remaining = Just 0
142 , _scst_events = Just []
145 -- | `Advanced` to update graphs
146 updateNode _uId lId (UpdateNodeParamsList Advanced) logStatus = do
147 logStatus JobLog { _scst_succeeded = Just 1
148 , _scst_failed = Just 0
149 , _scst_remaining = Just 2
150 , _scst_events = Just []
152 corpusId <- view node_parent_id <$> getNode lId
154 logStatus JobLog { _scst_succeeded = Just 2
155 , _scst_failed = Just 0
156 , _scst_remaining = Just 1
157 , _scst_events = Just []
160 _ <- case corpusId of
162 _ <- Metrics.updatePie cId (Just lId) NgramsTypes.Authors Nothing
163 _ <- Metrics.updateTree cId (Just lId) NgramsTypes.Institutes MapTerm
164 _ <- Metrics.updatePie cId (Just lId) NgramsTypes.Sources Nothing
168 pure JobLog { _scst_succeeded = Just 3
169 , _scst_failed = Just 0
170 , _scst_remaining = Just 0
171 , _scst_events = Just []
174 updateNode _uId lId (UpdateNodeParamsList _mode) logStatus = do
175 logStatus JobLog { _scst_succeeded = Just 1
176 , _scst_failed = Just 0
177 , _scst_remaining = Just 2
178 , _scst_events = Just []
180 corpusId <- view node_parent_id <$> getNode lId
182 logStatus JobLog { _scst_succeeded = Just 2
183 , _scst_failed = Just 0
184 , _scst_remaining = Just 1
185 , _scst_events = Just []
188 _ <- case corpusId of
190 _ <- reIndexWith cId lId NgramsTerms (Set.singleton MapTerm)
191 _ <- updateNgramsOccurrences cId (Just lId)
195 pure JobLog { _scst_succeeded = Just 3
196 , _scst_failed = Just 0
197 , _scst_remaining = Just 0
198 , _scst_events = Just []
201 updateNode _userId phyloId (UpdateNodePhylo config) logStatus = do
202 logStatus JobLog { _scst_succeeded = Just 1
203 , _scst_failed = Just 0
204 , _scst_remaining = Just 2
205 , _scst_events = Just []
208 corpusId' <- view node_parent_id <$> getNode phyloId
210 let corpusId = fromMaybe (panic "") corpusId'
212 phy <- flowPhyloAPI (subConfig2config config) corpusId
214 logStatus JobLog { _scst_succeeded = Just 2
215 , _scst_failed = Just 0
216 , _scst_remaining = Just 1
217 , _scst_events = Just []
220 _ <- updateHyperdata phyloId (HyperdataPhylo Nothing (Just phy))
222 pure JobLog { _scst_succeeded = Just 3
223 , _scst_failed = Just 0
224 , _scst_remaining = Just 0
225 , _scst_events = Just []
229 updateNode _uId tId (UpdateNodeParamsTexts _mode) logStatus = do
230 logStatus JobLog { _scst_succeeded = Just 1
231 , _scst_failed = Just 0
232 , _scst_remaining = Just 2
233 , _scst_events = Just []
235 corpusId <- view node_parent_id <$> getNode tId
236 lId <- defaultList $ fromMaybe (panic "[G.A.N.Update] updateNode/UpdateNodeParamsTexts: no defaultList") corpusId
238 logStatus JobLog { _scst_succeeded = Just 2
239 , _scst_failed = Just 0
240 , _scst_remaining = Just 1
241 , _scst_events = Just []
244 _ <- case corpusId of
246 _ <- reIndexWith cId lId NgramsTerms (Set.singleton MapTerm)
247 _ <- updateNgramsOccurrences cId (Just lId)
248 _ <- updateContextScore cId (Just lId)
249 _ <- Metrics.updateChart cId (Just lId) NgramsTypes.Docs Nothing
250 -- printDebug "updateContextsScore" (cId, lId, u)
254 pure JobLog { _scst_succeeded = Just 3
255 , _scst_failed = Just 0
256 , _scst_remaining = Just 0
257 , _scst_events = Just []
264 updateNode _uId _nId _p logStatus = do
265 simuLogs logStatus 10
267 ------------------------------------------------------------------------
268 -- TODO unPrefix "pn_" FromJSON, ToJSON, ToSchema, adapt frontend.
269 instance FromJSON UpdateNodeParams where
270 parseJSON = genericParseJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
272 instance ToJSON UpdateNodeParams where
273 toJSON = genericToJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
275 instance ToSchema UpdateNodeParams
276 instance Arbitrary UpdateNodeParams where
278 l <- UpdateNodeParamsList <$> arbitrary
279 g <- UpdateNodeParamsGraph <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
280 t <- UpdateNodeParamsTexts <$> arbitrary
281 b <- UpdateNodeParamsBoard <$> arbitrary
284 instance FromJSON Method
285 instance ToJSON Method
286 instance ToSchema Method
287 instance Arbitrary Method where
288 arbitrary = elements [ minBound .. maxBound ]
290 instance FromJSON Granularity
291 instance ToJSON Granularity
292 instance ToSchema Granularity
293 instance Arbitrary Granularity where
294 arbitrary = elements [ minBound .. maxBound ]
296 instance FromJSON Charts
297 instance ToJSON Charts
298 instance ToSchema Charts
299 instance Arbitrary Charts where
300 arbitrary = elements [ minBound .. maxBound ]
302 ------------------------------------------------------------------------