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