]> Git — Sourcephile - gargantext.git/blob - src/Gargantext/API/Public.hs
Merge branch 'dev' into dev-fix-node-update-endpoint
[gargantext.git] / src / Gargantext / API / Public.hs
1 {-|
2 Module : Gargantext.API.Public
3 Description :
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
8 Portability : POSIX
9
10 -}
11
12 {-# LANGUAGE TypeOperators #-}
13 {-# LANGUAGE ScopedTypeVariables #-}
14
15 module Gargantext.API.Public
16 where
17
18 import Data.Set (Set)
19 import Control.Lens ((^?), (^.), _Just)
20 import Data.Maybe (catMaybes)
21 import Data.Text (Text)
22 import Data.List (replicate, null)
23 import Data.Aeson
24 import Data.Swagger
25 import GHC.Generics (Generic)
26 import Servant
27 import Test.QuickCheck (elements)
28 import Test.QuickCheck.Arbitrary
29
30 import qualified Data.List as List
31 import qualified Data.Map as Map
32 import qualified Data.Set as Set
33
34 import Gargantext.API.Prelude
35 import Gargantext.API.Node.File
36 import Gargantext.Database.Query.Table.Node.Error (HasNodeError(..))
37 import Gargantext.Database.Prelude
38 import Gargantext.Database.Admin.Types.Hyperdata
39 import Gargantext.Database.Admin.Types.Hyperdata.CorpusField
40 import Gargantext.Database.Admin.Types.Node
41 import Gargantext.Database.Query.Table.NodeNode (selectPublicNodes)
42 import Gargantext.Core.Utils.DateUtils (utc2year)
43 import Gargantext.Database.Schema.Node -- (NodePoly(..))
44 import Gargantext.Prelude
45 import qualified Gargantext.Utils.Aeson as GUA
46
47 ------------------------------------------------------------------------
48 type API = API_Home
49 :<|> API_Node
50
51 api :: Text -> GargServer API
52 api baseUrl = (api_home baseUrl)
53 :<|> api_node
54
55 -------------------------------------------------------------------------
56 type API_Home = Summary " Public Home API"
57 :> Get '[JSON] [PublicData]
58
59 api_home :: Text -> GargServer API_Home
60 api_home baseUrl = catMaybes
61 <$> map (toPublicData baseUrl)
62 <$> filterPublicDatas
63 <$> selectPublic
64
65 -------------------------------------------------------------------------
66 type API_Node = Summary " Public Node API"
67 :> Capture "node" NodeId
68 :> "file" :> FileApi
69
70 api_node :: NodeId -> GargServer FileApi
71 api_node nId = do
72 pubNodes <- publicNodes
73 -- TODO optimize with SQL
74 case Set.member nId pubNodes of
75 False -> panic "Not allowed" -- TODO throwErr
76 True -> fileApi 0 nId
77
78 -------------------------------------------------------------------------
79
80
81 selectPublic :: HasNodeError err
82 => Cmd err [( Node HyperdataFolder, Maybe Int)]
83 selectPublic = selectPublicNodes
84
85 -- For tests only
86 -- pure $ replicate 6 defaultPublicData
87
88 filterPublicDatas :: [(Node HyperdataFolder, Maybe Int)]
89 -> [(Node HyperdataFolder, [NodeId])]
90 filterPublicDatas datas =
91 map (\(n,mi) ->
92 let mi' = NodeId <$> mi in
93 ( _node_id n, (n, maybe [] (:[]) mi' ))
94 ) datas
95 & Map.fromListWith (\(n1,i1) (_n2,i2) -> (n1, i1 <> i2))
96 & Map.filter (not . null . snd)
97 & Map.elems
98
99 publicNodes :: HasNodeError err
100 => Cmd err (Set NodeId)
101 publicNodes = do
102 candidates <- filterPublicDatas <$> selectPublicNodes
103 pure $ Set.fromList
104 $ List.concat
105 $ map (\(n, ns) -> (_node_id n) : ns) candidates
106
107
108 -- http://localhost:8008/api/v1.0/node/23543/file/download<Paste>
109 -- http://localhost:8000/images/Gargantextuel-212x300.jpg
110 toPublicData :: Text -> (Node HyperdataFolder, [NodeId]) -> Maybe PublicData
111 toPublicData base (n , mn) = PublicData <$> (hd ^? (_Just . hf_data . cf_title))
112 <*> (hd ^? (_Just . hf_data . cf_desc ))
113 <*> (Just $ url' mn) -- "images/Gargantextuel-212x300.jpg"
114 <*> (Just $ url' mn)
115 <*> Just (cs $ show $ utc2year (n^.node_date))
116 <*> (hd ^? (_Just . hf_data . cf_query))
117 <*> (hd ^? (_Just . hf_data . cf_authors))
118 where
119 hd = head
120 $ filter (\(HyperdataField cd _ _) -> cd == JSON)
121 $ n^. (node_hyperdata . hc_fields)
122 url' :: [NodeId] -> Text
123 url' mn' = base
124 <> "/public/"
125 <> (cs $ show $ (maybe 0 unNodeId $ head mn'))
126 <> "/file/download"
127
128
129 data PublicData = PublicData
130 { title :: Text
131 , abstract :: Text
132 , img :: Text
133 , url :: Text
134 , date :: Text
135 , database :: Text
136 , author :: Text
137 } | NoData { nodata:: Text}
138 deriving (Generic)
139
140
141 instance FromJSON PublicData where
142 parseJSON = genericParseJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
143
144 instance ToJSON PublicData where
145 toJSON = genericToJSON (defaultOptions { sumEncoding = GUA.defaultTaggedObject })
146
147 instance ToSchema PublicData
148 instance Arbitrary PublicData where
149 arbitrary = elements
150 $ replicate 6 defaultPublicData
151
152 defaultPublicData :: PublicData
153 defaultPublicData =
154 PublicData "Title"
155 (foldl (<>) "" $ replicate 100 "abstract ")
156 "images/Gargantextuel-212x300.jpg"
157 "https://.."
158 "YY/MM/DD"
159 "database"
160 "Author"
161
162
163
164