diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index 4ad9b7456..190b73635 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -636,8 +636,8 @@ CorrectionTime: Korrekturdauer AssignSubmissionsRandomWarning: Die Zuteilungsvorschau kann von der tatsächlichen Zuteilung abweichen, wenn mehrere Blätter auf einmal zugeteilt werden, da beim Ausgleich der Kontigente nur bereits zugeteilte Abgaben berücksichtigt werden. Da es ein randomisierte Prozess ist, kann es auch bei einzelnen Blättern gerinfgügige Abweichungen geben. AssignSubmissionsAssignableSheets: Korrekturen verteilen für: -CorrectionsUploaded num@Int64: #{num} Korrekturen wurden gespeichert: -NoCorrectionsUploaded: In der hochgeladenen Datei wurden keine Korrekturen gefunden. +CorrectionsUploaded num@Int64: #{num} #{pluralDE num "Korrektur wurde" "Korrekturen wurden"} gespeichert +NoCorrectionsUploaded: In den hochgeladenen Dateien wurden keine Korrekturen gefunden. RatingBy: Korrigiert von HasCorrector: Korrektor zugeteilt @@ -2632,4 +2632,10 @@ RatingYAMLChangePointsComment: TODO: Hier die Punktezahl statt null eintragen (b RatingYAMLChangePassedComment: TODO: Hier true oder false statt null eintragen (true entspricht Bestanden) RatingYAMLChangeDoneComment: TODO: Von false auf true setzen, sobald Bewertung abgeschlossen; sonst Korrektur für die Studierenden nicht sichtbar und keine Anrechnung auf Klausurbonus RatingYAMLChangeCommentComment: TODO: Korrektur-Kommentar für die Studierenden unterhalb der Abtrennung (...) eintragen -RatingYAMLSubmissionIdComment: Abgabenummer; wird beim Hochladen mit dem Dateinamen abgeglichen \ No newline at end of file +RatingYAMLSubmissionIdComment: Abgabenummer; wird beim Hochladen mit dem Dateinamen abgeglichen + +SubmissionDoneNever: Nie +SubmissionDoneByFile: Je nach Bewertungsdatei +SubmissionDoneAlways: Immer +CorrUploadSubmissionDoneMode: Bewertung abgeschlossen +CorrUploadSubmissionDoneModeTip: Sollen hochgeladene Korrekturen als abgeschlossen markiert werden? Bewertungen sind erst für Studierende sichtbar und zählen gegen Examboni, wenn sie abgeschlossen sind. \ No newline at end of file diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index e5d84055d..7a37a0cae 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -634,8 +634,8 @@ CorrectionTime: Correction time AssignSubmissionsRandomWarning: The assignment preview might be different from the actual assignment if multiple sheets are being distributed. This is due to the fact that only assigned submissions are considered when handling corrector-deficits. Due to this being a randomised process small differences are also possible for a single sheet. AssignSubmissionsAssignableSheets: Distribute corrections for: -CorrectionsUploaded num: Successfully saved #{num} #{pluralEN num "correction" "corrections"}: -NoCorrectionsUploaded: No corrections could be found within the uploaded file. +CorrectionsUploaded num: Successfully saved #{num} #{pluralEN num "correction" "corrections"} +NoCorrectionsUploaded: No corrections could be found within the uploaded files. RatingBy: Marked by HasCorrector: Corrector assigned @@ -2633,3 +2633,9 @@ RatingYAMLChangePassedComment: TODO: Set true or false instead of null (true mea RatingYAMLChangeDoneComment: TODO: Set to true instead of false, when correction is finished; otherwise correction will not be visible to students and won't be counted for exam bonus RatingYAMLChangeCommentComment: TODO: Enter correction comment after the separator below (...) RatingYAMLSubmissionIdComment: Submission id; will be compared to the filename during upload + +SubmissionDoneNever: Never +SubmissionDoneByFile: According to correction file +SubmissionDoneAlways: Always +CorrUploadSubmissionDoneMode: Rating finished +CorrUploadSubmissionDoneModeTip: Should uploaded corrections be marked as finished? The rating is only visible to the submittors and considered for any exam bonuses if it is finished. diff --git a/routes b/routes index 374d94282..81e11801b 100644 --- a/routes +++ b/routes @@ -60,7 +60,7 @@ /health HealthR GET !free /instance InstanceR GET !free /info InfoR GET !free -/info/lecturer InfoLecturerR GET !lecturer +/info/lecturer InfoLecturerR GET !free /info/legal LegalR GET !free /info/allocation InfoAllocationR GET !free /info/glossary GlossaryR GET !free diff --git a/src/Foundation.hs b/src/Foundation.hs index f463eed7b..91d6e4ccc 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -2881,7 +2881,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , NavLink { navLabel = MsgInfoLecturerTitle , navRoute = InfoLecturerR - , navAccess' = return True + , navAccess' = hasWriteAccessTo CourseNewR , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False @@ -3206,7 +3206,7 @@ pageActions InfoR = return { navLink = NavLink { navLabel = MsgInfoLecturerTitle , navRoute = InfoLecturerR - , navAccess' = return True + , navAccess' = hasWriteAccessTo CourseNewR , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False @@ -3252,7 +3252,7 @@ pageActions VersionR = return { navLink = NavLink { navLabel = MsgInfoLecturerTitle , navRoute = InfoLecturerR - , navAccess' = return True + , navAccess' = hasWriteAccessTo CourseNewR , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False @@ -3335,7 +3335,7 @@ pageActions HelpR = return { navLink = NavLink { navLabel = MsgInfoLecturerTitle , navRoute = InfoLecturerR - , navAccess' = return True + , navAccess' = hasWriteAccessTo CourseNewR , navType = NavTypeLink { navModal = False } , navQuick' = mempty , navForceActive = False diff --git a/src/Handler/Submission/Upload.hs b/src/Handler/Submission/Upload.hs index 6884d97ad..baddb6d17 100644 --- a/src/Handler/Submission/Upload.hs +++ b/src/Handler/Submission/Upload.hs @@ -16,27 +16,57 @@ import Data.List (genericLength) import qualified Data.Conduit.List as C +data SubmissionDoneMode + = SubmissionDoneNever + | SubmissionDoneByFile + | SubmissionDoneAlways + deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable) + deriving anyclass (Universe, Finite) +nullaryPathPiece ''SubmissionDoneMode $ camelToPathPiece' 2 +embedRenderMessage ''UniWorX ''SubmissionDoneMode id + + +explainSubmissionDoneMode :: SubmissionDoneMode -> MaybeT Handler Widget +explainSubmissionDoneMode SubmissionDoneNever = return $(i18nWidgetFile "submission-done-tip/never") +explainSubmissionDoneMode SubmissionDoneAlways = return $(i18nWidgetFile "submission-done-tip/always") +explainSubmissionDoneMode SubmissionDoneByFile = return $(i18nWidgetFile "submission-done-tip/by-file") + + getCorrectionsUploadR, postCorrectionsUploadR :: Handler Html getCorrectionsUploadR = postCorrectionsUploadR postCorrectionsUploadR = do - ((uploadRes, upload), uploadEncoding) <- runFormPost . identifyForm FIDcorrectionsUpload . renderAForm FormStandard $ - areq (zipFileField True Nothing) (fslI MsgCorrUploadField) Nothing + ((uploadRes, upload), uploadEncoding) <- runFormPost . identifyForm FIDcorrectionsUpload . renderAForm FormStandard $ (,) + <$> areq (zipFileField True Nothing) (fslI MsgCorrUploadField) Nothing + <*> apopt (explainedSelectionField Nothing $ explainOptionList optionsFinite explainSubmissionDoneMode) (fslI MsgCorrUploadSubmissionDoneMode & setTooltip MsgCorrUploadSubmissionDoneModeTip) (Just SubmissionDoneByFile) - case uploadRes of - FormMissing -> return () - FormFailure errs -> mapM_ (addMessage Error . toHtml) errs - FormSuccess files -> do - uid <- requireAuthId - mbSubs <- msgSubmissionErrors . runDBJobs . runConduit $ transPipe (lift . lift) files .| C.mapM (either get404 return) .| extractRatingsMsg .| sinkMultiSubmission uid True - case mbSubs of - Nothing -> return () - (Just subs) - | null subs -> addMessageI Warning MsgNoCorrectionsUploaded - | otherwise -> do - subs' <- traverse (\x -> (,) <$> encrypt x <*> encrypt x) $ Set.toList subs :: Handler [(CryptoFileNameSubmission, CryptoUUIDSubmission)] - let trigger = [whamlet|_{MsgCorrectionsUploaded (genericLength subs')}|] - content = Right $(widgetFile "messages/correctionsUploaded") - addMessageModal Success trigger content + formResult uploadRes $ \(files, doneMode) -> do + let + setDone (Right (subId, rating)) + = Right ( subId + , rating & _ratingDone %~ setDone' + ) + where setDone' = case doneMode of + SubmissionDoneNever -> const False + SubmissionDoneByFile -> id + SubmissionDoneAlways -> const True + setDone other = other + + uid <- requireAuthId + mbSubs <- msgSubmissionErrors . runDBJobs . runConduit $ + transPipe (lift . lift) files + .| C.mapM (either get404 return) + .| extractRatingsMsg + .| C.map setDone + .| sinkMultiSubmission uid True + + forM_ mbSubs $ \subs -> if + | null subs -> addMessageI Warning MsgNoCorrectionsUploaded + | otherwise -> do + subs' <- traverse (\x -> (,) <$> encrypt x <*> encrypt x) $ Set.toList subs :: Handler [(CryptoFileNameSubmission, CryptoUUIDSubmission)] + let trigger = [whamlet|_{MsgCorrectionsUploaded (genericLength subs')}|] + content = Right $(widgetFile "messages/correctionsUploaded") + addMessageModal Success trigger content + redirect CorrectionsR let uploadForm = wrapForm upload def { formAction = Just $ SomeRoute CorrectionsUploadR diff --git a/src/Utils/Lens.hs b/src/Utils/Lens.hs index 6fe3c61a5..449ad431b 100644 --- a/src/Utils/Lens.hs +++ b/src/Utils/Lens.hs @@ -6,6 +6,7 @@ module Utils.Lens ( module Utils.Lens ) where import Import.NoModel import Model +import Model.Rating import qualified ClassyPrelude.Yesod as Yesod (HasHttpManager(..)) import Control.Lens as Utils.Lens @@ -230,6 +231,8 @@ makeLenses_ ''ExternalExam makeLenses_ ''ExternalExamOfficeSchool makeLenses_ ''ExternalExamStaff makeLenses_ ''ExternalExamResult + +makeLenses_ ''Rating' -- makeClassy_ ''Load diff --git a/templates/i18n/changelog/de-de-formal.hamlet b/templates/i18n/changelog/de-de-formal.hamlet index d99a07eff..d079ca5fa 100644 --- a/templates/i18n/changelog/de-de-formal.hamlet +++ b/templates/i18n/changelog/de-de-formal.hamlet @@ -1,5 +1,12 @@ $newline never
- Das Hochladen einer Korrekturen markiert die entsprechende Abgabe # - automatisch als "korrigiert" (Bewertung abgeschlossen), falls # - Ihnen die Abgabe zugeteilt gewesen war. - -
- - Lädt jedoch ein Assistent Korrekturen hoch, welche anderen # - Korrektoren oder noch nicht zugeteilt wurden, so werden diese # - Abgaben noch nicht als "korrigiert" markiert. + Das aktuelle (YAML-basierte) Format für Bewertungsdatei enthält # + ein Feld, ob die jeweilige Abgabe als „korrigiert“ (Bewertung # + abgeschlossen) markiert werden soll.
@@ -19,15 +13,19 @@ $newline never
- Es ist geplant, dass die Bewertungsdatei in Zukunft ein eigenes # - Feld enthält, in dem Korrektoren angeben können, ob die Korrektur # - abgeschlossen ist oder nicht. + Bei Bewertungsdateien im veralteten Format (nur Text) werden # + Abgaben nur dann automatisch als „korrigiert“ markiert, wenn das # + entsprechende Auswahlfeld („_{MsgCorrUploadSubmissionDoneMode}“) # + auf „_{SubmissionDoneAlways}“ gestellt wird.
- Im Gegensatz zu UniWorX enthalten die heruntergeladenen Abgaben #
- immer den aktuellen Stand der Bewertung. Dies betrifft ggf. auch #
- geänderte Dateien!
+ Die heruntergeladenen Abgaben enthalten immer den aktuellen Stand #
+ der Bewertung.
+
+
@@ -37,8 +35,8 @@ $newline never
diff --git a/templates/i18n/corrections-upload-instructions/en-eu.hamlet b/templates/i18n/corrections-upload-instructions/en-eu.hamlet
index a6644870e..95216437f 100644
--- a/templates/i18n/corrections-upload-instructions/en-eu.hamlet
+++ b/templates/i18n/corrections-upload-instructions/en-eu.hamlet
@@ -3,13 +3,9 @@ $newline never
- Uploading a correction automatically marks it finished iff you #
- were assigned that correction.
-
-
-
- If an administrator that was not assigned the correction uploads #
- it, it will not be marked finished.
+ The current (YAML-based) format for correction files contains a #
+ field determining whether the respective correction should be #
+ marked as finished.
@@ -17,13 +13,15 @@ $newline never
- It is expected that rating files will, in the future, contain a #
- field to mark the correction as finished or not.
+ When using rating files in the legacy format (plaintext only) #
+ corrections will only be marked as finished if the appropriate #
+ selection (“_{MsgCorrUploadSubmissionDoneMode}” set to #
+ “_{SubmissionDoneAlways}”) has been made.
- Contrary to UniWorX downloaded submissions always reflect the #
- current state of the correction.
+ Downloaded submissions always reflect the current state of the #
+ correction.
^{newU2WFeat} Uni2work unterstüzt die Verwaltung von mehreren Instituten, d.h.
- Kursnamen wie "[MATH]" für Kurse des mathematischen Instituts werden ab sofort nicht mehr benötigt.
+ Kursnamen wie "[MATH]" für Kurse des mathematischen Instituts werden nicht mehr benötigt.
Stattdessen gibt es nun Instituts-Filter für Kurslisten.
Die Berechtigungen der Uni2work-Administratoren sind auf Kurse des jeweiligen Instituts eingeschränkt,
@@ -52,7 +52,7 @@ $newline text
In UniWorX gab es die Rolle "Assistent",
@@ -106,7 +106,6 @@ $newline text
^{probFeatInline} Es kann sein, dass ein "gröberer" Studiengang
angezeigt wird, als tatsächlich studiert wird (z.B. Medieninformatik
statt Mensch-Computer-Interaktion).
- Dieses Problem soll demnächst behoben werden.
- In Zukunft sind ein RSS-Feed und (opt-in) E-Mail-Benachrichtigungen
+ In Zukunft sind ein RSS-Feed und E-Mail-Benachrichtigungen
hierfür geplant.
+ Zugeteilte Korrektoren und Kursverwalter haben die Möglichkeit einzelne oder auch Sammlungen von Abgaben als ZIP-Archiv herunterzuladen.
+
+
+ Es wird hierbei jeder Abgabe eine Bewertungsdatei beigelegt.
+
+
+ ^{newU2WFeat} Das Format der Bewertungsdatei ist primär
+ YAML (Englisch)
+ \ und somit maschinell einfach zu interpretieren und zu verändern.
+
+
+ Zusätzlich zum YAML-Teil besteht die Möglichkeit ans Ende der Datei einen Bewertungskommentar für die jeweiligen Studierenden anzuhängen.
+ Alternativ (für maschinelle Bearbeitung) kann ein Feld
+
+ YAML ist kompatibel zu
+ JSON
+ .
+ Bewertungsdateien können also beim Upload durch äquivalente JSON-Dateien (mit den gleichen Feldnamen) ersetzt werden.
+
+
+ Genauer Name und Dateiendung der Bewertungsdateien ist unerheblich; Uni2work prüft nur ob eine valide Abgabennummer teil des Dateinamen ist.
+
- An RSS feed and (opt-in) email notifications for course news are planned in the future.
+ An RSS feed and email notifications for course news are planned in the future.
+ Assigned correctors and course administrators can download submissions or collections thereof as ZIP archives.
+
+ When doing so correction files are added to each submission.
+
+
+ ^{newU2WFeat} Correction files are formatted primarily as
+ YAML
+ \ and are thus easy to parse and edit automatically.
+
+
+
+ Dies betrifft ggf. auch geänderte Dateien!
- Die Abgebenden werden entsprechend informiert, sobald die Abgabe #
- als "korrigiert" markiert wurde.
+ Die Abgebenden werden entsprechend informiert, sobald die #
+ Abgabe als „korrigiert“ markiert wurde.
diff --git a/templates/i18n/info-lecturer/de-de-formal.hamlet b/templates/i18n/info-lecturer/de-de-formal.hamlet
index 80eccd710..189fe4ae3 100644
--- a/templates/i18n/info-lecturer/de-de-formal.hamlet
+++ b/templates/i18n/info-lecturer/de-de-formal.hamlet
@@ -39,7 +39,7 @@ $newline text
+ es gibt keine Eintragung von Korrektoren in der Veranstaltungskonfiguration.
Um reinen Tutoren vorab Zugriff auf Lösungen zu gewähren, sollten diese
als Korrektoren mit Korrekturanteil 0 eingetragen werden.
@@ -152,6 +151,12 @@ $newline text
comment
+ eingefügt werden, dass den Kommentar als String enthält.
+
+ _{MsgInfoLecturerTutorials}
diff --git a/templates/i18n/info-lecturer/en-eu.hamlet b/templates/i18n/info-lecturer/en-eu.hamlet
index 20825bf44..2dfa0f33e 100644
--- a/templates/i18n/info-lecturer/en-eu.hamlet
+++ b/templates/i18n/info-lecturer/en-eu.hamlet
@@ -109,7 +109,7 @@ $newline text
^{newFeat 2019 10 7} On the course overview page, one can directly publish news concerning
the course ("News").