2 Module : Gargantext.API.Metrics
3 Description : Server API
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
14 {-# OPTIONS_GHC -fno-warn-orphans #-}
16 {-# LANGUAGE TypeOperators #-}
18 module Gargantext.API.Metrics
22 import qualified Data.Map as Map
23 import Data.Text (Text)
24 import Data.Time (UTCTime)
27 import Gargantext.API.HashedResponse
28 import Gargantext.API.Ngrams.NTree
29 import Gargantext.API.Ngrams.Types
30 import Gargantext.API.Prelude (GargServer)
31 import Gargantext.Core.Types (CorpusId, Limit, ListId, ListType(..))
32 import Gargantext.Database.Action.Flow
33 import Gargantext.Database.Admin.Types.Hyperdata (HyperdataList(..), hl_chart, hl_pie, hl_scatter, hl_tree)
34 import Gargantext.Database.Admin.Types.Metrics (ChartMetrics(..), Metric(..), Metrics(..))
35 import Gargantext.Database.Admin.Types.Node (NodeId)
36 import Gargantext.Database.Prelude
37 import Gargantext.Database.Query.Table.Node (defaultList, getNodeWith)
38 import Gargantext.Database.Query.Table.Node.Error (HasNodeError)
39 import Gargantext.Database.Query.Table.Node.UpdateOpaleye (updateHyperdata)
40 import Gargantext.Database.Schema.Node (node_hyperdata)
41 import Gargantext.Prelude
42 import Gargantext.Core.Text.Metrics (Scored(..), {-normalizeGlobal,-} normalizeLocal)
43 import Gargantext.Core.Viz.Chart
44 import Gargantext.Core.Viz.Types
45 import qualified Gargantext.Database.Action.Metrics as Metrics
47 -------------------------------------------------------------
48 -- | Scatter metrics API
49 type ScatterAPI = Summary "SepGen IncExc metrics"
50 :> QueryParam "list" ListId
51 :> QueryParamR "ngramsType" TabType
52 :> QueryParam "limit" Int
53 :> Get '[JSON] (HashedResponse Metrics)
54 :<|> Summary "Scatter update"
55 :> QueryParam "list" ListId
56 :> QueryParamR "ngramsType" TabType
57 :> QueryParam "limit" Int
59 :<|> "hash" :> Summary "Scatter Hash"
60 :> QueryParam "list" ListId
61 :> QueryParamR "ngramsType" TabType
64 scatterApi :: NodeId -> GargServer ScatterAPI
65 scatterApi id' = getScatter id'
66 :<|> updateScatter id'
67 :<|> getScatterHash id'
69 getScatter :: FlowCmdM env err m =>
74 -> m (HashedResponse Metrics)
75 getScatter cId maybeListId tabType _maybeLimit = do
76 listId <- case maybeListId of
78 Nothing -> defaultList cId
79 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
80 let HyperdataList { _hl_scatter = scatterMap } = node ^. node_hyperdata
81 mChart = Map.lookup tabType scatterMap
83 chart <- case mChart of
84 Just chart -> pure chart
86 updateScatter' cId maybeListId tabType Nothing
88 pure $ constructHashedResponse chart
90 updateScatter :: FlowCmdM env err m =>
96 updateScatter cId maybeListId tabType maybeLimit = do
97 printDebug "[updateScatter] cId" cId
98 printDebug "[updateScatter] maybeListId" maybeListId
99 printDebug "[updateScatter] tabType" tabType
100 printDebug "[updateScatter] maybeLimit" maybeLimit
101 _ <- updateScatter' cId maybeListId tabType maybeLimit
104 updateScatter' :: FlowCmdM env err m =>
110 updateScatter' cId maybeListId tabType maybeLimit = do
111 (ngs', scores) <- Metrics.getMetrics cId maybeListId tabType maybeLimit
114 metrics = map (\(Scored t s1 s2) -> Metric t s1 s2 (listType t ngs'))
115 $ map normalizeLocal scores
116 listType t m = maybe (panic errorMsg) fst $ Map.lookup t m
117 errorMsg = "API.Node.metrics: key absent"
119 listId <- case maybeListId of
121 Nothing -> defaultList cId
122 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
123 let hl = node ^. node_hyperdata
124 scatterMap = hl ^. hl_scatter
125 _ <- updateHyperdata listId $ hl { _hl_scatter = Map.insert tabType (Metrics metrics) scatterMap }
127 pure $ Metrics metrics
129 getScatterHash :: FlowCmdM env err m =>
134 getScatterHash cId maybeListId tabType = do
135 hash <$> getScatter cId maybeListId tabType Nothing
138 -------------------------------------------------------------
139 -- | Chart metrics API
140 type ChartApi = Summary " Chart API"
141 :> QueryParam "from" UTCTime
142 :> QueryParam "to" UTCTime
143 :> QueryParam "list" ListId
144 :> QueryParamR "ngramsType" TabType
145 :> Get '[JSON] (HashedResponse (ChartMetrics Histo))
146 :<|> Summary "Chart update"
147 :> QueryParam "list" ListId
148 :> QueryParamR "ngramsType" TabType
149 :> QueryParam "limit" Int
151 :<|> "hash" :> Summary "Chart Hash"
152 :> QueryParam "list" ListId
153 :> QueryParamR "ngramsType" TabType
156 chartApi :: NodeId -> GargServer ChartApi
157 chartApi id' = getChart id'
159 :<|> getChartHash id'
161 -- TODO add start / end
162 getChart :: FlowCmdM env err m =>
168 -> m (HashedResponse (ChartMetrics Histo))
169 getChart cId _start _end maybeListId tabType = do
170 listId <- case maybeListId of
172 Nothing -> defaultList cId
173 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
174 let HyperdataList { _hl_chart = chartMap } = node ^. node_hyperdata
175 mChart = Map.lookup tabType chartMap
177 chart <- case mChart of
178 Just chart -> pure chart
180 updateChart' cId maybeListId tabType Nothing
182 pure $ constructHashedResponse chart
184 updateChart :: HasNodeError err =>
190 updateChart cId maybeListId tabType maybeLimit = do
191 printDebug "[updateChart] cId" cId
192 printDebug "[updateChart] maybeListId" maybeListId
193 printDebug "[updateChart] tabType" tabType
194 printDebug "[updateChart] maybeLimit" maybeLimit
195 _ <- updateChart' cId maybeListId tabType maybeLimit
198 updateChart' :: HasNodeError err =>
203 -> Cmd err (ChartMetrics Histo)
204 updateChart' cId maybeListId tabType _maybeLimit = do
205 listId <- case maybeListId of
207 Nothing -> defaultList cId
208 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
209 let hl = node ^. node_hyperdata
210 chartMap = hl ^. hl_chart
212 _ <- updateHyperdata listId $ hl { _hl_chart = Map.insert tabType (ChartMetrics h) chartMap }
214 pure $ ChartMetrics h
217 getChartHash :: FlowCmdM env err m =>
222 getChartHash cId maybeListId tabType = do
223 hash <$> getChart cId Nothing Nothing maybeListId tabType
225 -------------------------------------------------------------
227 type PieApi = Summary "Pie Chart"
228 :> QueryParam "from" UTCTime
229 :> QueryParam "to" UTCTime
230 :> QueryParam "list" ListId
231 :> QueryParamR "ngramsType" TabType
232 :> Get '[JSON] (HashedResponse (ChartMetrics Histo))
233 :<|> Summary "Pie Chart update"
234 :> QueryParam "list" ListId
235 :> QueryParamR "ngramsType" TabType
236 :> QueryParam "limit" Int
238 :<|> "hash" :> Summary "Pie Hash"
239 :> QueryParam "list" ListId
240 :> QueryParamR "ngramsType" TabType
243 pieApi :: NodeId -> GargServer PieApi
244 pieApi id' = getPie id'
248 getPie :: FlowCmdM env err m
254 -> m (HashedResponse (ChartMetrics Histo))
255 getPie cId _start _end maybeListId tabType = do
256 listId <- case maybeListId of
258 Nothing -> defaultList cId
259 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
260 let HyperdataList { _hl_pie = pieMap } = node ^. node_hyperdata
261 mChart = Map.lookup tabType pieMap
263 chart <- case mChart of
264 Just chart -> pure chart
266 updatePie' cId maybeListId tabType Nothing
268 pure $ constructHashedResponse chart
270 updatePie :: FlowCmdM env err m =>
276 updatePie cId maybeListId tabType maybeLimit = do
277 printDebug "[updatePie] cId" cId
278 printDebug "[updatePie] maybeListId" maybeListId
279 printDebug "[updatePie] tabType" tabType
280 printDebug "[updatePie] maybeLimit" maybeLimit
281 _ <- updatePie' cId maybeListId tabType maybeLimit
284 updatePie' :: FlowCmdM env err m =>
289 -> m (ChartMetrics Histo)
290 updatePie' cId maybeListId tabType _maybeLimit = do
291 listId <- case maybeListId of
293 Nothing -> defaultList cId
294 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
295 let hl = node ^. node_hyperdata
296 pieMap = hl ^. hl_pie
298 p <- chartData cId (ngramsTypeFromTabType tabType) MapTerm
299 _ <- updateHyperdata listId $ hl { _hl_pie = Map.insert tabType (ChartMetrics p) pieMap }
301 pure $ ChartMetrics p
303 getPieHash :: FlowCmdM env err m =>
308 getPieHash cId maybeListId tabType = do
309 hash <$> getPie cId Nothing Nothing maybeListId tabType
311 -------------------------------------------------------------
312 -- | Tree metrics API
314 type TreeApi = Summary " Tree API"
315 :> QueryParam "from" UTCTime
316 :> QueryParam "to" UTCTime
317 :> QueryParam "list" ListId
318 :> QueryParamR "ngramsType" TabType
319 :> QueryParamR "listType" ListType
320 :> Get '[JSON] (HashedResponse (ChartMetrics [MyTree]))
321 :<|> Summary "Tree Chart update"
322 :> QueryParam "list" ListId
323 :> QueryParamR "ngramsType" TabType
324 :> QueryParamR "listType" ListType
328 :> QueryParam "list" ListId
329 :> QueryParamR "ngramsType" TabType
330 :> QueryParamR "listType" ListType
333 -- Depending on the Type of the Node, we could post
334 -- New documents for a corpus
335 -- New map list terms
336 -- :<|> "process" :> MultipartForm MultipartData :> Post '[JSON] Text
338 treeApi :: NodeId -> GargServer TreeApi
339 treeApi id' = getTree id'
343 getTree :: FlowCmdM env err m
350 -> m (HashedResponse (ChartMetrics [MyTree]))
351 getTree cId _start _end maybeListId tabType listType = do
352 listId <- case maybeListId of
354 Nothing -> defaultList cId
356 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
357 let HyperdataList { _hl_tree = treeMap } = node ^. node_hyperdata
358 mChart = Map.lookup tabType treeMap
360 chart <- case mChart of
361 Just chart -> pure chart
363 updateTree' cId maybeListId tabType listType
365 pure $ constructHashedResponse chart
367 updateTree :: FlowCmdM env err m =>
373 updateTree cId maybeListId tabType listType = do
374 printDebug "[updateTree] cId" cId
375 printDebug "[updateTree] maybeListId" maybeListId
376 printDebug "[updateTree] tabType" tabType
377 printDebug "[updateTree] listType" listType
378 _ <- updateTree' cId maybeListId tabType listType
381 updateTree' :: FlowCmdM env err m =>
386 -> m (ChartMetrics [MyTree])
387 updateTree' cId maybeListId tabType listType = do
388 listId <- case maybeListId of
390 Nothing -> defaultList cId
392 node <- getNodeWith listId (Proxy :: Proxy HyperdataList)
393 let hl = node ^. node_hyperdata
394 treeMap = hl ^. hl_tree
395 t <- treeData cId (ngramsTypeFromTabType tabType) listType
396 _ <- updateHyperdata listId $ hl { _hl_tree = Map.insert tabType (ChartMetrics t) treeMap }
398 pure $ ChartMetrics t
400 getTreeHash :: FlowCmdM env err m =>
406 getTreeHash cId maybeListId tabType listType = do
407 hash <$> getTree cId Nothing Nothing maybeListId tabType listType