[FIX] mime files for a dependency (servant-static).
[gargantext.git] / src / Gargantext / API.hs
index 5fab52d073682f70a598bfa613998d8c035b6612..27a932c79325196a633a45fbca0745a2a5bea53e 100644 (file)
@@ -20,15 +20,17 @@ Thanks @yannEsposito for this.
 
 {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
 
-{-# LANGUAGE DataKinds                   #-}
-{-# LANGUAGE DeriveGeneric               #-}
-{-# LANGUAGE FlexibleInstances           #-}
-{-# LANGUAGE OverloadedStrings           #-}
-{-# LANGUAGE TemplateHaskell             #-}
-{-# LANGUAGE TypeOperators               #-}
-{-# LANGUAGE KindSignatures              #-}
-{-# LANGUAGE TypeFamilies                #-}
-{-# LANGUAGE UndecidableInstances        #-}
+
+{-# LANGUAGE NoImplicitPrelude    #-}
+{-# LANGUAGE DataKinds            #-}
+{-# LANGUAGE DeriveGeneric        #-}
+{-# LANGUAGE FlexibleInstances    #-}
+{-# LANGUAGE OverloadedStrings    #-}
+{-# LANGUAGE TemplateHaskell      #-}
+{-# LANGUAGE TypeOperators        #-}
+{-# LANGUAGE KindSignatures       #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE UndecidableInstances #-}
 
 ---------------------------------------------------------------------
 module Gargantext.API
@@ -36,7 +38,7 @@ module Gargantext.API
 ---------------------------------------------------------------------
 import           Gargantext.Prelude
 
-import           System.IO (FilePath, print)
+import           System.IO (FilePath)
 
 import           GHC.Generics (D1, Meta (..), Rep)
 import           GHC.TypeLits (AppendSymbol, Symbol)
@@ -45,16 +47,16 @@ import           Control.Lens
 import           Data.Aeson.Encode.Pretty (encodePretty)
 import qualified Data.ByteString.Lazy.Char8 as BL8
 import           Data.Swagger
-import           Data.Text (Text, pack)
+import           Data.Text (Text)
+import qualified Data.Text.IO as T
 --import qualified Data.Set as Set
 
-import           Database.PostgreSQL.Simple (Connection, connect)
-
 import           Network.Wai
-import           Network.Wai.Handler.Warp
+import           Network.Wai.Handler.Warp hiding (defaultSettings)
 
 import           Servant
 import           Servant.Mock (mock)
+import           Servant.Job.Server (WithCallbacks)
 import           Servant.Swagger
 import           Servant.Swagger.UI
 -- import Servant.API.Stream
@@ -67,11 +69,11 @@ import Gargantext.API.Node ( Roots    , roots
                            , NodesAPI , nodesAPI
                            )
 import Gargantext.API.Count ( CountAPI, count, Query)
-import Gargantext.Database.Utils (databaseParameters)
+import Gargantext.API.Orchestrator
+import Gargantext.API.Orchestrator.Types
 
 ---------------------------------------------------------------------
 
-
 import GHC.Base (Applicative)
 -- import Control.Lens
 
@@ -83,15 +85,13 @@ import Network.Wai (Request, requestHeaders)
 --import qualified Network.Wai.Handler.Warp as Warp
 import Network.Wai.Middleware.Cors
 
--- import Network.Wai.Middleware.RequestLogger
+import Network.Wai.Middleware.RequestLogger
 -- import qualified Network.Wai.Middleware.RequestLogger as RequestLogger
 
 import Network.HTTP.Types hiding (Query)
 
 
--- import Gargantext.API.Settings
-
-data FireWall = FireWall { unFireWall :: Bool }
+import Gargantext.API.Settings
 
 fireWall :: Applicative f => Request -> FireWall -> f Bool
 fireWall req fw = do
@@ -101,23 +101,27 @@ fireWall req fw = do
     let hostOk   = Just (encodeUtf8 "localhost:3000")
     let originOk = Just (encodeUtf8 "http://localhost:8008")
 
-    if origin == originOk && host == hostOk || unFireWall fw
+    if  origin == originOk
+       && host == hostOk
+       || (not $ unFireWall fw)
+       
        then pure True
        else pure False
 
 
--- makeApp :: Env -> IO (Warp.Settings, Application)
-makeApp :: FireWall -> IO Application
-makeApp fw = do
+-- makeMockApp :: Env -> IO (Warp.Settings, Application)
+makeMockApp :: MockEnv -> IO Application
+makeMockApp env = do
     let serverApp = appMock
 
     -- logWare <- mkRequestLogger def { destination = RequestLogger.Logger $ env^.logger }
-
+    --logWare <- mkRequestLogger def { destination = RequestLogger.Logger "/tmp/logs.txt" }
     let checkOriginAndHost app req resp = do
-            blocking <- fireWall req fw
+            blocking <- fireWall req (env ^. menv_firewall)
             case blocking  of
                 True  -> app req resp
-                False -> resp ( responseLBS status401 [] "Invalid Origin or Host header" )
+                False -> resp ( responseLBS status401 [] 
+                              "Invalid Origin or Host header")
         
     let corsMiddleware = cors $ \_ -> Just CorsResourcePolicy
 --          { corsOrigins        = Just ([env^.settings.allowedOrigin], False)
@@ -136,12 +140,44 @@ makeApp fw = do
     --          $ Warp.defaultSettings
     
     --pure (warpS, logWare $ checkOriginAndHost $ corsMiddleware $ serverApp)
-    pure $ checkOriginAndHost $ corsMiddleware $ serverApp
+    pure $ logStdoutDev $ checkOriginAndHost $ corsMiddleware $ serverApp
 
 
+--
+makeDevApp :: Env -> IO Application
+makeDevApp env = do
+    serverApp <- makeApp env
+
+    -- logWare <- mkRequestLogger def { destination = RequestLogger.Logger $ env^.logger }
+    --logWare <- mkRequestLogger def { destination = RequestLogger.Logger "/tmp/logs.txt" }
+--    let checkOriginAndHost app req resp = do
+--            blocking <- fireWall req (env ^. menv_firewall)
+--            case blocking  of
+--                True  -> app req resp
+--                False -> resp ( responseLBS status401 [] 
+--                              "Invalid Origin or Host header")
+--        
+    let corsMiddleware = cors $ \_ -> Just CorsResourcePolicy
+--          { corsOrigins        = Just ([env^.settings.allowedOrigin], False)
+            { corsOrigins        = Nothing --  == /*
+            , corsMethods        = [ methodGet   , methodPost   , methodPut
+                                   , methodDelete, methodOptions, methodHead]
+            , corsRequestHeaders = ["authorization", "content-type"]
+            , corsExposedHeaders = Nothing
+            , corsMaxAge         = Just ( 60*60*24 ) -- one day
+            , corsVaryOrigin     = False
+            , corsRequireOrigin  = False
+            , corsIgnoreFailures = False
+            }
+
+    --let warpS = Warp.setPort (8008 :: Int)   -- (env^.settings.appPort)
+    --          $ Warp.defaultSettings
+    
+    --pure (warpS, logWare $ checkOriginAndHost $ corsMiddleware $ serverApp)
+    pure $ logStdoutDev $ corsMiddleware $ serverApp
+
+--
 
----------------------------------------------------------------------
-type PortNumber = Int
 ---------------------------------------------------------------------
 -- | API Global
 
@@ -165,6 +201,8 @@ type GargAPI =  "user"  :> Summary "First user endpoint"
            :<|> "count" :> Summary "Count endpoint"
                         :> ReqBody '[JSON] Query :> CountAPI 
 
+       --    :<|> "scraper" :> WithCallbacks ScraperAPI
+
 -- /mv/<id>/<id>
 -- /merge/<id>/<id>
 -- /rename/<id>
@@ -179,13 +217,18 @@ type API = SwaggerFrontAPI :<|> GargAPI
 
 ---------------------------------------------------------------------
 -- | Server declaration
-server :: Connection -> Server API
-server conn = swaggerFront
-          :<|> roots    conn
-          :<|> nodeAPI  conn
-          :<|> nodeAPI  conn
-          :<|> nodesAPI conn
-          :<|> count
+server :: Env -> IO (Server API)
+server env = do
+  -- orchestrator <- scrapyOrchestrator env
+  pure $ swaggerFront
+     :<|> roots    conn
+     :<|> nodeAPI  conn
+     :<|> nodeAPI  conn
+     :<|> nodesAPI conn
+     :<|> count
+  --   :<|> orchestrator
+  where
+    conn = env ^. env_conn
 
 ---------------------------------------------------------------------
 swaggerFront :: Server SwaggerFrontAPI
@@ -196,8 +239,8 @@ gargMock :: Server GargAPI
 gargMock = mock apiGarg Proxy
 
 ---------------------------------------------------------------------
-app :: Connection -> Application
-app  = serve api . server
+makeApp :: Env -> IO Application
+makeApp = fmap (serve api) . server
 
 appMock :: Application
 appMock = serve api (swaggerFront :<|> gargMock)
@@ -215,7 +258,7 @@ schemaUiServer :: (Server api ~ Handler Swagger)
 schemaUiServer = swaggerSchemaUIServer
 
 
--- Type Familiy for the Documentation
+-- Type Family for the Documentation
 type family TypeName (x :: *) :: Symbol where
     TypeName Int  = "Int"
     TypeName Text = "Text"
@@ -247,30 +290,21 @@ swaggerWriteJSON = BL8.writeFile "swagger.json" (encodePretty swaggerDoc)
 
 portRouteInfo :: PortNumber -> IO ()
 portRouteInfo port = do
-   print (pack "      ----Main Routes-----      ")
-   print      ("http://localhost:" <> show port <> "/index.html")
-   print      ("http://localhost:" <> show port <> "/swagger-ui")
+  T.putStrLn "      ----Main Routes-----      "
+  T.putStrLn $ "http://localhost:" <> toUrlPiece port <> "/index.html"
+  T.putStrLn $ "http://localhost:" <> toUrlPiece port <> "/swagger-ui"
 
 -- | startGargantext takes as parameters port number and Ini file.
 startGargantext :: PortNumber -> FilePath -> IO ()
 startGargantext port file = do
-  
-  param <- databaseParameters file
-  conn  <- connect param
-  
+  env <- newEnv port file
   portRouteInfo port
-  run port (app conn)
+  app <- makeDevApp env
+  run port app
 
 startGargantextMock :: PortNumber -> IO ()
 startGargantextMock port = do
   portRouteInfo port
-
-  application <- makeApp (FireWall False)
-
+  application <- makeMockApp . MockEnv $ FireWall False
   run port application
 
-
-
-
-
-