1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE DuplicateRecordFields #-}
4 module Gargantext.API.GraphQL.Context where
6 -- TODO Add support for adding FrameWrite comments for a Context
8 import Data.Morpheus.Types
15 import Data.Text (Text, pack)
16 import Data.Time.Format.ISO8601 (iso8601Show)
17 import Gargantext.API.Admin.Types (HasSettings)
18 import Gargantext.API.Prelude (GargM, GargError)
19 import Gargantext.Core.Types.Search (HyperdataRow(..), toHyperdataRow)
20 import Gargantext.Core.Mail.Types (HasMail)
21 import Gargantext.Database.Admin.Types.Hyperdata (HyperdataDocument)
22 import Gargantext.Database.Admin.Types.Node (ContextTitle, NodeId(..), NodeTypeId, UserId, unNodeId)
23 import Gargantext.Database.Prelude (HasConnectionPool, HasConfig)
24 import Gargantext.Database.Query.Table.NodeContext (getNodeContext, getContextsForNgramsTerms, ContextForNgramsTerms(..))
25 import qualified Gargantext.Database.Query.Table.NodeContext as DNC
26 import Gargantext.Database.Schema.NodeContext (NodeContext, NodeContextPoly(..))
27 import Gargantext.Prelude
28 import Gargantext.Prelude.Crypto.Hash (Hash)
29 import GHC.Generics (Generic)
31 data ContextGQL = ContextGQL
33 , c_hash_id :: Maybe Hash
34 , c_typename :: NodeTypeId
36 , c_parent_id :: Maybe Int
37 , c_name :: ContextTitle
38 , c_date :: Text -- TODO UTCTime
39 , c_hyperdata :: Maybe HyperdataRowDocumentGQL
40 , c_score :: Maybe Double
41 , c_category :: Maybe Int
42 } deriving (Generic, GQLType, Show)
44 -- We need this type instead of HyperdataRow(HyperdataRowDocument)
45 -- because the latter is a sum type (of doc and contact) and we return
46 -- docs here only. Without the union type, GraphQL endpoint is simpler.
47 data HyperdataRowDocumentGQL =
48 HyperdataRowDocumentGQL { hrd_abstract :: Text
52 , hrd_institutes :: Text
53 , hrd_language_iso2 :: Text
55 , hrd_publication_date :: Text
56 , hrd_publication_day :: Int
57 , hrd_publication_hour :: Int
58 , hrd_publication_minute :: Int
59 , hrd_publication_month :: Int
60 , hrd_publication_second :: Int
61 , hrd_publication_year :: Int
66 , hrd_uniqIdBdd :: Text
67 } deriving (Generic, GQLType, Show)
69 data NodeContextGQL = NodeContextGQL
72 , nc_context_id :: Int
73 , nc_score :: Maybe Double
74 , nc_category :: Maybe Int
75 } deriving (Generic, GQLType, Show)
77 -- | Arguments to the "context node" query.
78 -- "context_id" is doc id
79 -- "node_id" is it's corpus id
84 } deriving (Generic, GQLType)
86 data ContextsForNgramsArgs
87 = ContextsForNgramsArgs
89 , ngrams_terms :: [Text]
90 } deriving (Generic, GQLType)
92 data NodeContextCategoryMArgs = NodeContextCategoryMArgs
96 } deriving (Generic, GQLType)
98 type GqlM e env = Resolver QUERY e (GargM env GargError)
99 type GqlM' e env a = ResolverM e (GargM env GargError) a
103 -- | Function to resolve context from a query.
105 :: (HasConnectionPool env, HasConfig env, HasMail env)
106 => NodeContextArgs -> GqlM e env [NodeContextGQL]
107 resolveNodeContext NodeContextArgs { context_id, node_id } =
108 dbNodeContext context_id node_id
110 resolveContextsForNgrams
111 :: (HasConnectionPool env, HasConfig env, HasMail env)
112 => ContextsForNgramsArgs -> GqlM e env [ContextGQL]
113 resolveContextsForNgrams ContextsForNgramsArgs { corpus_id, ngrams_terms } =
114 dbContextForNgrams corpus_id ngrams_terms
118 -- | Inner function to fetch the node context DB.
120 :: (HasConnectionPool env, HasConfig env, HasMail env)
121 => Int -> Int -> GqlM e env [NodeContextGQL]
122 dbNodeContext context_id node_id = do
123 -- lift $ printDebug "[dbUsers]" user_id
124 -- user <- getUsersWithId user_id
125 -- hyperdata <- getUserHyperdata user_id
126 -- lift (map toUser <$> zip user hyperdata)
127 c <- lift $ getNodeContext (NodeId context_id) (NodeId node_id)
128 pure $ toNodeContextGQL <$> [c]
131 :: (HasConnectionPool env, HasConfig env, HasMail env)
132 => Int -> [Text] -> GqlM e env [ContextGQL]
133 dbContextForNgrams node_id ngrams_terms = do
134 contextsForNgramsTerms <- lift $ getContextsForNgramsTerms (NodeId node_id) ngrams_terms
135 --lift $ printDebug "[dbContextForNgrams] contextsForNgramsTerms" contextsForNgramsTerms
136 pure $ toContextGQL <$> contextsForNgramsTerms
138 -- Conversion functions
140 toNodeContextGQL :: NodeContext -> NodeContextGQL
141 toNodeContextGQL (NodeContext { _nc_node_id = NodeId nc_node_id
142 , _nc_context_id = NodeId nc_context_id
144 NodeContextGQL { nc_id = _nc_id
147 , nc_score = _nc_score
148 , nc_category = _nc_category }
150 toContextGQL :: ContextForNgramsTerms -> ContextGQL
151 toContextGQL ContextForNgramsTerms { _cfnt_nodeId = c_id
152 , _cfnt_hash = c_hash_id
153 , _cfnt_nodeTypeId = c_typename
154 , _cfnt_userId = c_user_id
155 , _cfnt_parentId = m_c_parent_id
156 , _cfnt_c_title = c_name
157 , _cfnt_date = c_date
158 , _cfnt_hyperdata =hyperdata
159 , _cfnt_score = c_score
160 , _cfnt_category = c_category } =
161 ContextGQL { c_id = unNodeId c_id
162 , c_parent_id = unNodeId <$> m_c_parent_id
163 , c_date = pack $ iso8601Show c_date
164 , c_hyperdata = toHyperdataRowDocumentGQL hyperdata
169 toHyperdataRowDocumentGQL :: HyperdataDocument -> Maybe HyperdataRowDocumentGQL
170 toHyperdataRowDocumentGQL hyperdata =
171 case toHyperdataRow hyperdata of
172 HyperdataRowDocument { .. } ->
173 Just $ HyperdataRowDocumentGQL { hrd_abstract = _hr_abstract
174 , hrd_authors = _hr_authors
177 , hrd_institutes = _hr_institutes
178 , hrd_language_iso2 = _hr_language_iso2
179 , hrd_page = _hr_page
180 , hrd_publication_date = _hr_publication_date
181 , hrd_publication_day = _hr_publication_day
182 , hrd_publication_hour = _hr_publication_hour
183 , hrd_publication_minute = _hr_publication_minute
184 , hrd_publication_month = _hr_publication_month
185 , hrd_publication_second = _hr_publication_second
186 , hrd_publication_year = _hr_publication_year
187 , hrd_source = _hr_source
188 , hrd_title = _hr_title
190 , hrd_uniqId = _hr_uniqId
191 , hrd_uniqIdBdd = _hr_uniqIdBdd
193 HyperdataRowContact { } -> Nothing
195 updateNodeContextCategory :: (HasConnectionPool env, HasConfig env, HasMail env, HasSettings env) =>
196 NodeContextCategoryMArgs -> GqlM' e env [Int]
197 updateNodeContextCategory NodeContextCategoryMArgs { context_id, node_id, category } = do
198 _ <- lift $ DNC.updateNodeContextCategory (NodeId context_id) (NodeId node_id) category