gonito/Handler/Shared.hs

108 lines
3.1 KiB
Haskell
Raw Normal View History

2015-08-29 18:24:01 +02:00
{-# LANGUAGE RecordWildCards #-}
module Handler.Shared where
import Import
import Control.Concurrent (forkIO, threadDelay)
import Control.Concurrent.STM
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
2015-08-29 22:19:44 +02:00
import Network.URI
import qualified Data.Text as T
import Database.Persist.Sql (ConnectionPool, runSqlPool)
2015-08-29 18:24:01 +02:00
atom = Control.Concurrent.STM.atomically
type Channel = TChan (Maybe Text)
runViewProgress :: (Channel -> IO ()) -> Handler TypedContent
runViewProgress action = do
App {..} <- getYesod
(jobId, chan) <- liftIO $ atom $ do
jobId <- readTVar nextJob
writeTVar nextJob $! jobId + 1
chan <- newBroadcastTChan
m <- readTVar jobs
writeTVar jobs $ IntMap.insert jobId chan m
return (jobId, chan)
liftIO $ forkIO $ do
2015-08-29 22:19:44 +02:00
threadDelay 1000000
2015-08-29 18:24:01 +02:00
action chan
atom $ do
writeTChan chan $ Just "All done\n"
writeTChan chan Nothing
m <- readTVar jobs
writeTVar jobs $ IntMap.delete jobId m
redirect $ ViewProgressR jobId
msg :: Channel -> Text -> IO ()
2015-08-29 22:19:44 +02:00
msg chan m = atom $ writeTChan chan $ Just (m ++ "\n")
err :: Channel -> Text -> IO ()
err = msg
2015-08-29 18:24:01 +02:00
doSomething :: Channel -> IO ()
doSomething chan = do
2015-08-29 22:19:44 +02:00
msg chan "Did something"
2015-08-29 18:24:01 +02:00
threadDelay 1000000
2015-08-29 22:19:44 +02:00
msg chan "Did something else"
2015-08-29 18:24:01 +02:00
threadDelay 1000000
2015-08-29 22:19:44 +02:00
doRepoCloning :: Text -> Text -> Channel -> IO ()
doRepoCloning url branch chan = do
msg chan "Did something"
_ <- cloneRepo url branch chan
return ()
validGitProtocols :: [String]
validGitProtocols = ["git", "http", "https", "ssh"]
validGitProtocolsAsText :: Text
validGitProtocolsAsText = T.pack $ intercalate ", " $ map (++"://") validGitProtocols
cloneRepo :: Text -> Text -> Channel -> IO (Maybe Repo)
cloneRepo url branch chan = do
let maybeRepo = Nothing
case maybeRepo of
Just _ -> do
err chan "Repo already there"
return Nothing
Nothing -> do
msg chan $ concat ["Preparing to clone repo ", url]
if checkRepoUrl url
then
return Nothing
else do
err chan $ concat ["Wrong URL to a Git repo (note that one of the following protocols must be specified: ", validGitProtocolsAsText]
return Nothing
checkRepoUrl :: Text -> Bool
checkRepoUrl url = case parsedURI of
Just uri -> (uriScheme uri) `elem` (map (++":") validGitProtocols)
Nothing -> False
where parsedURI = parseURI $ T.unpack url
2015-08-29 18:24:01 +02:00
getViewProgressR :: Int -> Handler TypedContent
getViewProgressR jobId = do
App {..} <- getYesod
mchan <- liftIO $ atom $ do
m <- readTVar jobs
case IntMap.lookup jobId m of
Nothing -> return Nothing
Just chan -> fmap Just $ dupTChan chan
case mchan of
Nothing -> notFound
Just chan -> respondSource typePlain $ do
let loop = do
mtext <- liftIO $ atom $ readTChan chan
case mtext of
Nothing -> return ()
Just text -> do
sendChunkText text
sendFlush
loop
loop