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 module Gargantext.Prelude.Utils
15 import Control.Exception
16 import Control.Lens (view)
17 import Control.Monad.Reader (MonadReader)
18 import Control.Monad.Random.Class (MonadRandom)
19 import Data.Text (Text)
20 import qualified Data.Text as Text
21 import GHC.IO (FilePath)
22 import System.Directory (createDirectoryIfMissing)
23 import qualified System.Directory as SD
24 import System.IO.Error
25 import System.Random (newStdGen)
26 import qualified System.Random.Shuffle as SRS
28 import Gargantext.Prelude.Config
29 import Gargantext.Prelude.Crypto.Hash
30 import Gargantext.Database.Prelude (HasConfig(..))
31 import Gargantext.Database.Admin.Types.Node (NodeId, NodeType)
32 import Gargantext.Prelude
34 --------------------------------------------------------------------------
35 shuffle :: MonadRandom m => [a] -> m [a]
36 shuffle ns = SRS.shuffleM ns
38 --------------------------------------------------------------------------
39 data NodeToHash = NodeToHash { nodeType :: NodeType
43 type FolderPath = FilePath
44 type FileName = FilePath
46 -- | toPath example of use:
47 -- toPath 2 "gargantexthello"
48 -- ("ga/rg","antexthello")
50 -- toPath 3 "gargantexthello"
51 -- ("gar/gan","texthello")
54 toPath :: Int -> Text -> (FolderPath, FileName)
55 toPath n x = (Text.unpack $ Text.intercalate "/" [x1,x2], Text.unpack xs)
57 (x1,x') = Text.splitAt n x
58 (x2,xs) = Text.splitAt n x'
60 class SaveFile a where
61 saveFile' :: FilePath -> a -> IO ()
63 class ReadFile a where
64 readFile' :: FilePath -> IO a
67 folderFilePath :: (MonadReader env m, MonadBase IO m) => m (FolderPath, FileName)
69 (foldPath, fileName) <- liftBase $ (toPath 3) . hash . show <$> newStdGen
71 pure (foldPath, fileName)
74 writeFile :: (MonadReader env m, MonadBase IO m, HasConfig env, SaveFile a)
77 dataPath <- view $ hasConfig . gc_datafilepath
79 (foldPath, fileName) <- folderFilePath
81 let filePath = foldPath <> "/" <> fileName
82 dataFoldPath = dataPath <> "/" <> foldPath
83 dataFileName = dataPath <> "/" <> filePath
85 _ <- liftBase $ createDirectoryIfMissing True dataFoldPath
86 _ <- liftBase $ saveFile' dataFileName a
91 readFile :: (MonadReader env m, MonadBase IO m, HasConfig env, ReadFile a)
94 dataPath <- view $ hasConfig . gc_datafilepath
95 liftBase $ readFile' $ dataPath <> "/" <> fp
97 removeFile :: (MonadReader env m, MonadBase IO m, HasConfig env)
100 dataPath <- view $ hasConfig . gc_datafilepath
101 liftBase $ SD.removeFile (dataPath <> "/" <> fp) `catch` handleExists
104 | isDoesNotExistError e = return ()
105 | otherwise = throwIO e