Add endpoint for querying by hash
This commit is contained in:
parent
4c7f7add98
commit
106e076bc8
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
{-# LANGUAGE InstanceSigs #-}
|
{-# LANGUAGE InstanceSigs #-}
|
||||||
|
|
||||||
module Foundation where
|
module Foundation where
|
||||||
@ -175,6 +176,7 @@ instance Yesod App where
|
|||||||
isAuthorized UserInfoR _ = return Authorized
|
isAuthorized UserInfoR _ = return Authorized
|
||||||
isAuthorized (ChallengeSubmissionJsonR _) _ = return Authorized
|
isAuthorized (ChallengeSubmissionJsonR _) _ = return Authorized
|
||||||
isAuthorized (ChallengeReadmeInMarkdownR _) _ = regularAuthorization
|
isAuthorized (ChallengeReadmeInMarkdownR _) _ = regularAuthorization
|
||||||
|
isAuthorized (QueryJsonR _) _ = return Authorized
|
||||||
|
|
||||||
isAuthorized (ChallengeGraphDataR _) _ = regularAuthorization
|
isAuthorized (ChallengeGraphDataR _) _ = regularAuthorization
|
||||||
isAuthorized (ChallengeDiscussionR _) _ = regularAuthorization
|
isAuthorized (ChallengeDiscussionR _) _ = regularAuthorization
|
||||||
|
148
Handler/Query.hs
148
Handler/Query.hs
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
module Handler.Query where
|
module Handler.Query where
|
||||||
|
|
||||||
import Import
|
import Import hiding (fromList, Proxy)
|
||||||
|
|
||||||
import Handler.SubmissionView
|
import Handler.SubmissionView
|
||||||
import Handler.Shared
|
import Handler.Shared
|
||||||
@ -43,6 +43,90 @@ import System.Directory (makeAbsolute)
|
|||||||
|
|
||||||
import Data.SplitIntoCrossTabs
|
import Data.SplitIntoCrossTabs
|
||||||
|
|
||||||
|
import Data.Swagger hiding (get)
|
||||||
|
import qualified Data.Swagger as DS
|
||||||
|
|
||||||
|
import Data.Swagger.Declare
|
||||||
|
import Control.Lens hiding ((.=), (^.), (<.>))
|
||||||
|
import Data.Proxy as DPR
|
||||||
|
import Data.HashMap.Strict.InsOrd (fromList)
|
||||||
|
|
||||||
|
import Handler.ShowChallenge
|
||||||
|
|
||||||
|
|
||||||
|
data VariantView = VariantView {
|
||||||
|
variantViewId :: Int64,
|
||||||
|
variantViewName :: Text,
|
||||||
|
variantViewEvaluations :: [EvaluationView],
|
||||||
|
variantViewParams :: [Parameter]
|
||||||
|
}
|
||||||
|
|
||||||
|
instance ToJSON Parameter where
|
||||||
|
toJSON entry = object
|
||||||
|
[ "name" .= parameterName entry,
|
||||||
|
"value" .= parameterValue entry
|
||||||
|
]
|
||||||
|
|
||||||
|
instance ToSchema Parameter where
|
||||||
|
declareNamedSchema _ = do
|
||||||
|
stringSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy String)
|
||||||
|
return $ NamedSchema (Just "SubmissionInfo") $ mempty
|
||||||
|
& type_ .~ SwaggerObject
|
||||||
|
& properties .~
|
||||||
|
fromList [ ("name", stringSchema),
|
||||||
|
("value", stringSchema)
|
||||||
|
]
|
||||||
|
& required .~ [ "name", "value" ]
|
||||||
|
|
||||||
|
instance ToJSON VariantView where
|
||||||
|
toJSON entry = object
|
||||||
|
[ "id" .= variantViewId entry,
|
||||||
|
"name" .= variantViewName entry,
|
||||||
|
"evaluations" .= variantViewEvaluations entry,
|
||||||
|
"params" .= variantViewParams entry
|
||||||
|
]
|
||||||
|
|
||||||
|
instance ToSchema VariantView where
|
||||||
|
declareNamedSchema _ = do
|
||||||
|
intSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy [Int64])
|
||||||
|
stringSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy [String])
|
||||||
|
evaluationsSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy [EvaluationView])
|
||||||
|
paramsSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy [Parameter])
|
||||||
|
return $ NamedSchema (Just "SubmissionInfo") $ mempty
|
||||||
|
& type_ .~ SwaggerObject
|
||||||
|
& properties .~
|
||||||
|
fromList [ ("id", intSchema),
|
||||||
|
("name", stringSchema),
|
||||||
|
("evaluations", evaluationsSchema),
|
||||||
|
("params", paramsSchema)
|
||||||
|
]
|
||||||
|
& required .~ [ "evaluations" ]
|
||||||
|
|
||||||
|
data QueryResultView = QueryResultView {
|
||||||
|
queryResultViewSubmissionInfo :: FullSubmissionInfo,
|
||||||
|
queryResultViewVariants :: [VariantView]
|
||||||
|
}
|
||||||
|
|
||||||
|
instance ToJSON QueryResultView where
|
||||||
|
toJSON entry = object
|
||||||
|
[ "submissionInfo" .= queryResultViewSubmissionInfo entry,
|
||||||
|
"variants" .= queryResultViewVariants entry
|
||||||
|
]
|
||||||
|
|
||||||
|
instance ToSchema QueryResultView where
|
||||||
|
declareNamedSchema _ = do
|
||||||
|
submissionInfoSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy FullSubmissionInfo)
|
||||||
|
variantViewsSchema <- declareSchemaRef (DPR.Proxy :: DPR.Proxy [VariantView])
|
||||||
|
return $ NamedSchema (Just "SubmissionInfo") $ mempty
|
||||||
|
& type_ .~ SwaggerObject
|
||||||
|
& properties .~
|
||||||
|
fromList [ ("submissionInfo", submissionInfoSchema),
|
||||||
|
("variants", variantViewsSchema)
|
||||||
|
]
|
||||||
|
& required .~ [ "submissionInfo", "variants" ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rawCommitQuery :: (MonadIO m, RawSql a) => Text -> ReaderT SqlBackend m [a]
|
rawCommitQuery :: (MonadIO m, RawSql a) => Text -> ReaderT SqlBackend m [a]
|
||||||
rawCommitQuery sha1Prefix =
|
rawCommitQuery sha1Prefix =
|
||||||
rawSql "SELECT ?? FROM submission WHERE cast(commit as text) like ?" [PersistText $ "\\\\x" ++ sha1Prefix ++ "%"]
|
rawSql "SELECT ?? FROM submission WHERE cast(commit as text) like ?" [PersistText $ "\\\\x" ++ sha1Prefix ++ "%"]
|
||||||
@ -191,6 +275,68 @@ processQuery query = do
|
|||||||
setTitle "query results"
|
setTitle "query results"
|
||||||
$(widgetFile "query-results")
|
$(widgetFile "query-results")
|
||||||
|
|
||||||
|
toQueryResultView :: FullSubmissionInfo -> Handler QueryResultView
|
||||||
|
toQueryResultView fsi = do
|
||||||
|
let submissionId = fsiSubmissionId fsi
|
||||||
|
let submission = fsiSubmission fsi
|
||||||
|
(tableEntries, tests) <- runDB
|
||||||
|
$ getChallengeSubmissionInfos 2
|
||||||
|
(\s -> entityKey s == submissionId)
|
||||||
|
(const True)
|
||||||
|
id
|
||||||
|
(submissionChallenge submission)
|
||||||
|
|
||||||
|
|
||||||
|
let evaluations = map (\entry ->
|
||||||
|
VariantView {
|
||||||
|
variantViewId = fromSqlKey $ entityKey $ tableEntryVariant entry,
|
||||||
|
variantViewName = variantName $ entityVal $ tableEntryVariant entry,
|
||||||
|
variantViewEvaluations = catMaybes $ Import.map (convertEvaluationToView $ tableEntryMapping entry) tests,
|
||||||
|
variantViewParams = Import.map entityVal $ tableEntryParams entry
|
||||||
|
|
||||||
|
}) tableEntries
|
||||||
|
|
||||||
|
return $ QueryResultView {
|
||||||
|
queryResultViewSubmissionInfo = fsi,
|
||||||
|
queryResultViewVariants = evaluations }
|
||||||
|
|
||||||
|
getQueryJsonR :: Text -> Handler Value
|
||||||
|
getQueryJsonR query = do
|
||||||
|
submissions' <- findSubmissions query
|
||||||
|
let submissions = map fst submissions'
|
||||||
|
|
||||||
|
qrvs <- mapM toQueryResultView submissions
|
||||||
|
return $ array qrvs
|
||||||
|
|
||||||
|
declareQuerySwagger :: Declare (Definitions Schema) Swagger
|
||||||
|
declareQuerySwagger = do
|
||||||
|
-- param schemas
|
||||||
|
let querySchema = toParamSchema (Proxy :: Proxy String)
|
||||||
|
|
||||||
|
queryResponse <- declareResponse (Proxy :: Proxy [QueryResultView])
|
||||||
|
|
||||||
|
return $ mempty
|
||||||
|
& paths .~
|
||||||
|
fromList [ ("/api/query/{query}",
|
||||||
|
mempty & DS.get ?~ (mempty
|
||||||
|
& parameters .~ [ Inline $ mempty
|
||||||
|
& name .~ "query"
|
||||||
|
& required ?~ True
|
||||||
|
& schema .~ ParamOther (mempty
|
||||||
|
& in_ .~ ParamPath
|
||||||
|
& paramSchema .~ querySchema) ]
|
||||||
|
& produces ?~ MimeList ["application/json"]
|
||||||
|
& description ?~ "For a SHA1 hash prefix returns all the submissions matching"
|
||||||
|
& at 200 ?~ Inline queryResponse))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
queryApi :: Swagger
|
||||||
|
queryApi = spec & definitions .~ defs
|
||||||
|
where
|
||||||
|
(defs, spec) = runDeclare declareLeaderboardSwagger mempty
|
||||||
|
|
||||||
|
|
||||||
priorityLimitForViewVariant :: Int
|
priorityLimitForViewVariant :: Int
|
||||||
priorityLimitForViewVariant = 4
|
priorityLimitForViewVariant = 4
|
||||||
|
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
module Handler.SubmissionView where
|
module Handler.SubmissionView where
|
||||||
|
|
||||||
import Import
|
import Import hiding (fromList)
|
||||||
|
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
import Database.Esqueleto ((^.))
|
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 {
|
data FullSubmissionInfo = FullSubmissionInfo {
|
||||||
fsiSubmissionId :: SubmissionId,
|
fsiSubmissionId :: SubmissionId,
|
||||||
fsiSubmission :: Submission,
|
fsiSubmission :: Submission,
|
||||||
@ -13,10 +21,31 @@ data FullSubmissionInfo = FullSubmissionInfo {
|
|||||||
fsiChallenge :: Challenge,
|
fsiChallenge :: Challenge,
|
||||||
fsiChallengeRepo :: Repo,
|
fsiChallengeRepo :: Repo,
|
||||||
fsiScheme :: RepoScheme,
|
fsiScheme :: RepoScheme,
|
||||||
fsiTags :: [(Entity Tag, Entity SubmissionTag)],
|
fsiTags :: [(Entity Import.Tag, Entity SubmissionTag)],
|
||||||
fsiExternalLinks :: [Entity ExternalLink],
|
fsiExternalLinks :: [Entity ExternalLink],
|
||||||
fsiSuperSubmissions :: [FullSubmissionInfo] }
|
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 Submission -> Handler FullSubmissionInfo
|
||||||
getFullInfo (Entity submissionId submission) = do
|
getFullInfo (Entity submissionId submission) = do
|
||||||
repo <- runDB $ get404 $ submissionRepo submission
|
repo <- runDB $ get404 $ submissionRepo submission
|
||||||
@ -50,7 +79,7 @@ getFullInfo (Entity submissionId submission) = do
|
|||||||
fsiExternalLinks = links,
|
fsiExternalLinks = links,
|
||||||
fsiSuperSubmissions = superSubmissionFsis }
|
fsiSuperSubmissions = superSubmissionFsis }
|
||||||
|
|
||||||
getTags :: (BaseBackend backend ~ SqlBackend, MonadIO m, PersistQueryRead backend) => Key Submission -> ReaderT backend m [(Entity Tag, Entity SubmissionTag)]
|
getTags :: (BaseBackend backend ~ SqlBackend, MonadIO m, PersistQueryRead backend) => Key Submission -> ReaderT backend m [(Entity Import.Tag, Entity SubmissionTag)]
|
||||||
getTags submissionId = do
|
getTags submissionId = do
|
||||||
sts <- selectList [SubmissionTagSubmission ==. submissionId] []
|
sts <- selectList [SubmissionTagSubmission ==. submissionId] []
|
||||||
let tagIds = Import.map (submissionTagTag . entityVal) sts
|
let tagIds = Import.map (submissionTagTag . entityVal) sts
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
/api/challenge-submission/#Text ChallengeSubmissionJsonR POST
|
/api/challenge-submission/#Text ChallengeSubmissionJsonR POST
|
||||||
/api/challenge-readme/#Text/markdown ChallengeReadmeInMarkdownR GET
|
/api/challenge-readme/#Text/markdown ChallengeReadmeInMarkdownR GET
|
||||||
/api/challenge-image/#ChallengeId ChallengeImageR GET
|
/api/challenge-image/#ChallengeId ChallengeImageR GET
|
||||||
|
/api/query/#Text QueryJsonR GET
|
||||||
/list-archived-challenges ListArchivedChallengesR GET
|
/list-archived-challenges ListArchivedChallengesR GET
|
||||||
|
|
||||||
/challenge/#Text ShowChallengeR GET
|
/challenge/#Text ShowChallengeR GET
|
||||||
|
Loading…
Reference in New Issue
Block a user