1 {-# LANGUAGE AllowAmbiguousTypes #-}
2 {-# LANGUAGE TypeOperators #-}
3 {-# OPTIONS_GHC -fno-warn-orphans -fno-warn-unused-matches -fno-warn-unused-imports #-}
5 module Gargantext.API.Node.File where
7 import Control.Lens ((^.))
8 import qualified Data.ByteString as BS
9 import qualified Data.ByteString.Lazy as BSL
10 import qualified Data.MIME.Types as DMT
11 import Data.Monoid (mempty)
14 import Data.Text.Encoding
15 import qualified Data.Text.IO as TIO
16 import GHC.Generics (Generic)
17 import qualified Network.HTTP.Media as M
18 import Network.Wai.Application.Static
20 import Servant.API.Raw (Raw)
21 import Servant.Server.Internal
23 import Gargantext.Prelude
24 import qualified Gargantext.Prelude.Utils as GPU
26 import Gargantext.API.Admin.Settings (HasSettings)
27 import Gargantext.API.Prelude
28 import Gargantext.Database.Action.Flow.Types
29 import Gargantext.Database.Admin.Types.Hyperdata.File
30 import Gargantext.Database.Admin.Types.Node
31 import Gargantext.Database.Query.Table.Node (getNodeWith)
32 import Gargantext.Database.Schema.Node (node_hyperdata)
34 data RESPONSE deriving Typeable
36 instance Accept RESPONSE where
37 contentType _ = "text" M.// "*"
39 instance MimeRender RESPONSE BSResponse where
40 mimeRender _ (BSResponse val) = BSL.fromStrict $ val
42 type FileApi = Summary "File download"
44 :> Get '[RESPONSE] (Headers '[Servant.Header "Content-Type" Text] BSResponse)
46 fileApi :: UserId -> NodeId -> GargServer FileApi
47 fileApi uId nId = fileDownload uId nId
49 newtype Contents = Contents BS.ByteString
51 instance GPU.ReadFile Contents where
56 newtype BSResponse = BSResponse BS.ByteString
59 instance ToSchema BSResponse where
60 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy BSResponse)
62 fileDownload :: (HasSettings env, FlowCmdM env err m)
65 -> m (Headers '[Servant.Header "Content-Type" Text] BSResponse)
66 fileDownload uId nId = do
67 printDebug "[fileDownload] uId" uId
68 printDebug "[fileDownload] nId" nId
70 node <- getNodeWith nId (Proxy :: Proxy HyperdataFile)
71 let (HyperdataFile { _hff_name = name'
72 , _hff_path = path }) = node ^. node_hyperdata
74 Contents c <- GPU.readFile $ unpack path
76 let (mMime, _) = DMT.guessType DMT.defaultmtd False $ unpack name'
79 Nothing -> "text/plain"
81 pure $ addHeader (pack mime) $ BSResponse c
85 -- let settings = embeddedSettings [("", encodeUtf8 c)]
87 -- Tagged $ staticApp settings
89 -- let settings = embeddedSettings [("", "hello")]
90 -- Tagged $ staticApp settings