mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-15 20:00:06 +00:00
40 lines
1.4 KiB
Haskell
40 lines
1.4 KiB
Haskell
{-# LANGUAGE DuplicateRecordFields #-}
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
module Simplex.Chat.Files
|
|
( SafeFileName,
|
|
safeFileName,
|
|
uniqueCombine,
|
|
getChatTempDirectory,
|
|
getDefaultFilesFolder,
|
|
)
|
|
where
|
|
|
|
import Simplex.Chat.Controller
|
|
import Simplex.Messaging.Util (ifM)
|
|
import System.FilePath (combine, makeValid, splitExtensions, takeFileName)
|
|
import UnliftIO.Directory (doesDirectoryExist, doesFileExist, getHomeDirectory, getTemporaryDirectory)
|
|
|
|
-- | A file name with directory components removed, so combining it with a folder cannot escape that folder.
|
|
newtype SafeFileName = SafeFileName String
|
|
|
|
safeFileName :: String -> SafeFileName
|
|
safeFileName = SafeFileName . makeValid . takeFileName
|
|
|
|
uniqueCombine :: FilePath -> SafeFileName -> IO FilePath
|
|
uniqueCombine fPath (SafeFileName fName) = tryCombine (0 :: Int)
|
|
where
|
|
tryCombine n =
|
|
let (name, ext) = splitExtensions fName
|
|
suffix = if n == 0 then "" else "_" <> show n
|
|
f = fPath `combine` (name <> suffix <> ext)
|
|
in ifM (doesFileExist f) (tryCombine $ n + 1) (pure f)
|
|
|
|
getChatTempDirectory :: CM' FilePath
|
|
getChatTempDirectory = chatReadVar' tempDirectory >>= maybe getTemporaryDirectory pure
|
|
|
|
getDefaultFilesFolder :: CM' FilePath
|
|
getDefaultFilesFolder = do
|
|
dir <- (`combine` "Downloads") <$> getHomeDirectory
|
|
ifM (doesDirectoryExist dir) (pure dir) getChatTempDirectory
|