Alusta Git-tietovaranto automaattisesti

This commit is contained in:
Saku Laesvuori 2025-04-16 15:15:08 +03:00
parent 33c2269671
commit b2da3220c9
Signed by: slaesvuo
GPG Key ID: 257D284A2A1D3A32
4 changed files with 25 additions and 12 deletions

View File

@ -11,6 +11,7 @@ import Control.Exception (throwIO)
import Control.Monad (void, forever) import Control.Monad (void, forever)
import Data.Acid (AcidState(..), openLocalState, createCheckpoint, createArchive) import Data.Acid (AcidState(..), openLocalState, createCheckpoint, createArchive)
import Data.Acid.Remote (skipAuthenticationCheck, acidServerSockAddr, openRemoteStateSockAddr, skipAuthenticationPerform) import Data.Acid.Remote (skipAuthenticationCheck, acidServerSockAddr, openRemoteStateSockAddr, skipAuthenticationPerform)
import Data.FileStore (gitFileStore, initialize)
import Data.IMF (Mailbox(..), parse, mailbox) import Data.IMF (Mailbox(..), parse, mailbox)
import Data.MIME.Charset (defaultCharsets) import Data.MIME.Charset (defaultCharsets)
import Data.Text.Encoding (encodeUtf8) import Data.Text.Encoding (encodeUtf8)
@ -33,15 +34,16 @@ import TiedoteMD.State
import TiedoteMD.Types import TiedoteMD.Types
import TiedoteMD.Debug import TiedoteMD.Debug
serverMain :: SockAddr -> Mailbox -> FilePath -> FilePath -> Int -> Int -> IO () serverMain :: SockAddr -> Mailbox -> FilePath -> GitOrigin -> FilePath -> Int -> Int -> IO ()
serverMain socket mail repoPath sendmailPath checkpointDelay port = do serverMain socket mail repoPath origin sendmailPath checkpointDelay port = do
initialize $ gitFileStore repoPath
acid <- openLocalState $ emptyState acid <- openLocalState $ emptyState
_ <- forkIO $ acidServerSockAddr skipAuthenticationCheck socket acid _ <- forkIO $ acidServerSockAddr skipAuthenticationCheck socket acid
queueMessages acid queueMessages acid
_ <- forkIO $ scotty port $ do _ <- forkIO $ scotty port $ do
defaultHandler $ liftAndCatchIO . LT.putStrLn -- Don't return exceptions to clients defaultHandler $ liftAndCatchIO . LT.putStrLn -- Don't return exceptions to clients
post "/" $ liftAndCatchIO $ void $ forkIO $ updateMessages acid repoPath post "/" $ liftAndCatchIO $ void $ forkIO $ updateMessages acid repoPath origin
updateMessages acid repoPath updateMessages acid repoPath origin
_ <- forkIO $ manageQueueingMessages acid _ <- forkIO $ manageQueueingMessages acid
_ <- forkIO $ managePreviews acid mail sendmailPath _ <- forkIO $ managePreviews acid mail sendmailPath
_ <- forkIO $ manageQueue acid mail sendmailPath _ <- forkIO $ manageQueue acid mail sendmailPath
@ -69,7 +71,7 @@ archiveMain socket = do
createArchive acid createArchive acid
data Config = Config { socketPath :: FilePath, mail :: Mailbox, sendmailCommand :: String, runMode :: RunMode } deriving Show data Config = Config { socketPath :: FilePath, mail :: Mailbox, sendmailCommand :: String, runMode :: RunMode } deriving Show
data RunMode = Server { repoPath :: FilePath, portNumber :: Int, checkpointDelay :: Int } | Receive | Print | Archive deriving Show data RunMode = Server { repoPath :: FilePath, origin :: GitOrigin, portNumber :: Int, checkpointDelay :: Int } | Receive | Print | Archive deriving Show
config :: Maybe Mailbox -> Parser Config config :: Maybe Mailbox -> Parser Config
config mail = Config config mail = Config
@ -84,6 +86,9 @@ config mail = Config
serverCommand :: Parser RunMode serverCommand :: Parser RunMode
serverCommand = Server serverCommand = Server
<$> strOption (long "repository" <> short 'r' <> metavar "DIRECTORY" <> value "/var/lib/tiedote.md/git-repo" <> showDefault <> help "Path to git repository") <$> strOption (long "repository" <> short 'r' <> metavar "DIRECTORY" <> value "/var/lib/tiedote.md/git-repo" <> showDefault <> help "Path to git repository")
<*> (GitOrigin
<$> strOption (long "remote-url" <> short 'u' <> metavar "URL" <> help "Url to fetch updated messages from")
<*> optional (strOption (long "remote-branch" <> short 'b' <> metavar "NAME" <> help "Branch to fetch updated messages from")))
<*> option auto (long "port" <> short 'p' <> metavar "PORT" <> value 3000 <> showDefault <> help "TCP port number to listen on for webhook notifications") <*> option auto (long "port" <> short 'p' <> metavar "PORT" <> value 3000 <> showDefault <> help "TCP port number to listen on for webhook notifications")
<*> option auto (long "checkpoint-delay" <> metavar "MINUTES" <> value (60 * 24 * 7) <> help "Number of minutes to wait between creating snapshots.") <*> option auto (long "checkpoint-delay" <> metavar "MINUTES" <> value (60 * 24 * 7) <> help "Number of minutes to wait between creating snapshots.")
@ -111,4 +116,4 @@ main = do
Config {runMode = Receive, ..} -> clientMain (SockAddrUnix socketPath) mail sendmailPath Config {runMode = Receive, ..} -> clientMain (SockAddrUnix socketPath) mail sendmailPath
Config {runMode = Print, ..} -> printStateMain (SockAddrUnix socketPath) Config {runMode = Print, ..} -> printStateMain (SockAddrUnix socketPath)
Config {runMode = Archive, ..} -> archiveMain (SockAddrUnix socketPath) Config {runMode = Archive, ..} -> archiveMain (SockAddrUnix socketPath)
Config {runMode = Server {..}, ..} -> serverMain (SockAddrUnix socketPath) mail repoPath sendmailPath checkpointDelay portNumber Config {runMode = Server {..}, ..} -> serverMain (SockAddrUnix socketPath) mail repoPath origin sendmailPath checkpointDelay portNumber

View File

@ -1,4 +1,5 @@
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE NamedFieldPuns #-}
module TiedoteMD.Git where module TiedoteMD.Git where
@ -9,6 +10,7 @@ import Control.Exception (throwIO)
import Control.Monad (liftM2, unless) import Control.Monad (liftM2, unless)
import Data.ByteString.Lazy.UTF8 (toString) import Data.ByteString.Lazy.UTF8 (toString)
import Data.FileStore.Types (FileStoreError(..)) import Data.FileStore.Types (FileStoreError(..))
import Data.List (singleton)
import System.Directory (getTemporaryDirectory, removeFile) import System.Directory (getTemporaryDirectory, removeFile)
import System.Environment (getEnvironment) import System.Environment (getEnvironment)
import System.Exit (ExitCode(..)) import System.Exit (ExitCode(..))
@ -19,9 +21,11 @@ import qualified Control.Exception as E
import qualified Data.ByteString as S import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as B import qualified Data.ByteString.Lazy as B
gitPull :: FilePath -> IO () import TiedoteMD.Types (GitOrigin(..))
gitPull repo = do
(exit, err, _) <- runGitCommand repo "fetch" [] gitPull :: FilePath -> GitOrigin -> IO ()
gitPull repo GitOrigin {url, branch} = do
(exit, err, _) <- runGitCommand repo "fetch" (url : (maybe [] singleton branch))
unless (exit == ExitSuccess) $ throwIO $ UnknownError $ "git-fetch failed: " <> err unless (exit == ExitSuccess) $ throwIO $ UnknownError $ "git-fetch failed: " <> err
(exit', err', _) <- runGitCommand repo "reset" ["--hard","FETCH_HEAD"] (exit', err', _) <- runGitCommand repo "reset" ["--hard","FETCH_HEAD"]
unless (exit' == ExitSuccess) $ throwIO $ UnknownError $ "git-reset failed: " <> err' unless (exit' == ExitSuccess) $ throwIO $ UnknownError $ "git-reset failed: " <> err'

View File

@ -52,9 +52,9 @@ import TiedoteMD.State
import TiedoteMD.Templates import TiedoteMD.Templates
import TiedoteMD.Types import TiedoteMD.Types
updateMessages :: AcidState State -> FilePath -> IO () updateMessages :: AcidState State -> FilePath -> GitOrigin -> IO ()
updateMessages acid repoPath = updateMessages acid repoPath origin =
gitPull repoPath >> readMessageFiles (gitFileStore repoPath) >>= update acid . UpdateState gitPull repoPath origin >> readMessageFiles (gitFileStore repoPath) >>= update acid . UpdateState
readMessageFiles :: FileStore -> IO [Message] readMessageFiles :: FileStore -> IO [Message]
readMessageFiles store = do readMessageFiles store = do

View File

@ -7,6 +7,7 @@
module TiedoteMD.Types module TiedoteMD.Types
( Email(..) ( Email(..)
, Error(..) , Error(..)
, GitOrigin(..)
, MailID , MailID
, MediaPart(..) , MediaPart(..)
, Message(..) , Message(..)
@ -141,6 +142,9 @@ messageIDToMailID = MailID . renderMessageID
renderMailID :: MailID -> ByteString renderMailID :: MailID -> ByteString
renderMailID = renderMessageID . mailIDToMessageID renderMailID = renderMessageID . mailIDToMessageID
data GitOrigin = GitOrigin { url :: String, branch :: Maybe String }
deriving (Show)
data Error = PandocError PandocError data Error = PandocError PandocError
| NoMeta Text | NoMeta Text
| InvalidTime Text | InvalidTime Text