2 Module : Gargantext.Prelude.Utils
3 Description : Useful Tools near Prelude of the project
4 Copyright : (c) CNRS, 2017-Present
5 License : AGPL + CECILL v3
6 Maintainer : team@gargantext.org
7 Stability : experimental
12 {-# LANGUAGE NoImplicitPrelude #-}
13 {-# LANGUAGE OverloadedStrings #-}
15 module Gargantext.Prelude.Utils
18 import Control.Lens (view)
19 import Control.Monad.Reader (MonadReader)
20 import Control.Monad.IO.Class (MonadIO, liftIO)
21 import Control.Monad.Random.Class (MonadRandom)
22 import Data.Text (Text)
23 import Control.Monad.Reader (ask)
24 import GHC.IO (FilePath)
25 import Gargantext.Prelude
26 import Gargantext.API.Settings
27 import System.Random (newStdGen)
28 import qualified System.Random.Shuffle as SRS
29 import System.Directory (createDirectoryIfMissing)
30 import qualified Data.ByteString.Lazy.Char8 as Char
31 import qualified Data.Digest.Pure.SHA as SHA (sha256, showDigest)
32 import qualified Data.Text as Text
33 import Gargantext.Database.Types.Node (NodeId, NodeType)
34 import Data.ByteString (ByteString)
35 import Crypto.Argon2 as Crypto
37 import Data.ByteString.Base64.URL as URL
39 shuffle :: MonadRandom m => [a] -> m [a]
40 shuffle ns = SRS.shuffleM ns
42 type FolderPath = FilePath
43 type FileName = FilePath
52 data NodeToHash = NodeToHash { nodeType :: NodeType
56 secret_key :: ByteString
57 secret_key = "WRV5ymit8s~ge6%08dLR7Q!gBcpb1MY%7e67db2206"
59 type SecretKey = ByteString
61 hashNode :: SecretKey -> NodeToHash -> ByteString
62 hashNode sk (NodeToHash nt ni) = case hashResult of
63 Left e -> panic (cs $ show e)
64 Right h -> URL.encode h
66 hashResult = Crypto.hash Crypto.defaultHashOptions
68 (cs $ show nt <> show ni)
71 toPath :: Int -> Text -> (FolderPath,FileName)
72 toPath n x = (Text.unpack $ Text.intercalate "/" [x1,x2], Text.unpack xs)
74 (x1,x') = Text.splitAt n x
75 (x2,xs) = Text.splitAt n x'
77 class SaveFile a where
78 saveFile' :: FilePath -> a -> IO ()
80 class ReadFile a where
81 readFile' :: FilePath -> IO a
84 writeFile :: (MonadReader env m, MonadIO m, HasSettings env, SaveFile a)
87 dataPath <- view (settings . fileFolder) <$> ask
88 (fp,fn) <- liftIO $ (toPath 3) . sha . Text.pack . show <$> newStdGen
90 let foldPath = dataPath <> "/" <> fp
91 filePath = foldPath <> "/" <> fn
93 _ <- liftIO $ createDirectoryIfMissing True foldPath
94 _ <- liftIO $ saveFile' filePath a
99 readFile :: (MonadReader env m, MonadIO m, HasSettings env, ReadFile a)
102 dataPath <- view (settings . fileFolder) <$> ask
103 liftIO $ readFile' $ dataPath <> "/" <> fp