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