diff --git a/CHANGELOG.md b/CHANGELOG.md index b25b8de72..c4a0f40ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [22.1.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v22.0.0...v22.1.0) (2020-11-10) + + +### Features + +* partial/conditional downloads & video streaming ([5b28303](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/5b28303539e28024b43addb413aedc4e5ee0e470)) + + +### Bug Fixes + +* translation ([80960f4](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/80960f42c578c201f78e226653431e9dd965cfce)) +* **personalised-sheet-files:** don't delete files when "keep" ([6008cb0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/commit/6008cb040dea268e0a096f6c2fafa87f321d115f)) + ## [22.0.0](https://gitlab2.rz.ifi.lmu.de/uni2work/uni2work/compare/v21.1.1...v22.0.0) (2020-11-06) diff --git a/config/settings.yml b/config/settings.yml index f7feda0a3..069b35358 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -35,7 +35,7 @@ notification-expiration: 259200 session-timeout: 7200 bearer-expiration: 604800 bearer-encoding: HS256 -maximum-content-length: "_env:MAX_UPLOAD_SIZE:134217728" +maximum-content-length: "_env:MAX_UPLOAD_SIZE:805306368" session-files-expire: 3600 prune-unreferenced-files-within: 57600 prune-unreferenced-files-interval: 3600 diff --git a/config/video-types b/config/video-types new file mode 100644 index 000000000..361fd28ef --- /dev/null +++ b/config/video-types @@ -0,0 +1,31 @@ +# Simple list of mime-types corresponding to video-formats +# +# Comments are empty lines and any line for which the first non-whitespace symbol is ‘#’ +# +# Format is a single mime-type per line (may not contain whitespace) +# +# Largely copied from https://en.wikipedia.org/wiki/Video_file_format + +video/webm +video/x-matroska +video/x-flv +video/x-f4v +video/ogg +video/x-mng +video/x-msvideo +model/vnd.mts +video/quicktime +video/x-ms-wmv +application/vnd.rn-realmedia +application/vnd.rn-realmedia-vbr +video/vnd.vivo +video/x-ms-asf +video/mp4 +video/mpeg +video/x-m4v +video/3gpp +video/3gpp2 +application/mxf +video/h261 +video/h263 +video/h264 \ No newline at end of file diff --git a/frontend/src/app.sass b/frontend/src/app.sass index 2b492df10..e8602a8e1 100644 --- a/frontend/src/app.sass +++ b/frontend/src/app.sass @@ -1408,6 +1408,19 @@ a.breadcrumbs__home .multi-user-invitation-field__wrapper max-width: 25rem +video + max-width: 100% + max-height: calc(90vh - var(--current-header-height)) + background: black + +.video-container + display: flex + justify-content: center + width: 100% + + & > video + object-fit: contain + flex-grow: 1 table.schedule .schedule--entry diff --git a/messages/uniworx/de-de-formal.msg b/messages/uniworx/de-de-formal.msg index 3eac71060..52c3e656f 100644 --- a/messages/uniworx/de-de-formal.msg +++ b/messages/uniworx/de-de-formal.msg @@ -508,7 +508,7 @@ MaterialVisibleFromTip: Ohne Datum nie sichtbar für Teilnehmer; leer lassen ist MaterialVisibleFromEditWarning: Das Datum der Veröffentlichung liegt in der Vergangenheit und sollte nicht mehr verändert werden, da dies die Benutzer verwirren könnte. MaterialInvisible: Dieses Material ist für Teilnehmer momentan unsichtbar! MaterialFiles: Dateien -MaterialHeading materialName@MaterialName: Material "#{materialName}" +MaterialHeading materialName@MaterialName: #{materialName} MaterialListHeading: Materialien MaterialNewHeading: Neues Material veröffentlichen MaterialNewTitle: Neues Material @@ -521,6 +521,9 @@ MaterialDelHasFiles count@Int64: inklusive #{count} #{pluralDE count "Datei" "Da MaterialIsVisible: Achtung, dieses Material wurde bereits veröffentlicht. MaterialDeleted materialName@MaterialName: Material "#{materialName}" gelöscht MaterialArchiveName tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase materialName} +MaterialVideo materialName@MaterialName: #{materialName} - Video +MaterialVideoUnsupported: Ihr Browser scheint keine eingebetten Videos zu unterstützen +MaterialVideoDownload: Herunterladen Unauthorized: Sie haben hierfür keine explizite Berechtigung. @@ -1088,10 +1091,10 @@ MailCourseRegisteredIntroOther displayName@Text courseName@Text termDesc@Text: # MailSubjectExamResult csh@CourseShorthand examn@ExamName: Ergebnisse für #{examn} in #{csh} wurden herausgegeben MailExamResultIntro courseName@Text termDesc@Text examn@ExamName: Sie können nun Ihr Ergebnis für #{examn} im Kurs #{courseName} (#{termDesc}) einsehen. -MailSubjectExamOfficeExamResults csh@CourseShorthand examn@ExamName: Ergebnisse für #{examn} in #{csh} sind fertiggestellt +MailSubjectExamOfficeExamResults coursen@CourseName examn@ExamName: Ergebnisse für #{examn} in #{coursen} sind fertiggestellt MailExamOfficeExamResultsIntro courseName@Text termDesc@Text examn@ExamName: Ein Kursverwalter hat die Prüfungsleistungen für #{examn} im Kurs #{courseName} (#{termDesc}) freigegeben. -MailSubjectExamOfficeExamResultsChanged csh@CourseShorthand examn@ExamName: Ergebnisse für #{examn} in #{csh} wurden verändert +MailSubjectExamOfficeExamResultsChanged coursen@CourseName examn@ExamName: Ergebnisse für #{examn} in #{coursen} wurden verändert MailExamOfficeExamResultsChangedIntro courseName@Text termDesc@Text examn@ExamName: Ein Kursverwalter hat Prüfungsleistungen für #{examn} im Kurs #{courseName} (#{termDesc}) verändert. MailSubjectExamOfficeExternalExamResults coursen@CourseName examn@ExamName: Ergebnisse für #{examn} in #{coursen} @@ -1518,6 +1521,7 @@ BreadcrumbAllocationInfo: Ablauf einer Zentralanmeldung BreadcrumbCourseParticipantInvitation: Einladung zum Kursteilnehmer BreadcrumbMaterialArchive: Archiv BreadcrumbMaterialFile: Datei +BreadcrumbMaterialVideo: Video BreadcrumbSheetArchive: Dateien BreadcrumbSheetIsCorrector: Korrektor-Überprüfung BreadcrumbSheetPseudonym: Pseudonym diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index 2f7c2707c..7a8855423 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -507,7 +507,7 @@ MaterialVisibleFromTip: Never visible to participants if left empty; leaving the MaterialVisibleFromEditWarning: This course material has already been published and should not be edited. Doing so might confuse the participants. MaterialInvisible: This course material is currently invisible to participants! MaterialFiles: Files -MaterialHeading materialName: Course material “#{materialName}” +MaterialHeading materialName: #{materialName} MaterialListHeading: Course materials MaterialNewHeading: Publish new course material MaterialNewTitle: New course material @@ -520,6 +520,9 @@ MaterialDelHasFiles count: including #{count} #{pluralEN count "file" "files"} MaterialIsVisible: Caution, this course material has already been published. MaterialDeleted materialName: Successfully deleted course material “#{materialName}” MaterialArchiveName tid ssh csh materialName: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase materialName} +MaterialVideo materialName: #{materialName} - Video +MaterialVideoUnsupported: Your browser does not seem to support embedded video +MaterialVideoDownload: Download Unauthorized: You do not have explicit authorisation. UnauthorizedAnd l r: (#{l} AND #{r}) @@ -1089,10 +1092,10 @@ MailCourseRegisteredIntroOther displayName courseName termDesc: #{displayName} w MailSubjectExamResult csh examn: Results for #{examn} in #{csh} are now available MailExamResultIntro courseName termDesc examn: You may now view your result for #{examn} of the course #{courseName} (#{termDesc}). -MailSubjectExamOfficeExamResults csh examn: Results for #{examn} of #{csh} are now available +MailSubjectExamOfficeExamResults coursen examn: Results for #{examn} of #{coursen} are now available MailExamOfficeExamResultsIntro courseName termDesc examn: A course administrator has made the results for #{examn} of the course #{courseName} (#{termDesc}) available. -MailSubjectExamOfficeExamResultsChanged csh examn: Results for #{examn} of #{csh} were changed +MailSubjectExamOfficeExamResultsChanged coursen examn: Results for #{examn} of #{coursen} were changed MailExamOfficeExamResultsChangedIntro courseName termDesc examn: A course administrator has changed exam results for #{examn} of the course #{courseName} (#{termDesc}). MailSubjectExamOfficeExternalExamResults coursen@CourseName examn@ExamName: Results for #{examn} in #{coursen} @@ -1519,6 +1522,7 @@ BreadcrumbAllocationInfo: On central allocations BreadcrumbCourseParticipantInvitation: Invitation to be a course participant BreadcrumbMaterialArchive: Archive BreadcrumbMaterialFile: File +BreadcrumbMaterialVideo: Video BreadcrumbSheetArchive: Files BreadcrumbSheetIsCorrector: Corrector-check BreadcrumbSheetPseudonym: Pseudonym diff --git a/package-lock.json b/package-lock.json index 0edfcdc36..36b02a12e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "22.0.0", + "version": "22.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9e4a74a00..8ae5fcf63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uni2work", - "version": "22.0.0", + "version": "22.1.0", "description": "", "keywords": [], "author": "", diff --git a/package.yaml b/package.yaml index 7d992178d..72ffbece2 100644 --- a/package.yaml +++ b/package.yaml @@ -1,5 +1,5 @@ name: uniworx -version: 22.0.0 +version: 22.1.0 dependencies: - base @@ -8,6 +8,7 @@ dependencies: - yesod-auth - yesod-static - yesod-form + - yesod-persistent - classy-prelude - classy-prelude-yesod - bytestring diff --git a/routes b/routes index 96dfac3d7..0dffa1063 100644 --- a/routes +++ b/routes @@ -181,6 +181,7 @@ /show MShowR GET !timeANDcourse-registered !timeANDmaterialsANDcourse-time !corrector !tutor !/download MArchiveR GET !timeANDcourse-registered !timeANDmaterialsANDcourse-time !corrector !tutor !/download/*FilePath MFileR GET !timeANDcourse-registered !timeANDmaterialsANDcourse-time !corrector !tutor + /video/#CryptoUUIDMaterialFile MVideoR GET !timeANDcourse-registered !timeANDmaterialsANDcourse-time !corrector !tutor /tuts CTutorialListR GET !tutor -- THIS route is used to check for overall course tutor access! /tuts/new CTutorialNewR GET POST /tuts/#TutorialName TutorialR: diff --git a/src/CryptoID.hs b/src/CryptoID.hs index 8884fba25..2c6462321 100644 --- a/src/CryptoID.hs +++ b/src/CryptoID.hs @@ -73,6 +73,7 @@ decCryptoIDs [ ''SubmissionId , ''CourseEventId , ''TutorialId , ''ExternalExamId + , ''MaterialFileId ] decCryptoIDKeySize diff --git a/src/Foundation/Navigation.hs b/src/Foundation/Navigation.hs index 54a33328e..3fce22496 100644 --- a/src/Foundation/Navigation.hs +++ b/src/Foundation/Navigation.hs @@ -299,6 +299,7 @@ instance BearerAuthSite UniWorX => YesodBreadcrumbs UniWorX where MDelR -> i18nCrumb MsgMenuMaterialDelete . Just $ CMaterialR tid ssh csh mnm MShowR MArchiveR -> i18nCrumb MsgBreadcrumbMaterialArchive . Just $ CMaterialR tid ssh csh mnm MShowR MFileR _ -> i18nCrumb MsgBreadcrumbMaterialFile . Just $ CMaterialR tid ssh csh mnm MShowR + MVideoR _ -> i18nCrumb MsgBreadcrumbMaterialVideo . Just $ CMaterialR tid ssh csh mnm MShowR breadcrumb (CourseR tid ssh csh CPersonalFilesR) = i18nCrumb MsgBreadcrumbCourseSheetPersonalisedFiles . Just $ CourseR tid ssh csh CShowR diff --git a/src/Foundation/Yesod/Middleware.hs b/src/Foundation/Yesod/Middleware.hs index 4c6206205..cf4b98db0 100644 --- a/src/Foundation/Yesod/Middleware.hs +++ b/src/Foundation/Yesod/Middleware.hs @@ -155,6 +155,7 @@ routeNormalizers = map (hoist (hoist liftHandler . withReaderT projectBackend) . , verifySubmission , verifyCourseApplication , verifyCourseNews + , verifyMaterialVideo ] where normalizeRender :: Route UniWorX -> WriterT Any (ReaderT SqlReadBackend (HandlerFor UniWorX)) (Route UniWorX) @@ -253,3 +254,12 @@ routeNormalizers = map (hoist (hoist liftHandler . withReaderT projectBackend) . let newRoute = CNewsR courseTerm courseSchool courseShorthand cID sr tell . Any $ route /= newRoute return newRoute + verifyMaterialVideo = maybeOrig $ \route -> do + CMaterialR _tid _ssh _csh _mnm (MVideoR cID) <- return route + mfId <- decrypt cID + MaterialFile{materialFileMaterial} <- lift . lift $ get404 mfId + Material{materialName, materialCourse} <- lift . lift $ get404 materialFileMaterial + Course{courseTerm, courseSchool, courseShorthand} <- lift . lift $ get404 materialCourse + let newRoute = CMaterialR courseTerm courseSchool courseShorthand materialName (MVideoR cID) + tell . Any $ route /= newRoute + return newRoute diff --git a/src/Handler/Material.hs b/src/Handler/Material.hs index 37367fa70..fa6a8db39 100644 --- a/src/Handler/Material.hs +++ b/src/Handler/Material.hs @@ -170,12 +170,33 @@ getMFileR tid ssh csh mnm title = serveOneFile $ fileQuery .| C.map entityVal -- return file entity return matFile +getMVideoR :: TermId -> SchoolId -> CourseShorthand -> MaterialName -> CryptoUUIDMaterialFile -> Handler Html +getMVideoR tid ssh csh mnm cID = do + mfId <- decrypt cID + MaterialFile{..} <- runDB $ get404 mfId + let mimeType = mimeLookup $ pack materialFileTitle + mfile = CMaterialR tid ssh csh mnm $ MFileR materialFileTitle + unless (mimeType `Set.member` videoTypes) $ + redirectWith movedPermanently301 mfile + siteLayout' Nothing $ do + setTitleI . prependCourseTitle tid ssh csh $ MsgMaterialVideo mnm + [whamlet| + $newline never +
+
+