feat(personalised-sheet-files): download from CUsersR
This commit is contained in:
parent
0b0eaff20d
commit
93d0ace8ba
@ -2648,6 +2648,7 @@ CourseParticipantInactive: Abgemeldet
|
|||||||
CourseParticipantNoShow: Nicht erschienen
|
CourseParticipantNoShow: Nicht erschienen
|
||||||
CourseUserState: Zustand
|
CourseUserState: Zustand
|
||||||
CourseUserSheets: Übungsblätter
|
CourseUserSheets: Übungsblätter
|
||||||
|
CourseUserDownloadPersonalisedSheetFiles: Personalisierte Übungsblatt-Dateien herunterladen
|
||||||
|
|
||||||
TestDownload: Download-Test
|
TestDownload: Download-Test
|
||||||
TestDownloadMaxSize: Maximale Dateigröße
|
TestDownloadMaxSize: Maximale Dateigröße
|
||||||
|
|||||||
@ -2648,6 +2648,7 @@ CourseParticipantInactive: Deregistered
|
|||||||
CourseParticipantNoShow: No show
|
CourseParticipantNoShow: No show
|
||||||
CourseUserState: State
|
CourseUserState: State
|
||||||
CourseUserSheets: Exercise sheets
|
CourseUserSheets: Exercise sheets
|
||||||
|
CourseUserDownloadPersonalisedSheetFiles: Download personalised sheet files
|
||||||
|
|
||||||
TestDownload: Download test
|
TestDownload: Download test
|
||||||
TestDownloadMaxSize: Maximum filesize
|
TestDownloadMaxSize: Maximum filesize
|
||||||
|
|||||||
@ -32,6 +32,8 @@ import qualified Data.CaseInsensitive as CI
|
|||||||
|
|
||||||
import Database.Persist.Sql (updateWhereCount)
|
import Database.Persist.Sql (updateWhereCount)
|
||||||
|
|
||||||
|
import Handler.Sheet.PersonalisedFiles
|
||||||
|
|
||||||
|
|
||||||
type UserTableExpr = ( E.SqlExpr (Entity User)
|
type UserTableExpr = ( E.SqlExpr (Entity User)
|
||||||
`E.InnerJoin` E.SqlExpr (Entity CourseParticipant)
|
`E.InnerJoin` E.SqlExpr (Entity CourseParticipant)
|
||||||
@ -305,11 +307,12 @@ userTableCsvHeader showSex tuts sheets UserCsvExportData{..} = Csv.header $
|
|||||||
|
|
||||||
|
|
||||||
data CourseUserAction = CourseUserSendMail
|
data CourseUserAction = CourseUserSendMail
|
||||||
| CourseUserDeregister
|
|
||||||
| CourseUserRegisterTutorial
|
| CourseUserRegisterTutorial
|
||||||
| CourseUserRegisterExam
|
| CourseUserRegisterExam
|
||||||
| CourseUserSetSubmissionGroup
|
| CourseUserSetSubmissionGroup
|
||||||
| CourseUserReRegister
|
| CourseUserReRegister
|
||||||
|
| CourseUserDeregister
|
||||||
|
| CourseUserDownloadPersonalisedSheetFiles
|
||||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
||||||
|
|
||||||
instance Universe CourseUserAction
|
instance Universe CourseUserAction
|
||||||
@ -331,6 +334,10 @@ data CourseUserActionData = CourseUserSendMailData
|
|||||||
{ setSubmissionGroup :: Maybe SubmissionGroupName
|
{ setSubmissionGroup :: Maybe SubmissionGroupName
|
||||||
}
|
}
|
||||||
| CourseUserReRegisterData
|
| CourseUserReRegisterData
|
||||||
|
| CourseUserDownloadPersonalisedSheetFilesData
|
||||||
|
{ downloadPersonalisedFilesForSheet :: SheetName
|
||||||
|
, downloadPersonalisedFilesAnonMode :: PersonalisedSheetFilesDownloadAnonymous
|
||||||
|
}
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||||
|
|
||||||
|
|
||||||
@ -598,7 +605,7 @@ getCUsersR, postCUsersR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
|||||||
getCUsersR = postCUsersR
|
getCUsersR = postCUsersR
|
||||||
postCUsersR tid ssh csh = do
|
postCUsersR tid ssh csh = do
|
||||||
showSex <- getShowSex
|
showSex <- getShowSex
|
||||||
(Entity cid course, numParticipants, (participantRes,participantTable)) <- runDB $ do
|
(Entity cid Course{..}, numParticipants, (participantRes,participantTable)) <- runDB $ do
|
||||||
mayRegister <- hasWriteAccessTo $ CourseR tid ssh csh CAddUserR
|
mayRegister <- hasWriteAccessTo $ CourseR tid ssh csh CAddUserR
|
||||||
ent@(Entity cid _) <- getBy404 $ TermSchoolCourseShort tid ssh csh
|
ent@(Entity cid _) <- getBy404 $ TermSchoolCourseShort tid ssh csh
|
||||||
hasTutorials <- exists [TutorialCourse ==. cid]
|
hasTutorials <- exists [TutorialCourse ==. cid]
|
||||||
@ -612,6 +619,16 @@ postCUsersR tid ssh csh = do
|
|||||||
E.on $ submissionGroupUser E.^. SubmissionGroupUserSubmissionGroup E.==. submissionGroup E.^. SubmissionGroupId
|
E.on $ submissionGroupUser E.^. SubmissionGroupUserSubmissionGroup E.==. submissionGroup E.^. SubmissionGroupId
|
||||||
E.where_ $ submissionGroup E.^. SubmissionGroupCourse E.==. E.val cid
|
E.where_ $ submissionGroup E.^. SubmissionGroupCourse E.==. E.val cid
|
||||||
sheetList <- selectList [SheetCourse ==. cid] [Desc SheetActiveTo, Desc SheetActiveFrom]
|
sheetList <- selectList [SheetCourse ==. cid] [Desc SheetActiveTo, Desc SheetActiveFrom]
|
||||||
|
personalisedSheets <- E.select . E.from $ \sheet -> do
|
||||||
|
let hasPersonalised = E.exists . E.from $ \psFile ->
|
||||||
|
E.where_ $ psFile E.^. PersonalisedSheetFileSheet E.==. sheet E.^. SheetId
|
||||||
|
E.where_ $ E.not_ (sheet E.^. SheetAllowNonPersonalisedSubmission)
|
||||||
|
E.||. hasPersonalised
|
||||||
|
E.where_ $ sheet E.^. SheetCourse E.==. E.val cid
|
||||||
|
E.orderBy [ E.desc $ sheet E.^. SheetActiveTo
|
||||||
|
, E.desc $ sheet E.^. SheetActiveFrom
|
||||||
|
]
|
||||||
|
return $ sheet E.^. SheetName
|
||||||
let exams = nubOn entityKey $ examOccurrencesPerExam ^.. folded . _1
|
let exams = nubOn entityKey $ examOccurrencesPerExam ^.. folded . _1
|
||||||
let colChoices = mconcat $ catMaybes
|
let colChoices = mconcat $ catMaybes
|
||||||
[ pure . cap' $ dbSelect (applying _2) id (return . view (hasEntity . _entityKey))
|
[ pure . cap' $ dbSelect (applying _2) id (return . view (hasEntity . _entityKey))
|
||||||
@ -659,6 +676,7 @@ postCUsersR tid ssh csh = do
|
|||||||
optionDisplay = CI.original $ examName entityVal
|
optionDisplay = CI.original $ examName entityVal
|
||||||
return Option{..}
|
return Option{..}
|
||||||
submissionGroupOpts = optionsPersist [SubmissionGroupCourse ==. cid] [Asc SubmissionGroupName] submissionGroupName <&> fmap (submissionGroupName . entityVal)
|
submissionGroupOpts = optionsPersist [SubmissionGroupCourse ==. cid] [Asc SubmissionGroupName] submissionGroupName <&> fmap (submissionGroupName . entityVal)
|
||||||
|
acts :: Map CourseUserAction (AForm Handler CourseUserActionData)
|
||||||
acts = mconcat $ catMaybes
|
acts = mconcat $ catMaybes
|
||||||
[ pure . singletonMap CourseUserSendMail $ pure CourseUserSendMailData
|
[ pure . singletonMap CourseUserSendMail $ pure CourseUserSendMailData
|
||||||
, pure . singletonMap CourseUserRegisterTutorial $ CourseUserRegisterTutorialData
|
, pure . singletonMap CourseUserRegisterTutorial $ CourseUserRegisterTutorialData
|
||||||
@ -671,6 +689,10 @@ postCUsersR tid ssh csh = do
|
|||||||
<$> aopt (textField & cfStrip & cfCI & addDatalist submissionGroupOpts) (fslI MsgSubmissionGroup & setTooltip MsgSubmissionGroupEmptyIsUnsetTip) Nothing
|
<$> aopt (textField & cfStrip & cfCI & addDatalist submissionGroupOpts) (fslI MsgSubmissionGroup & setTooltip MsgSubmissionGroupEmptyIsUnsetTip) Nothing
|
||||||
, guardOn mayRegister . singletonMap CourseUserDeregister $ courseUserDeregisterForm cid
|
, guardOn mayRegister . singletonMap CourseUserDeregister $ courseUserDeregisterForm cid
|
||||||
, guardOn mayRegister . singletonMap CourseUserReRegister $ pure CourseUserReRegisterData
|
, guardOn mayRegister . singletonMap CourseUserReRegister $ pure CourseUserReRegisterData
|
||||||
|
, guardOn (not $ null personalisedSheets) . singletonMap CourseUserDownloadPersonalisedSheetFiles $
|
||||||
|
CourseUserDownloadPersonalisedSheetFilesData
|
||||||
|
<$> apopt (selectField' Nothing . optionsF $ map E.unValue personalisedSheets) (fslI MsgExerciseSheet) Nothing
|
||||||
|
<*> apopt (selectField optionsFinite) (fslI MsgPersonalisedSheetFilesDownloadAnonymousField) (Just PersonalisedSheetFilesDownloadAnonymous)
|
||||||
]
|
]
|
||||||
numParticipants <- count [CourseParticipantCourse ==. cid, CourseParticipantState ==. CourseParticipantActive]
|
numParticipants <- count [CourseParticipantCourse ==. cid, CourseParticipantState ==. CourseParticipantActive]
|
||||||
table <- makeCourseUserTable cid acts (const E.true) colChoices psValidator (Just $ const True)
|
table <- makeCourseUserTable cid acts (const E.true) colChoices psValidator (Just $ const True)
|
||||||
@ -753,8 +775,14 @@ postCUsersR tid ssh csh = do
|
|||||||
return $ Sum didUpdate
|
return $ Sum didUpdate
|
||||||
addMessageI Success $ MsgCourseUsersStateSet nrSet
|
addMessageI Success $ MsgCourseUsersStateSet nrSet
|
||||||
redirect $ CourseR tid ssh csh CUsersR
|
redirect $ CourseR tid ssh csh CUsersR
|
||||||
|
(CourseUserDownloadPersonalisedSheetFilesData shn anonMode, selectedUsers) -> do
|
||||||
|
shId <- runDB . getKeyBy404 $ CourseSheet cid shn
|
||||||
|
archiveName <- fmap (flip addExtension (unpack extensionZip) . unpack) . ap getMessageRender . pure $
|
||||||
|
MsgPersonalisedSheetFilesArchiveName courseTerm courseSchool courseShorthand shn
|
||||||
|
sendResponse <=< serveZipArchive' archiveName $ sourcePersonalisedSheetFiles cid (Just shId) (Just selectedUsers) anonMode
|
||||||
|
|
||||||
let headingLong = [whamlet|_{MsgMenuCourseMembers} #{courseName course} #{tid}|]
|
|
||||||
|
let headingLong = [whamlet|_{MsgMenuCourseMembers} #{courseName} #{tid}|]
|
||||||
headingShort = prependCourseTitle tid ssh csh MsgCourseMembers
|
headingShort = prependCourseTitle tid ssh csh MsgCourseMembers
|
||||||
siteLayout headingLong $ do
|
siteLayout headingLong $ do
|
||||||
setTitleI headingShort
|
setTitleI headingShort
|
||||||
|
|||||||
@ -3,6 +3,7 @@ module Handler.Sheet.PersonalisedFiles
|
|||||||
, getSPersonalFilesR, getCPersonalFilesR
|
, getSPersonalFilesR, getCPersonalFilesR
|
||||||
, PersonalisedSheetFilesKeyException(..)
|
, PersonalisedSheetFilesKeyException(..)
|
||||||
, sourcePersonalisedSheetFiles, resolvePersonalisedSheetFiles
|
, sourcePersonalisedSheetFiles, resolvePersonalisedSheetFiles
|
||||||
|
, PersonalisedSheetFilesDownloadAnonymous(..)
|
||||||
, PersonalisedSheetFileUnresolved(..)
|
, PersonalisedSheetFileUnresolved(..)
|
||||||
, _PSFUnresolved, _PSFUnresolvedCollatable, _PSFUnresolvedDirectory
|
, _PSFUnresolved, _PSFUnresolvedCollatable, _PSFUnresolvedDirectory
|
||||||
) where
|
) where
|
||||||
@ -192,9 +193,10 @@ sourcePersonalisedSheetFiles :: forall m.
|
|||||||
)
|
)
|
||||||
=> CourseId
|
=> CourseId
|
||||||
-> Maybe SheetId
|
-> Maybe SheetId
|
||||||
|
-> Maybe (Set UserId)
|
||||||
-> PersonalisedSheetFilesDownloadAnonymous
|
-> PersonalisedSheetFilesDownloadAnonymous
|
||||||
-> ConduitT () (Either PersonalisedSheetFile File) (SqlPersistT m) ()
|
-> ConduitT () (Either PersonalisedSheetFile File) (SqlPersistT m) ()
|
||||||
sourcePersonalisedSheetFiles cId mbsid anonMode = do
|
sourcePersonalisedSheetFiles cId mbsid mbuids anonMode = do
|
||||||
(mbIdx, cIDKey) <- lift . newPersonalisedFilesKey $ maybe (Left cId) Right mbsid
|
(mbIdx, cIDKey) <- lift . newPersonalisedFilesKey $ maybe (Left cId) Right mbsid
|
||||||
let
|
let
|
||||||
genSuffixes uid = case anonMode of
|
genSuffixes uid = case anonMode of
|
||||||
@ -223,7 +225,9 @@ sourcePersonalisedSheetFiles cId mbsid anonMode = do
|
|||||||
E.on $ E.just (courseParticipant E.^. CourseParticipantUser) E.==. personalisedSheetFile E.?. PersonalisedSheetFileUser
|
E.on $ E.just (courseParticipant E.^. CourseParticipantUser) E.==. personalisedSheetFile E.?. PersonalisedSheetFileUser
|
||||||
E.&&. E.val mbsid E.==. personalisedSheetFile E.?. PersonalisedSheetFileSheet
|
E.&&. E.val mbsid E.==. personalisedSheetFile E.?. PersonalisedSheetFileSheet
|
||||||
E.where_ $ courseParticipant E.^. CourseParticipantCourse E.==. E.val cId
|
E.where_ $ courseParticipant E.^. CourseParticipantCourse E.==. E.val cId
|
||||||
E.where_ $ courseParticipant E.^. CourseParticipantState E.==. E.val CourseParticipantActive
|
case mbuids of
|
||||||
|
Just uids -> E.where_ $ courseParticipant E.^. CourseParticipantUser `E.in_` E.valList (Set.toList uids)
|
||||||
|
Nothing -> E.where_ $ courseParticipant E.^. CourseParticipantState E.==. E.val CourseParticipantActive
|
||||||
return (courseParticipant, personalisedSheetFile)
|
return (courseParticipant, personalisedSheetFile)
|
||||||
|
|
||||||
toRefs = awaitForever $ \(Entity _ cPart@CourseParticipant{..}, mbPFile) -> do
|
toRefs = awaitForever $ \(Entity _ cPart@CourseParticipant{..}, mbPFile) -> do
|
||||||
@ -370,7 +374,7 @@ getPersonalFilesR cId mbsid = do
|
|||||||
archiveName <- fmap (flip addExtension (unpack extensionZip) . unpack) . ap getMessageRender . pure $ case mbSheet of
|
archiveName <- fmap (flip addExtension (unpack extensionZip) . unpack) . ap getMessageRender . pure $ case mbSheet of
|
||||||
Nothing -> MsgCoursePersonalisedSheetFilesArchiveName courseTerm courseSchool courseShorthand
|
Nothing -> MsgCoursePersonalisedSheetFilesArchiveName courseTerm courseSchool courseShorthand
|
||||||
Just Sheet{..} -> MsgPersonalisedSheetFilesArchiveName courseTerm courseSchool courseShorthand sheetName
|
Just Sheet{..} -> MsgPersonalisedSheetFilesArchiveName courseTerm courseSchool courseShorthand sheetName
|
||||||
sendResponse <=< serveZipArchive' archiveName $ sourcePersonalisedSheetFiles cId mbsid anonMode
|
sendResponse <=< serveZipArchive' archiveName $ sourcePersonalisedSheetFiles cId mbsid Nothing anonMode
|
||||||
|
|
||||||
isModal <- hasCustomHeader HeaderIsModal
|
isModal <- hasCustomHeader HeaderIsModal
|
||||||
|
|
||||||
|
|||||||
@ -4,4 +4,4 @@ $#
|
|||||||
$# participantTable : widget table
|
$# participantTable : widget table
|
||||||
|
|
||||||
^{participantTable}
|
^{participantTable}
|
||||||
_{MsgCourseMembersCountOf numParticipants (courseCapacity course)}.
|
_{MsgCourseMembersCountOf numParticipants courseCapacity}.
|
||||||
|
|||||||
@ -76,7 +76,7 @@ spec = withApp . describe "Personalised sheet file zip encoding" $ do
|
|||||||
isDirectory = either (is _Nothing . personalisedSheetFileContent) (is _Nothing . fileContent)
|
isDirectory = either (is _Nothing . personalisedSheetFileContent) (is _Nothing . fileContent)
|
||||||
|
|
||||||
recoveredFiles <- runConduit $
|
recoveredFiles <- runConduit $
|
||||||
sourcePersonalisedSheetFiles cid (Just shid) anonMode
|
sourcePersonalisedSheetFiles cid (Just shid) Nothing anonMode
|
||||||
.| resolvePersonalisedSheetFiles fpL isDirectory cid shid
|
.| resolvePersonalisedSheetFiles fpL isDirectory cid shid
|
||||||
.| C.foldMap pure
|
.| C.foldMap pure
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user