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