Add challenge healing

This commit is contained in:
Filip Gralinski 2021-02-17 09:31:23 +01:00
parent 7cb2678f11
commit f7d61aa256
6 changed files with 46 additions and 8 deletions

View File

@ -208,6 +208,7 @@ instance Yesod App where
isAuthorized (ArchiveR _) _ = isAdmin isAuthorized (ArchiveR _) _ = isAdmin
isAuthorized (UnarchiveR _) _ = isAdmin isAuthorized (UnarchiveR _) _ = isAdmin
isAuthorized (ChallengeUpdateR _) _ = isAdmin isAuthorized (ChallengeUpdateR _) _ = isAdmin
isAuthorized (HealR _) _ = isAdmin
isAuthorized MyScoreR _ = regularAuthorization isAuthorized MyScoreR _ = regularAuthorization

View File

@ -15,8 +15,6 @@ import qualified Data.Text.Encoding as DTE
import Database.Persist.Sql (fromSqlKey) import Database.Persist.Sql (fromSqlKey)
import Data.Scientific
import Control.Concurrent.Lifted (threadDelay) import Control.Concurrent.Lifted (threadDelay)
import Control.Concurrent (forkIO) import Control.Concurrent (forkIO)
@ -341,13 +339,19 @@ getStuffUsingGitAnnex tmpRepoDir (Just gitAnnexRemote) = do
runGitAnnex :: FilePath -> [String] -> Runner () runGitAnnex :: FilePath -> [String] -> Runner ()
runGitAnnex tmpRepoDir args = runProg (Just tmpRepoDir) gitPath ("annex":args) runGitAnnex tmpRepoDir args = runProg (Just tmpRepoDir) gitPath ("annex":args)
doesRepoExistsOnTheDisk :: RepoId -> Handler Bool
doesRepoExistsOnTheDisk repoId = do
repoDir <- getRepoDir repoId
repoDirExists <- liftIO $ doesDirectoryExist repoDir
return repoDirExists
-- Gets a directory for an already cloned repo (e.g. arena/r1234). If, -- Gets a directory for an already cloned repo (e.g. arena/r1234). If,
-- for some reason, the directory does not exist (e.g. the database -- for some reason, the directory does not exist (e.g. the database
-- was recovered on a new computer), it will re-clone the repository. -- was recovered on a new computer), it will re-clone the repository.
getRepoDirOrClone :: RepoId -> Channel -> Handler FilePath getRepoDirOrClone :: RepoId -> Channel -> Handler FilePath
getRepoDirOrClone repoId chan = do getRepoDirOrClone repoId chan = do
repoDirExists <- doesRepoExistsOnTheDisk repoId
repoDir <- getRepoDir repoId repoDir <- getRepoDir repoId
repoDirExists <- liftIO $ doesDirectoryExist repoDir
if repoDirExists if repoDirExists
then then
return () return ()

View File

@ -188,6 +188,9 @@ getShowChallengeR challengeName = do
let leaderboardStyle = appLeaderboardStyle $ appSettings app let leaderboardStyle = appLeaderboardStyle $ appSettings app
challengeEnt@(Entity challengeId challenge) <- runDB $ getBy404 $ UniqueName challengeName challengeEnt@(Entity challengeId challenge) <- runDB $ getBy404 $ UniqueName challengeName
isHealthy <- isChallengeHealthy challenge
Just repo <- runDB $ get $ challengePublicRepo challenge Just repo <- runDB $ get $ challengePublicRepo challenge
(leaderboard, (entries, tests)) <- getLeaderboardEntries 1 leaderboardStyle challengeId (leaderboard, (entries, tests)) <- getLeaderboardEntries 1 leaderboardStyle challengeId
@ -218,7 +221,8 @@ getShowChallengeR challengeName = do
altLeaderboard altLeaderboard
params params
tests tests
altTests) altTests
isHealthy)
hasMetricsOfSecondPriority :: (PersistQueryRead backend, MonadIO m, BaseBackend backend ~ SqlBackend) => Key Challenge -> ReaderT backend m Bool hasMetricsOfSecondPriority :: (PersistQueryRead backend, MonadIO m, BaseBackend backend ~ SqlBackend) => Key Challenge -> ReaderT backend m Bool
hasMetricsOfSecondPriority challengeId = do hasMetricsOfSecondPriority challengeId = do
@ -265,6 +269,13 @@ challengeReadme challengeName = do
theContents <- doChallengeReadmeContents challengeName theContents <- doChallengeReadmeContents challengeName
return $ markdown def theContents return $ markdown def theContents
-- Checks whether the directories with repos are available
isChallengeHealthy :: Challenge -> Handler Bool
isChallengeHealthy challenge = do
publicRepoDirExists <- doesRepoExistsOnTheDisk $ challengePublicRepo challenge
privateRepoDirExists <- doesRepoExistsOnTheDisk $ challengePrivateRepo challenge
return $ publicRepoDirExists && privateRepoDirExists
doChallengeReadmeContents :: Text -> Handler TL.Text doChallengeReadmeContents :: Text -> Handler TL.Text
doChallengeReadmeContents challengeName = do doChallengeReadmeContents challengeName = do
(Entity _ challenge) <- runDB $ getBy404 $ UniqueName challengeName (Entity _ challenge) <- runDB $ getBy404 $ UniqueName challengeName
@ -284,6 +295,7 @@ showChallengeWidget :: Maybe (Entity User)
-> [Text] -> [Text]
-> [Entity Test] -> [Entity Test]
-> (Maybe [Entity Test]) -> (Maybe [Entity Test])
-> Bool
-> WidgetFor App () -> WidgetFor App ()
showChallengeWidget mUserEnt showChallengeWidget mUserEnt
(Entity challengeId challenge) (Entity challengeId challenge)
@ -295,6 +307,7 @@ showChallengeWidget mUserEnt
params params
tests tests
mAltTests mAltTests
isHealthy
= $(widgetFile "show-challenge") = $(widgetFile "show-challenge")
where leaderboardWithRanks = zip [1..] leaderboard where leaderboardWithRanks = zip [1..] leaderboard
mAltLeaderboardWithRanks = zip [1..] <$> mAltLeaderboard mAltLeaderboardWithRanks = zip [1..] <$> mAltLeaderboard
@ -374,6 +387,15 @@ challengeHowTo challenge settings repo shownId isIDSet isSSHUploaded mAltRepoSch
Just altRepoScheme -> encodeSlash (altRepoScheme <> (challengeName challenge)) Just altRepoScheme -> encodeSlash (altRepoScheme <> (challengeName challenge))
Nothing -> "URL_TO_YOUR_REPO" Nothing -> "URL_TO_YOUR_REPO"
postHealR :: ChallengeId -> Handler TypedContent
postHealR challengeId = runViewProgress $ doHeal challengeId
doHeal challengeId chan = do
challenge <- runDB $ get404 challengeId
getRepoDirOrClone (challengePrivateRepo challenge) chan
getRepoDirOrClone (challengePublicRepo challenge) chan
return ()
postArchiveR :: ChallengeId -> Handler Html postArchiveR :: ChallengeId -> Handler Html
postArchiveR challengeId = doSetArchive True challengeId postArchiveR challengeId = doSetArchive True challengeId

View File

@ -66,6 +66,7 @@
/challenge-archive/#ChallengeId ArchiveR POST /challenge-archive/#ChallengeId ArchiveR POST
/challenge-unarchive/#ChallengeId UnarchiveR POST /challenge-unarchive/#ChallengeId UnarchiveR POST
/challenge-heal/#ChallengeId HealR POST
/account YourAccountR GET POST /account YourAccountR GET POST
/avatar/#UserId AvatarR GET /avatar/#UserId AvatarR GET

View File

@ -94,3 +94,8 @@ ShouldChallengeBeValidated: validate challenge (do not switch off unless you hav
ShowAnnotations: show annotations ShowAnnotations: show annotations
Compare: Compare Compare: Compare
OutSha1: Output Sha1 hash OutSha1: Output Sha1 hash
ChallengeIsArchived: This challenge is archived!
ChallengeNotHealthy: Something is wrong with the challenge data!
Archive: Archive
Unarchive: Unarchive
Heal: Heal

View File

@ -4,18 +4,23 @@ $maybe repoLink <- maybeRepoLink
$nothing $nothing
$if (challengeArchived challenge == Just True) $if (challengeArchived challenge == Just True)
<p><b>This challenge is archived! <p><b>_{MsgChallengeIsArchived}
$if (checkIfAdmin mUserEnt) $if (checkIfAdmin mUserEnt)
$if (challengeArchived challenge /= Just True) $if (challengeArchived challenge /= Just True)
<form method=post action=@{ArchiveR challengeId}#form enctype="text/plain"> <form method=post action=@{ArchiveR challengeId}#form enctype="text/plain">
<button>Archive <button>_{MsgArchive}
<form method=get action=@{ChallengeUpdateR challengeId}#form enctype="text/plain"> <form method=get action=@{ChallengeUpdateR challengeId}#form enctype="text/plain">
<button>Update <button>_{MsgUpdate}
$if (challengeArchived challenge == Just True) $if (challengeArchived challenge == Just True)
<form method=post action=@{UnarchiveR challengeId}#form enctype="text/plain"> <form method=post action=@{UnarchiveR challengeId}#form enctype="text/plain">
<button>Unarchive <button>_{MsgUnarchive}
$if not isHealthy
_{MsgChallengeNotHealthy} <form method=post action=@{HealR challengeId}#form enctype="text/plain">
<button>_{MsgHeal}
<h2>Leaderboard <h2>Leaderboard