gonito/Handler/Annotations.hs

117 lines
5.1 KiB
Haskell

module Handler.Annotations where
import Import
import qualified Database.Esqueleto as E
import qualified Yesod.Table as Table
import Handler.Tables (timestampCell)
getListAnnotationsR :: Handler Html
getListAnnotationsR = do
annotations <- runDB $ selectList [] [Asc AnnotationTaskId]
defaultLayout $ do
setTitle "List annotation tasks"
$(widgetFile "list-annotations")
getAnnotationTaskR :: AnnotationTaskId -> Handler Html
getAnnotationTaskR annotationTaskId = do
(Entity userId _) <- requireAuth
annotationTask <- runDB $ get annotationTaskId
-- Get all labels
labels <- runDB $ selectList [AnnotationLabelAnnotationTask ==. annotationTaskId] [Asc AnnotationLabelOrder]
-- Get list of user decisions for this annotation task
taskDecisionIds' <- runDB $ E.select
$ E.from $ \(annotationItem `E.InnerJoin` annotationDecision) -> do
E.on (annotationItem E.^. AnnotationItemId E.==. annotationDecision E.^. AnnotationDecisionAnnotationItem)
E.where_ (annotationItem E.^. AnnotationItemAnnotationTask E.==. E.val annotationTaskId
E.&&. annotationDecision E.^. AnnotationDecisionUser E.==. E.val userId)
return $ annotationDecision E.^. AnnotationDecisionAnnotationItem
let decisionLength = length taskDecisionIds'
-- Get number of items for this annotation task
taskItemsLength <- runDB $ count [AnnotationItemAnnotationTask ==. annotationTaskId]
-- Get first item to annotate which was not annotated
let taskDecisionIds = map E.unValue taskDecisionIds'
maybeItem <- runDB $ selectFirst [AnnotationItemAnnotationTask ==. annotationTaskId,
AnnotationItemId /<-. taskDecisionIds] [Asc AnnotationItemOrder]
let allDone = decisionLength == taskItemsLength && decisionLength > 0
defaultLayout $ do
setTitle "Annotation task"
$(widgetFile "annotation-task")
postAnnotationTaskDecisionR :: AnnotationTaskId -> AnnotationItemId -> AnnotationLabelId -> Handler Html
postAnnotationTaskDecisionR annotationTaskId itemId labelId = do
(Entity userId _) <- requireAuth
now <- liftIO getCurrentTime
label <- runDB $ get404 labelId
-- Check decision exists
maybeSaveDecision <- runDB $ selectFirst [AnnotationDecisionAnnotationItem ==. itemId,
AnnotationDecisionUser ==. userId] []
case maybeSaveDecision of
-- Update if exists
Nothing -> do
_ <- runDB $ insert $ AnnotationDecision itemId userId (annotationLabelValue label) now
return ()
-- Insert new
Just (Entity saveDecisionId _) -> do
_ <- runDB $ updateWhere [AnnotationDecisionId ==. saveDecisionId] [AnnotationDecisionValue =. annotationLabelValue label,
AnnotationDecisionStamp =. now]
return ()
-- Redirect to annotation page
redirect $ AnnotationTaskR annotationTaskId
getAnnotationTaskResultsR :: AnnotationTaskId -> Handler Html
getAnnotationTaskResultsR annotationTaskId = do
results <- runDB $ E.select
$ E.from $ \(annotationDecision `E.InnerJoin` annotationItem) -> do
E.on (annotationDecision E.^. AnnotationDecisionAnnotationItem E.==. annotationItem E.^. AnnotationItemId)
E.where_ (annotationItem E.^. AnnotationItemAnnotationTask E.==. E.val annotationTaskId)
E.orderBy [E.asc (annotationItem E.^. AnnotationItemOrder),
E.asc (annotationDecision E.^. AnnotationDecisionUser)]
return (annotationItem E.^. AnnotationItemContent,
annotationItem E.^. AnnotationItemOrder,
annotationDecision E.^. AnnotationDecisionUser,
annotationDecision E.^. AnnotationDecisionValue)
labels <- runDB $ selectList [AnnotationLabelAnnotationTask ==. annotationTaskId] [Asc AnnotationLabelOrder]
defaultLayout $ do
setTitle "Annotation task results"
$(widgetFile "annotation-task-results")
annotationListTable :: Table.Table App (Entity AnnotationTask)
annotationListTable = mempty
++ Table.text "Name" (annotationTaskName . entityVal)
++ Table.linked "Annotation link" (const "Annotation link") (AnnotationTaskR . entityKey)
++ Table.linked "Results link" (const "Results link") (AnnotationTaskResultsR . entityKey)
++ timestampCell "Date added" (annotationTaskAdded . entityVal)
annotationResultsTable :: Table.Table App (E.Value Text, E.Value Int, E.Value (Key User), E.Value Text)
annotationResultsTable = mempty
++ Table.int "ID" (\(_, order, _, _) -> E.unValue order)
++ Table.int "UserID" (\(_, _, userId, _) -> fromIntegral $ E.fromSqlKey $ E.unValue userId)
++ Table.text "Answer value" (\(_, _, _, answer) -> E.unValue answer)
++ Table.text "Text" (\(content, _, _, _) -> E.unValue content)
annotationLabelsTable :: Table.Table App (Entity AnnotationLabel)
annotationLabelsTable = mempty
++ Table.text "Answer value" (annotationLabelValue . entityVal)
++ Table.text "Text" (annotationLabelName . entityVal)