{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} module Proof.Assistant.RefreshFile where import Data.ByteString (ByteString) import Data.Coerce (coerce) import System.Directory import System.FilePath import Telegram.Bot.API (ChatId (..)) import Proof.Assistant.Helpers import Proof.Assistant.Request import Proof.Assistant.Settings import qualified Data.ByteString.Char8 as BS8 import qualified Data.Text as Text -- | Most interpreters work with files. Therefore, we need to store user input as a file. -- Remember that input could come from different chats, so we need to store input separately. -- Unless directory specified, temporary directory will be used to store the files. refreshTmpFile :: ExternalInterpreterSettings -> InterpreterRequest -> Maybe FilePath -> IO (FilePath, FilePath) refreshTmpFile settings ir@InterpreterRequest{interpreterRequestMessage} mDir = do tmpDir <- maybe getTemporaryDirectory pure mDir let tmpFilepath = getTempFilePath settings ir tmpDir createFile = do BS8.writeFile tmpFilepath $ dropSubCommand interpreterRequestMessage pure (tmpDir, tmpFilepath) exist <- doesFileExist tmpFilepath if (not exist) then createFile else removeFile tmpFilepath >> createFile -- | Make absolute filepath based on settings, request and directory. getTempFilePath :: ExternalInterpreterSettings -> InterpreterRequest -> FilePath -> FilePath getTempFilePath ExternalInterpreterSettings{tempFilePrefix, fileExtension} InterpreterRequest{interpreterRequestTelegramChatId} dir = let tmpFilepath = dir tempFilePrefix <> chatIdToString interpreterRequestTelegramChatId <.> fileExtension in tmpFilepath -- | Helper to convert Telegram ChatId to 'String' (for filepath). chatIdToString :: ChatId -> String chatIdToString = show . coerce @_ @Integer -- | Helper to cut filepath from the output. validate :: FilePath -> ByteString -> ByteString validate path bs = textToBS (Text.replace textPath "" txt) where textPath = Text.pack path txt = bsToText bs