module Handler.SubmissionView where import Import hiding (fromList) import qualified Database.Esqueleto as E import Database.Esqueleto ((^.)) import Handler.Shared import PersistSHA1 import Data.Swagger hiding (get) import Control.Lens hiding ((.=), (^.)) import Data.Proxy as DPR import Data.HashMap.Strict.InsOrd (fromList) data FullSubmissionInfo = FullSubmissionInfo { fsiSubmissionId :: SubmissionId, fsiSubmission :: Submission, fsiUser :: User, fsiRepo :: Repo, fsiChallenge :: Challenge, fsiChallengeRepo :: Repo, fsiScheme :: RepoScheme, fsiTags :: [(Entity Import.Tag, Entity SubmissionTag)], fsiExternalLinks :: [Entity ExternalLink], fsiSuperSubmissions :: [FullSubmissionInfo] } instance ToJSON FullSubmissionInfo where toJSON entry = object [ "hash" .= (fromSHA1ToText $ submissionCommit $ fsiSubmission entry), "submitter" .= (formatSubmitter $ fsiUser entry), "challenge" .= (challengeName $ fsiChallenge entry) ] instance ToSchema FullSubmissionInfo where declareNamedSchema _ = do stringSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy String) return $ NamedSchema (Just "SubmissionInfo") $ mempty & type_ .~ SwaggerObject & properties .~ fromList [ ("hash", stringSchema) , ("submitter", stringSchema) , ("challenge", stringSchema) ] & required .~ [ "hash", "submitter", "challenge" ] getFullInfo :: Entity Submission -> Handler FullSubmissionInfo getFullInfo (Entity submissionId submission) = do repo <- runDB $ get404 $ submissionRepo submission user <- runDB $ get404 $ submissionSubmitter submission challenge <- runDB $ get404 $ submissionChallenge submission challengeRepo <- runDB $ get404 $ challengePublicRepo challenge tags <- runDB $ getTags submissionId links <- runDB $ selectList [ExternalLinkSubmission ==. submissionId] [Asc ExternalLinkTitle] app <- getYesod let scheme = appRepoScheme $ appSettings app superSubmissions <- runDB $ E.select $ E.from $ \(submission', dependency) -> do E.where_ (submission' ^. SubmissionCommit E.==. dependency ^. DependencySuperRepoCommit E.&&. dependency ^. DependencySubRepoCommit E.==. (E.val (submissionCommit submission))) return submission' superSubmissionFsis <- mapM getFullInfo superSubmissions return $ FullSubmissionInfo { fsiSubmissionId = submissionId, fsiSubmission = submission, fsiUser = user, fsiRepo = repo, fsiChallenge = challenge, fsiChallengeRepo = challengeRepo, fsiScheme = scheme, fsiTags = tags, fsiExternalLinks = links, fsiSuperSubmissions = superSubmissionFsis } getTags :: (BaseBackend backend ~ SqlBackend, MonadIO m, PersistQueryRead backend) => Key Submission -> ReaderT backend m [(Entity Import.Tag, Entity SubmissionTag)] getTags submissionId = do sts <- selectList [SubmissionTagSubmission ==. submissionId] [] let tagIds = Import.map (submissionTagTag . entityVal) sts tags <- mapM get404 $ tagIds let tagEnts = Import.map (\(k, v) -> Entity k v) $ Import.zip tagIds tags return $ zip tagEnts sts