diff --git a/src/Application.hs b/src/Application.hs index 12c92bdeb..490040eed 100644 --- a/src/Application.hs +++ b/src/Application.hs @@ -94,11 +94,11 @@ import Handler.Utils.Routes (classifyHandler) import qualified Data.Acid.Memory as Acid import qualified Web.ServerSession.Backend.Acid as Acid - + import qualified Ldap.Client as Ldap (Host(Plain, Tls)) import qualified Network.Minio as Minio - + import Web.ServerSession.Core (StorageException(..)) import GHC.RTS.Flags (getRTSFlags) @@ -142,7 +142,7 @@ mkYesodDispatch "UniWorX" resourcesUniWorX makeFoundation :: (MonadResource m, MonadUnliftIO m, MonadCatch m) => AppSettings -> m UniWorX makeFoundation appSettings'@AppSettings{..} = do registerGHCMetrics - + -- Some basic initializations: HTTP connection manager, logger, and static -- subsite. appHttpManager <- newManager @@ -356,7 +356,7 @@ makeApplication foundation = liftIO $ makeMiddleware foundation <*> toWaiAppPlai makeMiddleware :: MonadIO m => UniWorX -> m Middleware makeMiddleware app = do logWare <- makeLogWare - return $ observeHTTPRequestLatency classifyHandler . logWare . normalizeCookies . defaultMiddlewaresNoLogging + return $ observeHTTPRequestLatency classifyHandler . logWare . normalizeCookies . defaultMiddlewaresNoLogging where makeLogWare = do logWareMap <- liftIO $ newTVarIO HashMap.empty @@ -391,7 +391,7 @@ makeMiddleware app = do respond $ Wai.mapResponseHeaders (const resHdrs') res where parseSetCookie' :: ByteString -> IO (Maybe SetCookie) parseSetCookie' = fmap (either (\(_ :: SomeException) -> Nothing) Just) . try . evaluate . force . parseSetCookie - + go [] = return [] go (hdr@(hdrName, hdrValue) : hdrs) | hdrName == hSetCookie = do @@ -458,7 +458,7 @@ warpSettings foundation = defaultSettings Just (SessionDoesNotExist{} :: StorageException (AcidStorage SessionMap)) -> False _other -> True ] - + getAppDevSettings, getAppSettings :: MonadIO m => m AppSettings getAppDevSettings = liftIO $ loadYamlSettings [configSettingsYml] [configSettingsYmlValue] useEnv @@ -479,7 +479,7 @@ develMain = runResourceT $ do lift $ threadDelay 100e3 whenM (lift $ doesFileExist "yesod-devel/devel-terminate") $ callCC ($ ()) - + void . liftIO $ installHandler sigINT (Signals.Catch $ return ()) Nothing runAppLoggingT foundation $ handleJobs foundation void . liftIO $ awaitTermination `race` runSettings wsettings app diff --git a/src/Audit.hs b/src/Audit.hs index fb52cb96d..6027f80ea 100644 --- a/src/Audit.hs +++ b/src/Audit.hs @@ -54,7 +54,7 @@ getRemote = handle testHandler $ do guard $ h `elem` ["x-real-ip", "x-forwarded-for"] v' <- either (const mzero) return $ Text.decodeUtf8' v maybeToList $ IP.decode v' - + byRemoteHost wai = case Wai.remoteHost wai of Wai.SockAddrInet _ hAddr -> let (b1, b2, b3, b4) = Wai.hostAddressToTuple hAddr diff --git a/src/Audit/Types.hs b/src/Audit/Types.hs index 573a91af5..7b5757e94 100644 --- a/src/Audit/Types.hs +++ b/src/Audit/Types.hs @@ -23,7 +23,7 @@ data Transaction { transactionExam :: ExamId , transactionUser :: UserId } - + | TransactionExamPartResultEdit { transactionExamPart :: ExamPartId , transactionUser :: UserId @@ -88,7 +88,7 @@ data Transaction { transactionSubmission :: SubmissionId , transactionUser :: UserId } - + | TransactionSubmissionFileEdit { transactionSubmissionFile :: SubmissionFileId , transactionSubmission :: SubmissionId @@ -133,7 +133,7 @@ data Transaction { transactionExternalExam :: ExternalExamId , transactionSchool :: SchoolId } - + | TransactionExternalExamStaffEdit { transactionExternalExam :: ExternalExamId , transactionUser :: UserId diff --git a/src/Auth/Dummy.hs b/src/Auth/Dummy.hs index a1cd8ad3b..859b04554 100644 --- a/src/Auth/Dummy.hs +++ b/src/Auth/Dummy.hs @@ -45,7 +45,7 @@ dummyLogin = AuthPlugin{..} where apName :: Text apName = "dummy" - + apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do ((loginRes, _), _) <- runFormPost $ renderWForm FormStandard dummyForm @@ -62,7 +62,7 @@ dummyLogin = AuthPlugin{..} setCredsRedirect $ Creds apName (CI.original ident) [] apDispatch _ [] = badMethod apDispatch _ _ = notFound - + apLogin :: (Route Auth -> Route site) -> WidgetFor site () apLogin toMaster = do (login, loginEnctype) <- handlerToWidget . generateFormPost $ renderWForm FormStandard dummyForm diff --git a/src/Auth/LDAP.hs b/src/Auth/LDAP.hs index dac6bd1fd..9b57c8904 100644 --- a/src/Auth/LDAP.hs +++ b/src/Auth/LDAP.hs @@ -52,7 +52,7 @@ findUser conf@LdapConf{..} ldap ident retAttrs = fromMaybe [] <$> findM (assertM [ ldapUserDisplayName Ldap.:= Text.encodeUtf8 ident , ldapUserMatriculation Ldap.:= Text.encodeUtf8 ident ] - + findUserMatr :: LdapConf -> Ldap -> Text -> [Ldap.Attr] -> IO [Ldap.SearchEntry] findUserMatr conf@LdapConf{..} ldap userMatr retAttrs = fromMaybe [] <$> findM (assertM (not . null) . lift . flip (Ldap.search ldap ldapBase $ userSearchSettings conf) retAttrs) userFilters where @@ -76,8 +76,8 @@ ldapUserFirstName = Ldap.Attr "givenName" ldapUserSurname = Ldap.Attr "sn" ldapUserTitle = Ldap.Attr "title" ldapUserStudyFeatures = Ldap.Attr "dfnEduPersonFeaturesOfStudy" -ldapUserFieldName = Ldap.Attr "LMU-Stg-Fach" -ldapUserSchoolAssociation = Ldap.Attr "LMU-IFI-eduPersonOrgUnitDNString" +ldapUserFieldName = Ldap.Attr "LMU-Stg-Fach" +ldapUserSchoolAssociation = Ldap.Attr "LMU-IFI-eduPersonOrgUnitDNString" ldapSex = Ldap.Attr "schacGender" ldapUserSubTermsSemester = Ldap.Attr "LMU-Stg-FachundFS" @@ -145,7 +145,7 @@ campusUserMatr pool mode userMatr = either (throwM . CampusUserLdapError) return [] -> throwM CampusUserNoResult [Ldap.SearchEntry _ attrs] -> return attrs _otherwise -> throwM CampusUserAmbiguous - + campusUserMatr' :: (MonadMask m, MonadUnliftIO m, MonadLogger m) => Failover (LdapConf, LdapPool) -> FailoverMode -> UserMatriculation -> m (Maybe (Ldap.AttrList [])) campusUserMatr' pool mode = runMaybeT . catchIfMaybeT (is _CampusUserNoResult) . campusUserMatr pool mode @@ -177,7 +177,7 @@ campusLogin pool mode = AuthPlugin{..} where apName :: Text apName = apLdap - + apDispatch :: forall m. MonadAuthHandler site m => Text -> [Text] -> m TypedContent apDispatch method [] | encodeUtf8 method == methodPost = liftSubHandler $ do ((loginRes, _), _) <- runFormPost $ renderWForm FormStandard campusForm diff --git a/src/Control/Monad/Trans/Memo/StateCache/Instances.hs b/src/Control/Monad/Trans/Memo/StateCache/Instances.hs index e885eb655..5e5d6d977 100644 --- a/src/Control/Monad/Trans/Memo/StateCache/Instances.hs +++ b/src/Control/Monad/Trans/Memo/StateCache/Instances.hs @@ -16,7 +16,7 @@ instance MonadResource m => MonadResource (StateCache c m) where instance MonadLogger m => MonadLogger (StateCache c m) instance MonadLoggerIO m => MonadLoggerIO (StateCache c m) - + instance MonadHandler m => MonadHandler (StateCache c m) where type HandlerSite (StateCache c m) = HandlerSite m type SubHandlerSite (StateCache c m) = SubHandlerSite m diff --git a/src/Cron.hs b/src/Cron.hs index b448bf335..4697c4bf8 100644 --- a/src/Cron.hs +++ b/src/Cron.hs @@ -21,7 +21,7 @@ import qualified Data.Set as Set import Utils.Lens hiding (from, to) - + data CronDate = CronDate { cdYear, cdWeekYear, cdWeekOfYear, cdDayOfYear , cdMonth, cdWeekOfMonth, cdDayOfMonth @@ -101,7 +101,7 @@ instance Alternative CronNextMatch where _ <|> MatchAsap = MatchAsap MatchAsap <|> _ = MatchAsap (MatchAt a) <|> (MatchAt _) = MatchAt a - + listToMatch :: [a] -> CronNextMatch a listToMatch [] = MatchNone @@ -203,7 +203,7 @@ nextCronMatch tz mPrev prec now c@Cron{..} = onlyOnceWithinPrec $ case notAfter in case execRef now False cronInitial of MatchAsap | now < cutoffTime -> MatchAt cutoffTime - MatchAt ts + MatchAt ts | ts < cutoffTime -> MatchAt cutoffTime other -> other CronRepeatScheduled cronNext diff --git a/src/Cron/Types.hs b/src/Cron/Types.hs index 00eec5047..648f44449 100644 --- a/src/Cron/Types.hs +++ b/src/Cron/Types.hs @@ -11,12 +11,12 @@ import ClassyPrelude import Utils.Lens.TH -import Data.Time +import Data.Time import Numeric.Natural import qualified Data.Set as Set - + data CronMatch = CronMatchAny diff --git a/src/Crypto/Hash/Instances.hs b/src/Crypto/Hash/Instances.hs index 27304d542..93bf63516 100644 --- a/src/Crypto/Hash/Instances.hs +++ b/src/Crypto/Hash/Instances.hs @@ -26,7 +26,7 @@ instance HashAlgorithm hash => PersistField (Digest hash) where fromPersistValue _ = Left "Digest values must be converted from PersistByteString or PersistText" instance HashAlgorithm hash => PersistFieldSql (Digest hash) where - sqlType _ = SqlBlob + sqlType _ = SqlBlob instance HashAlgorithm hash => PathPiece (Digest hash) where toPathPiece = showToPathPiece diff --git a/src/CryptoID.hs b/src/CryptoID.hs index a6cfb4d62..cc2f9a2ff 100644 --- a/src/CryptoID.hs +++ b/src/CryptoID.hs @@ -38,7 +38,7 @@ encrypt :: forall plaintext ciphertext m. , Typeable ciphertext , PathPiece plaintext ) - => plaintext -> m (I.CryptoID ciphertext plaintext) + => plaintext -> m (I.CryptoID ciphertext plaintext) encrypt plain = $cachedHereBinary (toPathPiece plain) $ I.encrypt plain decrypt :: forall plaintext ciphertext m. @@ -47,7 +47,7 @@ decrypt :: forall plaintext ciphertext m. , Typeable plaintext , PathPiece ciphertext ) - => I.CryptoID ciphertext plaintext -> m plaintext + => I.CryptoID ciphertext plaintext -> m plaintext decrypt cipher = $cachedHereBinary (toPathPiece $ ciphertext cipher) $ I.decrypt cipher diff --git a/src/Data/CaseInsensitive/Instances.hs b/src/Data/CaseInsensitive/Instances.hs index 2b374fe63..512195097 100644 --- a/src/Data/CaseInsensitive/Instances.hs +++ b/src/Data/CaseInsensitive/Instances.hs @@ -38,7 +38,7 @@ instance PersistField (CI String) where toPersistValue ciText = PersistDbSpecific . Text.encodeUtf8 . pack $ CI.original ciText fromPersistValue (PersistDbSpecific bs) = Right . CI.mk . unpack $ Text.decodeUtf8 bs fromPersistValue x = Left . pack $ "Expected PersistDbSpecific, received: " ++ show x - + instance PersistFieldSql (CI Text) where sqlType _ = SqlOther "citext" diff --git a/src/Data/Fixed/Instances.hs b/src/Data/Fixed/Instances.hs index 7593400e3..fafcba383 100644 --- a/src/Data/Fixed/Instances.hs +++ b/src/Data/Fixed/Instances.hs @@ -16,7 +16,7 @@ import Data.Proxy (Proxy(..)) import Data.Scientific import Data.Scientific.Instances () - + instance HasResolution a => ToMarkup (Fixed a) where toMarkup = toMarkup . showFixed True diff --git a/src/Data/Maybe/Instances.hs b/src/Data/Maybe/Instances.hs index 4b6eaf9e8..28c0e3557 100644 --- a/src/Data/Maybe/Instances.hs +++ b/src/Data/Maybe/Instances.hs @@ -10,4 +10,4 @@ import Text.Blaze (ToMarkup(..), string) instance ToMarkup a => ToMarkup (Maybe a) where toMarkup Nothing = string "" - toMarkup (Just x) = toMarkup x \ No newline at end of file + toMarkup (Just x) = toMarkup x diff --git a/src/Data/MonoTraversable/Instances.hs b/src/Data/MonoTraversable/Instances.hs index 13405c291..dcf89bd63 100644 --- a/src/Data/MonoTraversable/Instances.hs +++ b/src/Data/MonoTraversable/Instances.hs @@ -19,7 +19,7 @@ instance MonoFunctor All where instance MonoPointed Any where opoint = Any - + instance MonoPointed All where opoint = All diff --git a/src/Data/Scientific/Instances.hs b/src/Data/Scientific/Instances.hs index 85c46f844..cee91482d 100644 --- a/src/Data/Scientific/Instances.hs +++ b/src/Data/Scientific/Instances.hs @@ -11,5 +11,5 @@ import Web.PathPieces instance PathPiece Scientific where - toPathPiece = pack . formatScientific Fixed Nothing + toPathPiece = pack . formatScientific Fixed Nothing fromPathPiece = readFromPathPiece diff --git a/src/Data/Sum/Instances.hs b/src/Data/Sum/Instances.hs index 81c99f393..2b92dfcad 100644 --- a/src/Data/Sum/Instances.hs +++ b/src/Data/Sum/Instances.hs @@ -10,4 +10,4 @@ import Data.Monoid (Sum(..)) import Text.Blaze (ToMarkup(..)) instance ToMarkup a => ToMarkup (Sum a) where - toMarkup = toMarkup . getSum \ No newline at end of file + toMarkup = toMarkup . getSum diff --git a/src/Data/UUID/Instances.hs b/src/Data/UUID/Instances.hs index 38b20d104..c75d33ee9 100644 --- a/src/Data/UUID/Instances.hs +++ b/src/Data/UUID/Instances.hs @@ -10,7 +10,7 @@ import qualified Data.UUID as UUID import Database.Persist.Sql import Text.Blaze (ToMarkup(..)) - + instance PathPiece UUID where fromPathPiece = UUID.fromString . unpack diff --git a/src/Data/Universe/Instances/Reverse/MonoTraversable.hs b/src/Data/Universe/Instances/Reverse/MonoTraversable.hs index aaa50ca73..a9153690b 100644 --- a/src/Data/Universe/Instances/Reverse/MonoTraversable.hs +++ b/src/Data/Universe/Instances/Reverse/MonoTraversable.hs @@ -7,11 +7,11 @@ module Data.Universe.Instances.Reverse.MonoTraversable import Data.Universe import Data.MonoTraversable -import Data.Universe.Instances.Reverse - +import Data.Universe.Instances.Reverse + type instance Element (a -> b) = b instance Finite a => MonoFoldable (a -> b) instance (Ord a, Finite a) => MonoTraversable (a -> b) - + diff --git a/src/Data/Universe/TH.hs b/src/Data/Universe/TH.hs index 192182320..03250be58 100644 --- a/src/Data/Universe/TH.hs +++ b/src/Data/Universe/TH.hs @@ -23,7 +23,7 @@ import Data.List (elemIndex) getTVBName :: TyVarBndr -> Name getTVBName (PlainTV name ) = name getTVBName (KindedTV name _) = name - + finiteEnum :: Name -> DecsQ @@ -33,7 +33,7 @@ finiteEnum tName = do let datatype = foldl appT (conT datatypeName) $ map (varT . getTVBName) datatypeVars tUniverse = [e|universeF :: [$(datatype)]|] - + [d| instance Bounded $(datatype) where minBound = head $(tUniverse) diff --git a/src/Database/Esqueleto/Utils.hs b/src/Database/Esqueleto/Utils.hs index 474fe9fe9..43f48be7b 100644 --- a/src/Database/Esqueleto/Utils.hs +++ b/src/Database/Esqueleto/Utils.hs @@ -189,7 +189,7 @@ orderByList :: PersistField a => [a] -> E.SqlExpr (E.Value a) -> E.SqlExpr (E.Va orderByList vals = let sortUni = zip [1..] vals -- memoize this, might not work due to polymorphism in \x -> E.case_ [ (x E.==. E.val u, E.val i) | (i,u) <- sortUni ] (E.val . succ $ List.length vals) - + orderByOrd :: (Ord a, Finite a, PersistField a) => E.SqlExpr (E.Value a) -> E.SqlExpr (E.Value Int) orderByOrd = orderByList $ List.sort universeF @@ -199,12 +199,12 @@ orderByEnum = orderByList $ List.sortOn fromEnum universeF lower :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) lower = E.unsafeSqlFunction "LOWER" - + strip :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) strip = E.unsafeSqlFunction "TRIM" infix 4 `ciEq` - + ciEq :: E.SqlString s => E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value s) -> E.SqlExpr (E.Value Bool) ciEq a b = lower a E.==. lower b @@ -242,7 +242,7 @@ maybe onNothing onJust val = E.case_ (onJust $ E.veryUnsafeCoerceSqlExprValue val) ] (E.else_ onNothing) - + infix 4 `maybeEq` maybeEq :: PersistField a diff --git a/src/Database/Esqueleto/Utils/TH.hs b/src/Database/Esqueleto/Utils/TH.hs index b0c6a3699..988915aa0 100644 --- a/src/Database/Esqueleto/Utils/TH.hs +++ b/src/Database/Esqueleto/Utils/TH.hs @@ -46,7 +46,7 @@ sqlInTuple arity = do xsV <- newName "xs" let - matchE = lam1E (tupP $ map (\vV -> conP 'E.Value [varP vV]) vVs) (foldr1 (\e1 e2 -> [e|$(e1) E.&&. $(e2)|]) . map (\(varE -> vE, varE -> xE) -> [e|E.val $(vE) `sqlEq` $(xE)|]) $ zip vVs xVs) + matchE = lam1E (tupP $ map (\vV -> conP 'E.Value [varP vV]) vVs) (foldr1 (\e1 e2 -> [e|$(e1) E.&&. $(e2)|]) $ zipWith (\(varE -> vE) (varE -> xE) -> [e|E.val $(vE) `sqlEq` $(xE)|]) vVs xVs) tupTy f = foldl (\typ v -> typ `appT` f (varT v)) (tupleT arity) tyVars instanceD (cxt $ map (\v -> [t|SqlEq $(varT v)|]) tyVars) [t|SqlIn $(tupTy $ \v -> [t|E.SqlExpr (E.Value $(v))|]) $(tupTy $ \v -> [t|E.Value $(v)|])|] diff --git a/src/Database/Persist/TH/Directory.hs b/src/Database/Persist/TH/Directory.hs index 66966913c..f0395102b 100644 --- a/src/Database/Persist/TH/Directory.hs +++ b/src/Database/Persist/TH/Directory.hs @@ -18,13 +18,13 @@ import qualified System.Directory.Tree as DirTree import Control.Monad.Trans.Maybe (MaybeT(MaybeT), runMaybeT) import Control.Lens - + persistDirectoryWith :: PersistSettings -> FilePath -> Q Exp persistDirectoryWith settings dir = do files <- runIO . flip DirTree.readDirectoryWith dir $ \fp -> runMaybeT $ do fn <- MaybeT . return . fromNullable $ takeFileName fp - guard . not $ head fn == '.' + guard $ head fn /= '.' guard . not $ head fn == '#' && last fn == '#' lift $ do @@ -32,5 +32,5 @@ persistDirectoryWith settings dir = do SIO.hSetEncoding h SIO.utf8_bom Text.hGetContents h mapM_ qAddDependentFile . toListOf (traverse . filtered (has $ _2 . _Just) . _1) $ DirTree.zipPaths files - + parseReferences settings . Text.intercalate "\n" . toListOf (traverse . _Just) $ DirTree.dirTree files diff --git a/src/Foundation.hs b/src/Foundation.hs index c2809cab3..1388997c0 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -15,7 +15,8 @@ import Foundation.Routes as Foundation import Import.NoFoundation hiding (embedFile) -import Database.Persist.Sql (runSqlPool) +import Database.Persist.Sql + ( runSqlPool, transactionUndo, SqlReadBackend(..) ) import Text.Hamlet (hamletFile) import Yesod.Auth.Message @@ -105,7 +106,6 @@ import qualified Web.ServerSession.Frontend.Yesod.Jwt as JwtSession import Web.Cookie import Yesod.Core.Types (GHState(..), HandlerData(..), HandlerContents, RunHandlerEnv(rheSite, rheChild)) -import Database.Persist.Sql (transactionUndo, SqlReadBackend(..)) import qualified Control.Retry as Retry import GHC.IO.Exception (IOErrorType(OtherError)) @@ -196,7 +196,7 @@ data Nav makeLenses_ ''Nav makePrisms ''Nav - + data NavChildren type instance Children NavChildren a = ChildrenNavChildren a type family ChildrenNavChildren a where @@ -217,13 +217,13 @@ navLinkAccess NavLink{..} = handle shortCircuit $ liftHandler navAccess' `and2M` where shortCircuit :: HandlerContents -> m Bool shortCircuit _ = return False - + accessCheck :: HasRoute UniWorX route => NavType -> route -> m Bool accessCheck nt (urlRoute -> route) = do authCtx <- getAuthContext $memcachedByHere (Just $ Right 120) (authCtx, nt, route) $ bool hasWriteAccessTo hasReadAccessTo (is _NavTypeLink nt) route - + getTimeLocale' :: [Lang] -> TimeLocale getTimeLocale' = $(timeLocaleMap [("de-de", "de_DE.utf8"), ("en-GB", "en_GB.utf8")]) @@ -244,7 +244,7 @@ appLanguagesOpts = do } langOptions = map mkOption $ toList appLanguages return $ mkOptionList langOptions - + instance RenderMessage UniWorX WeekDay where renderMessage _ ls wDay = pack . fst $ wDays (getTimeLocale' ls) !! (fromEnum wDay `mod` 7) @@ -419,7 +419,7 @@ requireCurrentBearerRestrictions = runMaybeT $ do bearer <- requireBearerToken route <- MaybeT getCurrentRoute hoistMaybe $ bearer ^? _bearerRestrictionIx route - + maybeCurrentBearerRestrictions :: forall a m. ( MonadHandler m , HandlerSite m ~ UniWorX @@ -450,7 +450,7 @@ isDryRun = $cachedHere $ orM mAuthId <- maybeAuthId currentRoute <- maybe (permissionDeniedI MsgUnauthorizedToken404) return =<< getCurrentRoute isWrite <- isWriteRequest currentRoute - + let noTokenAuth :: AuthDNF -> AuthDNF noTokenAuth = over _dnfTerms . Set.filter . noneOf (re _nullable . folded) $ (== AuthToken) . plVar @@ -528,7 +528,7 @@ tagAccessPredicate AuthExamOffice = APDB $ \mAuthId route _ -> case route of E.&&. eexam E.^. ExternalExamSchool E.==. E.val ssh E.&&. eexam E.^. ExternalExamCourseName E.==. E.val coursen E.&&. eexam E.^. ExternalExamExamName E.==. E.val examn - + E.where_ $ examOfficeExternalExamResultAuth (E.val authId) eexamResult guardMExceptT hasUsers $ unauthorizedI MsgUnauthorizedExternalExamExamOffice return Authorized @@ -635,7 +635,7 @@ tagAccessPredicate AuthCorrector = APDB $ \mAuthId route _ -> exceptT return ret CSubmissionR _ _ _ _ cID _ -> $cachedHereBinary (mAuthId, cID) . maybeT (unauthorizedI MsgUnauthorizedSubmissionCorrector) $ do sid <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID Submission{..} <- MaybeT . lift $ get sid - guard $ maybe False (== authId) submissionRatingBy + guard $ Just authId == submissionRatingBy return Authorized CSheetR tid ssh csh shn _ -> $cachedHereBinary (mAuthId, tid, ssh, csh, shn) . maybeT (unauthorizedI MsgUnauthorizedSheetCorrector) $ do Entity cid _ <- MaybeT . lift . getBy $ TermSchoolCourseShort tid ssh csh @@ -715,7 +715,7 @@ tagAccessPredicate AuthSubmissionGroup = APDB $ \mAuthId route _ -> case route o E.on $ submissionGroupUser E.^. SubmissionGroupUserSubmissionGroup E.==. submissionGroup E.^. SubmissionGroupId E.where_ $ submissionGroup E.^. SubmissionGroupCourse E.==. E.val course E.&&. submissionGroupUser E.^. SubmissionGroupUserUser E.==. E.val uid - + return Authorized r -> $unsupportedAuthPredicate AuthSubmissionGroup r tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of @@ -742,7 +742,7 @@ tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of -> guard $ visible && NTop (Just cTime) <= NTop examDeregisterUntil ERegisterOccR occn -> do - occId <- (>>= hoistMaybe) . $cachedHereBinary (eId, occn) . lift . getKeyBy $ UniqueExamOccurrence eId occn + occId <- hoistMaybe <=< $cachedHereBinary (eId, occn) . lift . getKeyBy $ UniqueExamOccurrence eId occn if | (registration >>= examRegistrationOccurrence . entityVal) == Just occId -> guard $ visible @@ -850,7 +850,7 @@ tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of guard $ NTop (Just now) <= NTop deregUntil return Authorized _other -> unauthorizedI MsgUnauthorizedCourseTime - + CApplicationR tid ssh csh _ _ -> maybeT (unauthorizedI MsgUnauthorizedApplicationTime) $ do Entity course Course{..} <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getBy $ TermSchoolCourseShort tid ssh csh allocationCourse <- $cachedHereBinary course . lift . getBy $ UniqueAllocationCourse course @@ -879,7 +879,7 @@ tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of MessageR cID -> maybeT (unauthorizedI MsgUnauthorizedSystemMessageTime) $ do smId <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID SystemMessage{systemMessageFrom, systemMessageTo} <- $cachedHereBinary smId . MaybeT $ get smId - cTime <- (NTop . Just) <$> liftIO getCurrentTime + cTime <- NTop . Just <$> liftIO getCurrentTime guard $ NTop systemMessageFrom <= cTime && NTop systemMessageTo >= cTime return Authorized @@ -887,7 +887,7 @@ tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of MessageHideR cID -> maybeT (unauthorizedI MsgUnauthorizedSystemMessageTime) $ do smId <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID SystemMessage{systemMessageFrom, systemMessageTo} <- $cachedHereBinary smId . MaybeT $ get smId - cTime <- (NTop . Just) <$> liftIO getCurrentTime + cTime <- NTop . Just <$> liftIO getCurrentTime guard $ NTop systemMessageFrom <= cTime && NTop systemMessageTo >= cTime return Authorized @@ -895,7 +895,7 @@ tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of CNewsR _ _ _ cID _ -> maybeT (unauthorizedI MsgUnauthorizedCourseNewsTime) $ do nId <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID CourseNews{courseNewsVisibleFrom} <- $cachedHereBinary nId . MaybeT $ get nId - cTime <- (NTop . Just) <$> liftIO getCurrentTime + cTime <- NTop . Just <$> liftIO getCurrentTime guard $ NTop courseNewsVisibleFrom <= cTime return Authorized @@ -1195,7 +1195,7 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of when onlyActive $ E.where_ $ courseParticipant E.^. CourseParticipantState E.==. E.val CourseParticipantActive -- participant has at least one submission - when (not onlyActive) $ + unless onlyActive $ mapExceptT ($cachedHereBinary (participant, tid, ssh, csh)) . authorizedIfExists $ \(course `E.InnerJoin` sheet `E.InnerJoin` submission `E.InnerJoin` submissionUser) -> do E.on $ submission E.^. SubmissionId E.==. submissionUser E.^. SubmissionUserSubmission E.on $ sheet E.^. SheetId E.==. submission E.^. SubmissionSheet @@ -1205,7 +1205,7 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh -- participant is member of a submissionGroup - when (not onlyActive) $ + unless onlyActive $ mapExceptT ($cachedHereBinary (participant, tid, ssh, csh)) . authorizedIfExists $ \(course `E.InnerJoin` submissionGroup `E.InnerJoin` submissionGroupUser) -> do E.on $ submissionGroup E.^. SubmissionGroupId E.==. submissionGroupUser E.^. SubmissionGroupUserSubmissionGroup E.on $ course E.^. CourseId E.==. submissionGroup E.^. SubmissionGroupCourse @@ -1222,7 +1222,7 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh -- participant is a tutorial user - when (not onlyActive) $ + unless onlyActive $ mapExceptT ($cachedHereBinary (participant, tid, ssh, csh)) . authorizedIfExists $ \(course `E.InnerJoin` tutorial `E.InnerJoin` tutorialUser) -> do E.on $ tutorial E.^. TutorialId E.==. tutorialUser E.^. TutorialParticipantTutorial E.on $ course E.^. CourseId E.==. tutorial E.^. TutorialCourse @@ -1254,7 +1254,7 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh -- participant has an exam result for this course - when (not onlyActive) $ + unless onlyActive $ mapExceptT ($cachedHereBinary (participant, tid, ssh, csh)) . authorizedIfExists $ \(course `E.InnerJoin` exam `E.InnerJoin` examResult) -> do E.on $ examResult E.^. ExamResultExam E.==. exam E.^. ExamId E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse @@ -1263,7 +1263,7 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh -- participant is registered for an exam for this course - when (not onlyActive) $ + unless onlyActive $ mapExceptT ($cachedHereBinary (participant, tid, ssh, csh)) . authorizedIfExists $ \(course `E.InnerJoin` exam `E.InnerJoin` examRegistration) -> do E.on $ examRegistration E.^. ExamRegistrationExam E.==. exam E.^. ExamId E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse @@ -1271,21 +1271,19 @@ tagAccessPredicate AuthParticipant = APDB $ \mAuthId route _ -> case route of E.&&. course E.^. CourseTerm E.==. E.val tid E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh - - return () tagAccessPredicate AuthApplicant = APDB $ \mAuthId route _ -> case route of CourseR tid ssh csh (CUserR cID) -> maybeT (unauthorizedI MsgUnauthorizedApplicant) $ do - uid <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID + uid <- catchIfMaybeT (const True :: CryptoIDError -> Bool) $ decrypt cID isApplicant <- isCourseApplicant tid ssh csh uid guard isApplicant return Authorized - + CourseR tid ssh csh _ -> maybeT (unauthorizedI MsgUnauthorizedApplicantSelf) $ do uid <- hoistMaybe mAuthId isApplicant <- isCourseApplicant tid ssh csh uid guard isApplicant return Authorized - + r -> $unsupportedAuthPredicate AuthApplicant r where isCourseApplicant tid ssh csh uid = lift . $cachedHereBinary (uid, tid, ssh, csh) . E.selectExists . E.from $ \(course `E.InnerJoin` courseApplication) -> do @@ -1628,10 +1626,10 @@ instance Yesod UniWorX where makeSessionBackend app@UniWorX{ appSettings' = AppSettings{..}, ..} = notForBearer . sameSite $ case appSessionStore of SessionStorageMemcachedSql sqlStore - -> mkBackend =<< stateSettings <$> ServerSession.createState sqlStore + -> mkBackend . stateSettings =<< ServerSession.createState sqlStore SessionStorageAcid acidStore | appServerSessionAcidFallback - -> mkBackend =<< stateSettings <$> ServerSession.createState acidStore + -> mkBackend . stateSettings =<< ServerSession.createState acidStore _other -> return Nothing where @@ -1664,7 +1662,7 @@ instance Yesod UniWorX where notForBearer' (SessionBackend load) = let load' req | aHdrs <- mapMaybe (\(h, v) -> v <$ guard (h == W.hAuthorization)) $ W.requestHeaders req - , any (is _Just) $ map W.extractBearerAuth aHdrs + , any (is _Just . W.extractBearerAuth) aHdrs = return (mempty, const $ return []) | otherwise = load req @@ -1686,7 +1684,7 @@ instance Yesod UniWorX where dryRun <- isDryRun if | dryRun -> do hData <- ask - prevState <- readIORef (handlerState hData) + prevState <- readIORef (handlerState hData) let restoreSession = modifyIORef (handlerState hData) $ @@ -1698,7 +1696,7 @@ instance Yesod UniWorX where handler' = local (\hd -> hd { handlerEnv = (handlerEnv hd) { rheSite = site', rheChild = site' } }) handler addCustomHeader HeaderDryRun ("1" :: Text) - + handler' `finally` restoreSession | otherwise -> handler updateFavouritesMiddleware :: Handler a -> Handler a @@ -1893,7 +1891,7 @@ updateFavourites :: forall m. (MonadHandler m, HandlerSite m ~ UniWorX) updateFavourites cData = void . runMaybeT $ do $logDebugS "updateFavourites" "Updating favourites" - now <- liftIO $ getCurrentTime + now <- liftIO getCurrentTime uid <- MaybeT $ liftHandler maybeAuthId mcid <- for cData $ \(tid, ssh, csh) -> MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh User{userMaxFavourites} <- MaybeT $ get uid @@ -2004,7 +2002,7 @@ siteLayout' headingOverride widget = do [ E.when_ isCurrent E.then_ . E.just $ E.val FavouriteCurrent , E.when_ isAssociated E.then_ . E.just $ E.val FavouriteParticipant ] (E.else_ $ courseFavourite E.?. CourseFavouriteReason) - + E.where_ $ ((isFavourite E.||. isAssociated) E.&&. notBlacklist) E.||. isCurrent return (course, reason) @@ -2016,7 +2014,7 @@ siteLayout' headingOverride widget = do let favouriteTerms :: [TermIdentifier] favouriteTerms = take maxFavouriteTerms . Set.toDescList $ foldMap (\(Entity _ Course{..}, _) -> Set.singleton $ unTermKey courseTerm) favourites' - + favourites <- fmap catMaybes . forM favourites' $ \(Entity cId c@Course{..}, E.Value mFavourite) -> let courseRoute = CourseR courseTerm courseSchool courseShorthand CShowR favouriteReason = fromMaybe FavouriteCurrent mFavourite @@ -2028,7 +2026,7 @@ siteLayout' headingOverride widget = do $logDebugS "FavouriteQuickActions" $ tshow cK <> " Checking..." items <- memcachedLimitedKeyTimeoutBy MemcachedLimitKeyFavourites appFavouritesQuickActionsBurstsize appFavouritesQuickActionsAvgInverseRate 1 - (Right <$> appFavouritesQuickActionsCacheTTL) + (Right <$> appFavouritesQuickActionsCacheTTL) appFavouritesQuickActionsTimeout cK cK @@ -2241,7 +2239,7 @@ getSystemMessageState smId = liftHandler $ do applySystemMessages :: (MonadHandler m, HandlerSite m ~ UniWorX) => m () applySystemMessages = liftHandler . maybeT_ . catchMPlus (Proxy @CryptoIDError) $ do lift $ maybeAuthId >>= traverse_ syncSystemMessageHidden - + cRoute <- lift getCurrentRoute guard $ cRoute /= Just NewsR @@ -2258,14 +2256,14 @@ applySystemMessages = liftHandler . maybeT_ . catchMPlus (Proxy @CryptoIDError) , systemMessageHiddenTime } [ SystemMessageHiddenTime =. systemMessageHiddenTime ] - + when (maybe False (maybe (const True) (<=) userSystemMessageHidden) userSystemMessageUnhidden) $ do deleteBy $ UniqueSystemMessageHidden uid smId modifyRegisteredCookieJson CookieSystemMessageState $ \(fold -> MergeHashMap hm) -> fmap MergeHashMap . assertM' (/= mempty) $ HashMap.update (\smSt' -> assertM' (/= mempty) $ smSt' { userSystemMessageHidden = Nothing, userSystemMessageUnhidden = Nothing }) cID hm - + applyMessage (Entity smId SystemMessage{..}) = maybeT_ $ do guard $ not systemMessageNewsOnly @@ -2325,7 +2323,7 @@ instance YesodBreadcrumbs UniWorX where User{..} <- MaybeT . runDB $ get uid return (userDisplayName, Just UsersR) breadcrumb (AdminUserDeleteR cID) = i18nCrumb MsgBreadcrumbUserDelete . Just $ AdminUserR cID - breadcrumb (AdminHijackUserR cID) = i18nCrumb MsgBreadcrumbUserHijack . Just $ AdminUserR cID + breadcrumb (AdminHijackUserR cID) = i18nCrumb MsgBreadcrumbUserHijack . Just $ AdminUserR cID breadcrumb (UserNotificationR cID) = do mayList <- hasReadAccessTo UsersR if @@ -2344,12 +2342,12 @@ instance YesodBreadcrumbs UniWorX where breadcrumb AdminFunctionaryInviteR = i18nCrumb MsgBreadcrumbFunctionaryInvite Nothing breadcrumb AdminR = i18nCrumb MsgAdminHeading Nothing - breadcrumb AdminFeaturesR = i18nCrumb MsgAdminFeaturesHeading $ Just AdminR + breadcrumb AdminFeaturesR = i18nCrumb MsgAdminFeaturesHeading $ Just AdminR breadcrumb AdminTestR = i18nCrumb MsgMenuAdminTest $ Just AdminR breadcrumb AdminErrMsgR = i18nCrumb MsgMenuAdminErrMsg $ Just AdminR breadcrumb AdminTokensR = i18nCrumb MsgMenuAdminTokens $ Just AdminR breadcrumb AdminCrontabR = i18nCrumb MsgBreadcrumbAdminCrontab $ Just AdminR - + breadcrumb SchoolListR = i18nCrumb MsgMenuSchoolList $ Just AdminR breadcrumb (SchoolR ssh SchoolEditR) = maybeT (i18nCrumb MsgBreadcrumbSchool $ Just SchoolListR) $ do School{..} <- MaybeT . runDB $ get ssh @@ -2403,12 +2401,12 @@ instance YesodBreadcrumbs UniWorX where AShowR -> maybeT (i18nCrumb MsgBreadcrumbAllocation $ Just AllocationListR) $ do mr <- getMessageRender Entity _ Allocation{allocationName} <- MaybeT . runDB . getBy $ TermSchoolAllocationShort tid ssh ash - return ([st|#{allocationName} (#{mr (ShortTermIdentifier (unTermKey tid))}, #{CI.original (unSchoolKey ssh)})|], Just $ AllocationListR) + return ([st|#{allocationName} (#{mr (ShortTermIdentifier (unTermKey tid))}, #{CI.original (unSchoolKey ssh)})|], Just AllocationListR) ARegisterR -> i18nCrumb MsgBreadcrumbAllocationRegister . Just $ AllocationR tid ssh ash AShowR AApplyR cID -> maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ AllocationR tid ssh ash AShowR) $ do cid <- decrypt cID Course{..} <- hoist runDB $ do - aid <- MaybeT . getKeyBy $ TermSchoolAllocationShort tid ssh ash + aid <- MaybeT . getKeyBy $ TermSchoolAllocationShort tid ssh ash guardM . lift $ exists [ AllocationCourseAllocation ==. aid, AllocationCourseCourse ==. cid ] MaybeT $ get cid return (CI.original courseName, Just $ AllocationR tid ssh ash AShowR) @@ -2460,7 +2458,7 @@ instance YesodBreadcrumbs UniWorX where CNDeleteR -> i18nCrumb MsgBreadcrumbCourseNewsDelete . Just $ CNewsR tid ssh csh cID CNShowR CNArchiveR -> i18nCrumb MsgBreadcrumbCourseNewsArchive . Just $ CNewsR tid ssh csh cID CNShowR CNFileR _ -> i18nCrumb MsgBreadcrumbCourseNewsFile . Just $ CNewsR tid ssh csh cID CNShowR - + breadcrumb (CourseR tid ssh csh CEventsNewR) = i18nCrumb MsgMenuCourseEventNew . Just $ CourseR tid ssh csh CShowR breadcrumb (CourseR tid ssh csh (CourseEventR _cID sRoute)) = case sRoute of CEvEditR -> i18nCrumb MsgMenuCourseEventEdit . Just $ CourseR tid ssh csh CShowR @@ -2554,7 +2552,7 @@ instance YesodBreadcrumbs UniWorX where breadcrumb CorrectionsDownloadR = i18nCrumb MsgMenuCorrectionsDownload $ Just CorrectionsR breadcrumb (CryptoUUIDDispatchR _) = i18nCrumb MsgBreadcrumbCryptoIDDispatch Nothing - + breadcrumb (MessageR _) = do mayList <- (== Authorized) <$> evalAccess MessageListR False if @@ -2581,9 +2579,9 @@ instance YesodBreadcrumbs UniWorX where | otherwise -> EExamListR EEEditR -> i18nCrumb MsgBreadcrumbExternalExamEdit . Just $ EExamR tid ssh coursen examn EEShowR EEUsersR -> i18nCrumb MsgBreadcrumbExternalExamUsers . Just $ EExamR tid ssh coursen examn EEShowR - EEGradesR -> i18nCrumb MsgBreadcrumbExternalExamGrades . Just $ EExamR tid ssh coursen examn EEShowR - EEStaffInviteR -> i18nCrumb MsgBreadcrumbExternalExamStaffInvite . Just $ EExamR tid ssh coursen examn EEShowR - + EEGradesR -> i18nCrumb MsgBreadcrumbExternalExamGrades . Just $ EExamR tid ssh coursen examn EEShowR + EEStaffInviteR -> i18nCrumb MsgBreadcrumbExternalExamStaffInvite . Just $ EExamR tid ssh coursen examn EEShowR + -- breadcrumb _ = return ("Uni2work", Nothing) -- Default is no breadcrumb at all submissionList :: TermId -> CourseShorthand -> SheetName -> UserId -> DB [E.Value SubmissionId] @@ -2666,7 +2664,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the } , do mCurrentRoute <- getCurrentRoute - + return NavHeader { navHeaderRole = NavHeaderSecondary , navIcon = IconMenuHelp @@ -2678,7 +2676,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the , navQuick' = mempty , navForceActive = False } - } + } , return $ NavFooter NavLink { navLabel = MsgMenuDataProt , navRoute = LegalR :#: ("data-protection" :: Text) @@ -2787,7 +2785,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the { navHeaderRole = NavHeaderPrimary , navLabel = SomeMessage MsgAdminHeading , navIcon = IconMenuAdmin - , navChildren = + , navChildren = [ NavLink { navLabel = MsgMenuUsers , navRoute = UsersR @@ -2858,7 +2856,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the { navHeaderRole = NavHeaderPrimary , navLabel = SomeMessage (mempty :: Text) , navIcon = IconMenuExtra - , navChildren = + , navChildren = [ NavLink { navLabel = MsgMenuCourseNew , navRoute = CourseNewR @@ -3084,7 +3082,7 @@ pageActions (CourseR tid ssh csh CShowR) = do , navAccess' = do uid <- requireAuthId runDB $ do - cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh + cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh E.selectExists $ do (_school, isForced) <- courseExamOfficeSchools (E.val uid) (E.val cid) E.where_ $ E.not_ isForced @@ -3362,7 +3360,7 @@ pageActions HelpR = return , ("allocations", MsgInfoLecturerAllocations) ] :: [(Text, UniWorXMessage)] return NavLink - { navLabel + { navLabel , navRoute = InfoLecturerR :#: section , navAccess' = return True , navType = NavTypeLink { navModal = False } @@ -3477,7 +3475,7 @@ pageActions (AllocationR tid ssh ash AShowR) = return } , navChildren = [] } - ] + ] pageActions (AllocationR tid ssh ash AUsersR) = return [ NavPageActionPrimary { navLink = NavLink @@ -3501,7 +3499,7 @@ pageActions (AllocationR tid ssh ash AUsersR) = return } , navChildren = [] } - ] + ] pageActions CourseListR = do participantsSecondary <- pageQuickActions NavQuickViewPageActionSecondary ParticipantsListR return @@ -3538,7 +3536,7 @@ pageActions CourseListR = do } , navChildren = participantsSecondary } - ] + ] pageActions CourseNewR = return [ NavPageActionPrimary { navLink = NavLink @@ -3578,14 +3576,13 @@ pageActions (CourseR tid ssh csh CCorrectionsR) = return case muid of Nothing -> return False (Just uid) -> do - ok <- runDB . E.selectExists . E.from $ \(course `E.InnerJoin` sheet `E.InnerJoin` submission) -> do + runDB . E.selectExists . E.from $ \(course `E.InnerJoin` sheet `E.InnerJoin` submission) -> do E.on $ submission E.^. SubmissionSheet E.==. sheet E.^. SheetId E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId E.where_ $ submission E.^. SubmissionRatingBy E.==. E.just (E.val uid) E.&&. course E.^. CourseTerm E.==. E.val tid E.&&. course E.^. CourseSchool E.==. E.val ssh E.&&. course E.^. CourseShorthand E.==. E.val csh - return ok , navType = NavTypeLink { navModal = False } , navQuick' = navQuick NavQuickViewPageActionSecondary , navForceActive = False @@ -3609,7 +3606,7 @@ pageActions (CourseR tid ssh csh SheetListR) = do , navChildren = correctionsSecondary } showCorrections <- maybeT (return False) $ True <$ navAccess navCorrections - + return $ [ NavPageActionPrimary { navLink = NavLink @@ -3956,7 +3953,7 @@ pageActions (CSheetR tid ssh csh shn SShowR) = do , navChildren = subsSecondary } showSubmissions <- maybeT (return False) $ True <$ navAccess navSubmissions - + return $ [ NavPageActionPrimary { navLink = NavLink @@ -4373,19 +4370,19 @@ pageHeading UsersR = Just $ i18nHeading MsgUsers pageHeading (AdminUserR _) = Just $ i18nHeading MsgAdminUserHeading -pageHeading (AdminTestR) - = Just $ [whamlet|Internal Code Demonstration Page|] -pageHeading (AdminErrMsgR) +pageHeading AdminTestR + = Just [whamlet|Internal Code Demonstration Page|] +pageHeading AdminErrMsgR = Just $ i18nHeading MsgErrMsgHeading -pageHeading (InfoR) +pageHeading InfoR = Just $ i18nHeading MsgInfoHeading -pageHeading (LegalR) +pageHeading LegalR = Just $ i18nHeading MsgLegalHeading -pageHeading (VersionR) +pageHeading VersionR = Just $ i18nHeading MsgVersionHeading -pageHeading (HelpR) +pageHeading HelpR = Just $ i18nHeading MsgHelpRequest pageHeading ProfileR @@ -4408,8 +4405,8 @@ pageHeading (TermSchoolCourseListR tid ssh) School{schoolName=school} <- handlerToWidget $ runDB $ get404 ssh i18nHeading $ MsgTermSchoolCourseListHeading tid school -pageHeading (CourseListR) - = Just $ i18nHeading $ MsgCourseListTitle +pageHeading CourseListR + = Just $ i18nHeading MsgCourseListTitle pageHeading CourseNewR = Just $ i18nHeading MsgCourseNewHeading pageHeading (CourseR tid ssh csh CShowR) @@ -4585,7 +4582,7 @@ runSqlPoolRetry :: forall m a backend. => ReaderT backend m a -> Pool backend -> m a -runSqlPoolRetry action pool = do +runSqlPoolRetry action pool = do let policy = Retry.fullJitterBackoff 1e3 & Retry.limitRetriesByCumulativeDelay 10e6 handlers = Retry.skipAsyncExceptions `snoc` Retry.logRetries suggestRetry logRetry where suggestRetry :: IOException -> m Bool @@ -4608,7 +4605,7 @@ runSqlPoolRetry action pool = do runDBRead :: ReaderT SqlReadBackend Handler a -> Handler a runDBRead action = do $logDebugS "YesodPersist" "runDBRead" - runSqlPoolRetry (withReaderT SqlReadBackend action) =<< appConnPool <$> getYesod + runSqlPoolRetry (withReaderT SqlReadBackend action) . appConnPool =<< getYesod -- How to run database actions. instance YesodPersist UniWorX where @@ -4622,7 +4619,7 @@ instance YesodPersist UniWorX where | dryRun = action <* transactionUndo | otherwise = action - runSqlPoolRetry action' =<< appConnPool <$> getYesod + runSqlPoolRetry action' . appConnPool =<< getYesod instance YesodPersistRunner UniWorX where getDBRunner = do @@ -4774,7 +4771,7 @@ upsertCampusUser plugin ldapData = do -- , UserDisplayName =. userDisplayName , UserFirstName =. userFirstName , UserSurname =. userSurname - , UserTitle =. userTitle + , UserTitle =. userTitle , UserEmail =. userEmail , UserSex =. userSex , UserLastLdapSynchronisation =. Just now @@ -4852,7 +4849,7 @@ upsertCampusUser plugin ldapData = do knownParents <- lift $ map (studySubTermsParent . entityVal) <$> selectList [ StudySubTermsChild ==. subterm ] [] let matchingFeatures = case knownParents of [] -> filter ((== subSemester) . studyFeaturesSemester) unusedFeats - ps -> filter (\StudyFeatures{studyFeaturesField, studyFeaturesSemester} -> any (== studyFeaturesField) ps && studyFeaturesSemester == subSemester) unusedFeats + ps -> filter (\StudyFeatures{studyFeaturesField, studyFeaturesSemester} -> elem studyFeaturesField ps && studyFeaturesSemester == subSemester) unusedFeats when (null knownParents) . forM_ matchingFeatures $ \StudyFeatures{..} -> tell $ Set.singleton (subterm, Just studyFeaturesField) if @@ -4911,12 +4908,12 @@ upsertCampusUser plugin ldapData = do insertMaybe studyFeaturesDegree $ StudyDegree (unStudyDegreeKey studyFeaturesDegree) Nothing Nothing insertMaybe studyFeaturesField $ StudyTerms (unStudyTermsKey studyFeaturesField) Nothing Nothing Nothing Nothing oldFs <- selectKeysList - ([ StudyFeaturesUser ==. studyFeaturesUser + [ StudyFeaturesUser ==. studyFeaturesUser , StudyFeaturesDegree ==. studyFeaturesDegree , StudyFeaturesField ==. studyFeaturesField , StudyFeaturesType ==. studyFeaturesType , StudyFeaturesSemester ==. studyFeaturesSemester - ]) + ] [] case oldFs of [oldF] -> update oldF @@ -4933,20 +4930,20 @@ upsertCampusUser plugin ldapData = do associateUserSchoolsByTerms userId let - userAssociatedSchools = fmap concat $ forM userAssociatedSchools' parseLdapSchools + userAssociatedSchools = concat <$> forM userAssociatedSchools' parseLdapSchools userAssociatedSchools' = do (k, v) <- ldapData guard $ k == ldapUserSchoolAssociation v' <- v Right str <- return $ Text.decodeUtf8' v' return str - + ss <- either (throwM . CampusUserInvalidAssociatedSchools . tshow) return userAssociatedSchools forM_ ss $ \frag -> void . runMaybeT $ do let exactMatch = MaybeT . getBy $ UniqueOrgUnit frag - infixMatch = (hoistMaybe . preview _head =<<) . lift . E.select . E.from $ \schoolLdap -> do + infixMatch = (hoistMaybe . preview _head) <=< (lift . E.select . E.from) $ \schoolLdap -> do E.where_ $ E.val frag `E.isInfixOf` schoolLdap E.^. SchoolLdapOrgUnit E.&&. E.not_ (E.isNothing $ schoolLdap E.^. SchoolLdapSchool) return schoolLdap @@ -4960,7 +4957,7 @@ upsertCampusUser plugin ldapData = do } forM_ ss $ void . insertUnique . SchoolLdap Nothing - + return user where insertMaybe key val = get key >>= maybe (insert_ val) (\_ -> return ()) @@ -5092,7 +5089,7 @@ instance YesodAuth UniWorX where _other -> acceptExisting - authPlugins (UniWorX{ appSettings' = AppSettings{..}, appLdapPool }) = catMaybes + authPlugins UniWorX{ appSettings' = AppSettings{..}, appLdapPool } = catMaybes [ flip campusLogin campusUserFailoverMode <$> appLdapPool , Just . hashLogin $ pwHashAlgorithm appAuthPWHash , dummyLogin <$ guard appAuthDummyLogin @@ -5122,7 +5119,7 @@ campusUserFailoverMode = FailoverUnlimited instance YesodAuthPersist UniWorX where getAuthEntity = liftHandler . runDBRead . get - + unsafeHandler :: UniWorX -> Handler a -> IO a unsafeHandler f h = do logger <- makeLogger f diff --git a/src/Foundation/I18n.hs b/src/Foundation/I18n.hs index ce5ead5ee..3da033964 100644 --- a/src/Foundation/I18n.hs +++ b/src/Foundation/I18n.hs @@ -110,7 +110,7 @@ ordinalEN (toMessage -> numStr) = case lastChar of Just '3' -> [st|#{numStr}rd|] _other -> [st|#{numStr}th|] where - lastChar = last <$> fromNullable numStr + lastChar = last <$> fromNullable numStr -- Convenience Type for Messages, since Yesod messages cannot deal with compound type identifiers @@ -172,7 +172,7 @@ instance RenderMessage UniWorX MsgLanguage where | ("de" : "DE" : _) <- lang' = mr MsgGermanGermany | ("de" : _) <- lang' = mr MsgGerman | ("en" : "EU" : _) <- lang' = mr MsgEnglishEurope - | ("en" : _) <- lang' = mr MsgEnglish + | ("en" : _) <- lang' = mr MsgEnglish | otherwise = lang where mr = renderMessage foundation $ lang : filter (/= lang) ls @@ -247,7 +247,7 @@ instance RenderMessage UniWorX StudyDegreeTerm where where mr :: RenderMessage UniWorX msg => msg -> Text mr = renderMessage foundation ls - + newtype ShortStudyFieldType = ShortStudyFieldType StudyFieldType embedRenderMessageVariant ''UniWorX ''ShortStudyFieldType ("Short" <>) @@ -333,7 +333,7 @@ instance RenderMessage UniWorX UniWorXMessages where uniworxMessages :: [UniWorXMessage] -> UniWorXMessages uniworxMessages = UniWorXMessages . map SomeMessage - + -- This instance is required to use forms. You can modify renderMessage to -- achieve customized and internationalized form validation messages. instance RenderMessage UniWorX FormMessage where diff --git a/src/Foundation/Routes.hs b/src/Foundation/Routes.hs index afe77ba0e..658f5cf70 100644 --- a/src/Foundation/Routes.hs +++ b/src/Foundation/Routes.hs @@ -75,11 +75,11 @@ pattern CSubmissionR tid ssh csh shn cid ptn pattern CApplicationR :: TermId -> SchoolId -> CourseShorthand -> CryptoFileNameCourseApplication -> CourseApplicationR -> Route UniWorX pattern CApplicationR tid ssh csh appId ptn = CourseR tid ssh csh (CourseApplicationR appId ptn) - + pattern CNewsR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> CourseNewsR -> Route UniWorX pattern CNewsR tid ssh csh nId ptn = CourseR tid ssh csh (CourseNewsR nId ptn) - + pattern CEventR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseEvent -> CourseEventR -> Route UniWorX pattern CEventR tid ssh csh nId ptn = CourseR tid ssh csh (CourseEventR nId ptn) diff --git a/src/Handler/Admin/StudyFeatures.hs b/src/Handler/Admin/StudyFeatures.hs index 0dfd105b8..f4f40c7fb 100644 --- a/src/Handler/Admin/StudyFeatures.hs +++ b/src/Handler/Admin/StudyFeatures.hs @@ -47,7 +47,7 @@ embedRenderMessage ''UniWorX ''ButtonAdminStudyTermsParents id instance Button UniWorX ButtonAdminStudyTermsParents where btnClasses BtnParentCandidatesInfer = [BCIsButton, BCPrimary] btnClasses BtnParentCandidatesDeleteAll = [BCIsButton, BCDanger] - + data ButtonAdminStudyTermsStandalone = BtnStandaloneCandidatesDeleteRedundant | BtnStandaloneCandidatesDeleteAll @@ -62,7 +62,7 @@ instance Button UniWorX ButtonAdminStudyTermsStandalone where btnClasses BtnStandaloneCandidatesDeleteRedundant = [BCIsButton, BCPrimary] btnClasses BtnStandaloneCandidatesDeleteAll = [BCIsButton, BCDanger] - + {-# ANN postAdminFeaturesR ("HLint: ignore Redundant void" :: String) #-} getAdminFeaturesR, postAdminFeaturesR :: Handler Html getAdminFeaturesR = postAdminFeaturesR @@ -147,7 +147,7 @@ postAdminFeaturesR = do deleteWhere ([] :: [Filter StudyTermStandaloneCandidate]) addMessageI Success MsgAllStandaloneIncidencesDeleted redirect AdminFeaturesR - + newStudyTermKeys <- fromMaybe [] <$> lookupSessionJson SessionNewStudyTerms badStudyTermKeys <- lookupSessionJson SessionConflictingStudyTerms @@ -208,7 +208,7 @@ postAdminFeaturesR = do infRedundantStandalone <- Candidates.removeRedundantStandalone unless (null infRedundantStandalone) . addMessageI Info . MsgRedundantStandaloneCandidatesRemoved $ length infRedundantStandalone return updated - + let newKeys = catMaybes $ Map.elems updated unless (null newKeys) $ do setSessionJson SessionNewStudyTerms newKeys @@ -247,19 +247,19 @@ postAdminFeaturesR = do => Lens' a (Maybe Text) -> Getter (DBRow r) (Maybe Text) -> Getter (DBRow r) i - -> DBRow r + -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) textInputCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) (\row _mkUnique -> bimap (fmap $ set lensRes . assertM (not . Text.null)) fvWidget <$> mopt (textField & cfStrip) "" (Just $ row ^. lensDefault) ) - + checkboxCell :: Ord i => Lens' a Bool -> Getter (DBRow r) Bool -> Getter (DBRow r) i - -> DBRow r - -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) + -> DBRow r + -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) checkboxCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) ( \row _mkUnique -> bimap (fmap $ set lensRes) fvWidget <$> mpopt checkBoxField "" (Just $ row ^. lensDefault) @@ -306,7 +306,7 @@ postAdminFeaturesR = do ( \row _mkUnique -> bimap (fmap $ set lensRes) fvWidget <$> mopt degreeField "" (Just $ row ^. lensDefault) ) - + fieldTypeCell :: Ord i => Lens' a (Maybe StudyFieldType) -> Getter (DBRow r) (Maybe StudyFieldType) @@ -359,7 +359,7 @@ postAdminFeaturesR = do fieldSchools <- fmap (setOf $ folded . _Value) . E.select . E.from $ \school -> do E.where_ . E.exists . E.from $ \schoolTerms -> E.where_ $ schoolTerms E.^. SchoolTermsSchool E.==. school E.^. SchoolId - E.&&. schoolTerms E.^. SchoolTermsTerms E.==. E.val fId + E.&&. schoolTerms E.^. SchoolTermsTerms E.==. E.val fId E.where_ $ school E.^. SchoolShorthand `E.in_` E.valList (toListOf (folded . _entityKey . _SchoolId) schools) return $ school E.^. SchoolId fieldParents <- fmap (setOf folded) . E.select . E.from $ \terms -> do diff --git a/src/Handler/Admin/Test/Download.hs b/src/Handler/Admin/Test/Download.hs index a6efc04ef..dc02ae8e0 100644 --- a/src/Handler/Admin/Test/Download.hs +++ b/src/Handler/Admin/Test/Download.hs @@ -45,10 +45,10 @@ testDownloadForm = identifyForm FIDTestDownload . renderWForm FormStandard $ do maxSizeRes <- wreq intField (fslI MsgTestDownloadMaxSize) . Just $ 2 * 2^30 modeRes <- wpopt (selectField optionsFinite) (fslI MsgTestDownloadMode) $ Just TestDownloadDirect - + return $ TestDownloadOptions - <$> pure randomSeed - <*> maxSizeRes + randomSeed + <$> maxSizeRes <*> pure (2^20) <*> modeRes @@ -86,7 +86,7 @@ testDownload = do sourceDBFiles = E.selectSource . E.from $ \fileContent -> do E.orderBy [E.asc $ E.random_ @Int64] return fileContent - + takeLimit n | n <= 0 = return () takeLimit n = do c <- await diff --git a/src/Handler/Admin/Tokens.hs b/src/Handler/Admin/Tokens.hs index 4a9427598..70bb3f9ce 100644 --- a/src/Handler/Admin/Tokens.hs +++ b/src/Handler/Admin/Tokens.hs @@ -30,7 +30,7 @@ bearerTokenForm :: WForm Handler (FormResult BearerTokenForm) bearerTokenForm = do muid <- maybeAuthId mr <- getMessageRender - + btfAuthorityGroups <- aFormToWForm $ HashSet.fromList . map Left <$> massInputListA pathPieceField (const "") MsgBearerTokenAuthorityGroupMissing (\p -> Just . SomeRoute $ AdminTokensR :#: p) ("token-groups" :: Text) (fslI MsgBearerTokenAuthorityGroups & setTooltip MsgBearerTokenAuthorityGroupsTip) False Nothing btfAuthorityUsers <- fmap (fmap . ofoldMap $ HashSet.singleton . Right) <$> wopt (checkMap (foldMapM $ fmap Set.singleton . left MsgBearerTokenAuthorityUnknownUser) (Set.map Right) $ multiUserField False Nothing) (fslpI MsgBearerTokenAuthorityUsers (mr MsgLdapIdentificationOrEmail) & setTooltip MsgBearerTokenAuthorityUsersTip) (Just $ Set.singleton <$> muid) let btfAuthority' :: FormResult (HashSet (Either UserGroupName UserId)) @@ -58,7 +58,7 @@ bearerTokenForm = do miLayout' :: MassInputLayout ListLength (Route UniWorX, Value) (Route UniWorX, Value) miLayout' lLength _ cellWdgts delButtons addWdgts = $(widgetFile "widgets/massinput/token-restrictions/layout") - + btfRestrict' <- fmap HashMap.fromList <$> btfRestrictForm btfAddAuth' <- fmap (assertM $ not . Set.null . dnfTerms) <$> wopt pathPieceField (fslI MsgBearerTokenAdditionalAuth & setTooltip MsgBearerTokenAdditionalAuthTip) Nothing @@ -87,7 +87,7 @@ postAdminTokensR = do & HashSet.map (left toJSON) fmap Just . encodeBearer . set _bearerRestrictions btfRestrict =<< bearerToken btfAuthority' btfRoutes btfAddAuth btfExpiresAt btfStartsAt - + siteLayoutMsg' MsgMenuAdminTokens $ do setTitleI MsgMenuAdminTokens diff --git a/src/Handler/Allocation/Accept.hs b/src/Handler/Allocation/Accept.hs index 59ea952d2..d6b1c47d3 100644 --- a/src/Handler/Allocation/Accept.hs +++ b/src/Handler/Allocation/Accept.hs @@ -33,7 +33,7 @@ newtype SessionDataAllocationResults = SessionDataAllocationResults deriving (Monoid, Semigroup) via Dual (Map (TermId, SchoolId, AllocationShorthand) (UTCTime, AllocationFingerprint, Set (UserId, CourseId), Seq MatchingLogRun)) makeWrapped ''SessionDataAllocationResults - + data AllocationAcceptButton = BtnAllocationAccept @@ -59,7 +59,7 @@ allocationAcceptForm aId = runMaybeT $ do let applications = E.subSelectCount . E.from $ \courseApplication -> E.where_ $ courseApplication E.^. CourseApplicationAllocation E.==. E.val (Just aId) E.&&. courseApplication E.^. CourseApplicationUser E.==. allocationUser E.^. AllocationUserUser - return . (allocationUser E.^. AllocationUserUser, ) $ E.case_ + return . (allocationUser E.^. AllocationUserUser, ) $ E.case_ [ E.when_ (E.castNum (allocationUser E.^. AllocationUserTotalCourses) E.>. applications) E.then_ (applications :: E.SqlExpr (E.Value Int)) ] @@ -124,7 +124,7 @@ allocationAcceptForm aId = runMaybeT $ do = invDualHeat (optimumAllocated capN) capN degenerateHeat capN = capN <= optimumAllocated capN - + return (prevAllocMatches, $(widgetFile "allocation/accept")) getAAcceptR, postAAcceptR :: TermId -> SchoolId -> AllocationShorthand -> Handler Html @@ -135,7 +135,7 @@ postAAcceptR tid ssh ash = do acceptForm <- maybe (redirect $ AllocationR tid ssh ash AComputeR) return =<< allocationAcceptForm aId - formRes@((acceptRes, _), _) <- liftHandler $ runFormPost acceptForm + formRes@((acceptRes, _), _) <- liftHandler $ runFormPost acceptForm didStore <- formResultMaybe acceptRes $ \(now, allocFp, allocMatchings, allocLog) -> do modifySessionJson SessionAllocationResults . fmap (assertM $ not . views _Wrapped onull) . over (mapped . _Wrapped :: Setter' (Maybe SessionDataAllocationResults) _) $ diff --git a/src/Handler/Allocation/Application.hs b/src/Handler/Allocation/Application.hs index 73d898959..7f0a6154e 100644 --- a/src/Handler/Allocation/Application.hs +++ b/src/Handler/Allocation/Application.hs @@ -58,24 +58,24 @@ data ApplicationFormMode = ApplicationFormMode , afmApplicantEdit :: Bool -- ^ Allow editing text, files, priority (if shown) , afmLecturer :: Bool -- ^ Allow editing rating } - + data ApplicationFormException = ApplicationFormNoApplication -- ^ Could not fill forced fields of application form with data from application deriving (Eq, Ord, Read, Show, Generic, Typeable) instance Exception ApplicationFormException -applicationForm :: (Maybe AllocationId) +applicationForm :: Maybe AllocationId -> CourseId -> UserId -> ApplicationFormMode -- ^ Which parts of the shared form to display -> Html -> MForm Handler (FormResult ApplicationForm, ApplicationFormView) applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf = do - + (mApp, coursesNum, Course{..}, maxPrio) <- liftHandler . runDB $ do mApplication <- listToMaybe <$> selectList [CourseApplicationAllocation ==. maId, CourseApplicationUser ==. uid, CourseApplicationCourse ==. cid] [LimitTo 1] coursesNum <- fromIntegral . fromMaybe 1 <$> for maId (\aId -> count [AllocationCourseAllocation ==. aId]) course <- getJust cid - (fromMaybe 0 -> maxPrio) <- fmap ((>>= E.unValue) . listToMaybe) . E.select . E.from $ \courseApplication -> do + (fromMaybe 0 -> maxPrio) <- fmap (E.unValue <=< listToMaybe) . E.select . E.from $ \courseApplication -> do E.where_ $ courseApplication E.^. CourseApplicationUser E.==. E.val uid E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.val maId E.&&. E.not_ (E.isNothing $ courseApplication E.^. CourseApplicationAllocationPriority) @@ -91,25 +91,25 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf mkPrioOption :: Natural -> Option Natural mkPrioOption i = Option - { optionDisplay = mr . MsgAllocationCoursePriority $ coursesNum' - i + { optionDisplay = mr . MsgAllocationCoursePriority $ coursesNum' - i , optionInternalValue = i , optionExternalValue = tshow i } - + prioOptions :: OptionList Natural prioOptions = OptionList { olOptions = sortOn (Down . optionInternalValue) . map mkPrioOption $ [0 .. pred coursesNum'] , olReadExternal = readMay } prioField = selectField' (Just $ SomeMessage MsgAllocationCourseNoApplication) $ return prioOptions - + (prioRes, prioView) <- case (isAlloc, afmApplicant, afmApplicantEdit, mApp) of (True , True , True , Nothing) - -> over _2 Just <$> mopt prioField (fslI MsgApplicationPriority) (Just $ oldPrio) + -> over _2 Just <$> mopt prioField (fslI MsgApplicationPriority) (Just oldPrio) (True , True , True , Just _ ) -> over (_1 . _FormSuccess) Just . over _2 Just <$> mreq prioField (fslI MsgApplicationPriority) oldPrio (True , True , False, _ ) - -> over _2 Just <$> mforcedOpt prioField (fslI MsgApplicationPriority) oldPrio + -> over _2 Just <$> mforcedOpt prioField (fslI MsgApplicationPriority) oldPrio (True , False, _ , Just _ ) | is _Just oldPrio -> pure (FormSuccess oldPrio, Nothing) @@ -144,7 +144,7 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf let appFilesInfo = (,) <$> hasFiles <*> appCID filesLinkView <- if - | fromMaybe False hasFiles || (isn't _NoUpload courseApplicationsFiles && not afmApplicantEdit) + | Just True == hasFiles || (isn't _NoUpload courseApplicationsFiles && not afmApplicantEdit) -> let filesLinkField = Field{..} where fieldParse _ _ = return $ Right Nothing @@ -165,7 +165,7 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf -> return Nothing filesWarningView <- if - | fromMaybe False hasFiles && isn't _NoUpload courseApplicationsFiles && afmApplicantEdit + | Just True == hasFiles && isn't _NoUpload courseApplicationsFiles && afmApplicantEdit -> fmap (Just . snd) . formMessage =<< messageIconI Info IconFileUpload MsgCourseApplicationFilesNeedReupload | otherwise -> return Nothing @@ -174,16 +174,16 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf let mkFs = bool MsgCourseApplicationFile MsgCourseApplicationArchive in if | not afmApplicantEdit || is _NoUpload courseApplicationsFiles - -> return $ (FormSuccess Nothing, Nothing) + -> return (FormSuccess Nothing, Nothing) | otherwise -> fmap (over _2 $ Just . ($ [])) . aFormToForm $ fileUploadForm False (fslI . mkFs) courseApplicationsFiles (vetoRes, vetoView) <- if | afmLecturer - -> over _2 Just <$> mpopt checkBoxField (fslI MsgApplicationVeto & setTooltip MsgApplicationVetoTip) (Just . fromMaybe False $ courseApplicationRatingVeto . entityVal <$> mApp) + -> over _2 Just <$> mpopt checkBoxField (fslI MsgApplicationVeto & setTooltip MsgApplicationVetoTip) (Just $ Just True == fmap (courseApplicationRatingVeto . entityVal) mApp) | otherwise - -> return (FormSuccess . fromMaybe False $ courseApplicationRatingVeto . entityVal <$> mApp, Nothing) - + -> return (FormSuccess $ Just True == fmap (courseApplicationRatingVeto . entityVal) mApp, Nothing) + (pointsRes, pointsView) <- if | afmLecturer -> over _2 Just <$> mopt examGradeField (fslI MsgApplicationRatingPoints & setTooltip MsgApplicationRatingPointsTip) (fmap Just $ mApp >>= courseApplicationRatingPoints . entityVal) @@ -195,7 +195,7 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf -> over _2 Just . over (_1 . _FormSuccess) (assertM $ not . Text.null) <$> mopt textField' (fslI MsgApplicationRatingComment & setTooltip (bool MsgApplicationRatingCommentInvisibleTip MsgApplicationRatingCommentVisibleTip courseApplicationsRatingsVisible)) (fmap Just $ mApp >>= courseApplicationRatingComment . entityVal) | otherwise -> return (FormSuccess $ courseApplicationRatingComment . entityVal =<< mApp, Nothing) - + let buttons = catMaybes [ guardOn (not afmApplicantEdit && is _Just mApp && afmLecturer) BtnAllocationApplicationRate @@ -225,7 +225,7 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf <*> actionRes , ApplicationFormView { afvPriority = prioView - , afvForm = catMaybes $ + , afvForm = catMaybes $ [ Just fieldView' , textView , filesLinkView @@ -240,7 +240,7 @@ applicationForm maId@(is _Just -> isAlloc) cid uid ApplicationFormMode{..} csrf } ) - + editApplicationR :: Maybe AllocationId @@ -285,7 +285,7 @@ editApplicationR maId uid cid mAppId afMode allowAction postAction = do , courseApplicationRatingTime = guardOn rated now } - runConduit $ transPipe liftHandler (traverse_ id afFiles) .| C.mapM_ (insert_ . review _FileReference . (, CourseApplicationFileResidual appId)) + runConduit $ transPipe liftHandler (sequence_ afFiles) .| C.mapM_ (insert_ . review _FileReference . (, CourseApplicationFileResidual appId)) audit $ TransactionCourseApplicationEdit cid uid appId addMessageI Success $ MsgCourseApplicationCreated courseShorthand | is _BtnAllocationApplicationEdit afAction || is _BtnAllocationApplicationRate afAction @@ -354,7 +354,7 @@ editApplicationR maId uid cid mAppId afMode allowAction postAction = do redirect postAction return (appView, appEnc) - + postAApplyR :: TermId -> SchoolId -> AllocationShorthand -> CryptoUUIDCourse -> Handler Void postAApplyR tid ssh ash cID = do diff --git a/src/Handler/Allocation/Compute.hs b/src/Handler/Allocation/Compute.hs index 9c8b300e6..d18b68b31 100644 --- a/src/Handler/Allocation/Compute.hs +++ b/src/Handler/Allocation/Compute.hs @@ -62,7 +62,7 @@ missingPriorities aId = wFormToAForm $ do missingPriosFieldView theId name attrs res isReq = $(i18nWidgetFile "allocation-confirm-missing-prios") where checkBoxFieldView = labeledCheckBoxView (i18n MsgAllocationUsersMissingPrioritiesOk) theId name attrs res isReq - + if | null usersWithoutPrio -> return $ pure Set.empty diff --git a/src/Handler/Allocation/List.hs b/src/Handler/Allocation/List.hs index fc6d7e48a..549209bf8 100644 --- a/src/Handler/Allocation/List.hs +++ b/src/Handler/Allocation/List.hs @@ -5,7 +5,7 @@ module Handler.Allocation.List ) where import Import - + import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils as E import Handler.Utils.Table.Columns @@ -23,16 +23,16 @@ queryAllocation = id countCourses :: (Num n, PersistField n) - => (E.SqlExpr (Entity AllocationCourse) -> E.SqlExpr (E.Value Bool)) + => (E.SqlExpr (Entity AllocationCourse) -> E.SqlExpr (E.Value Bool)) -> E.SqlExpr (Entity Allocation) -> E.SqlExpr (E.Value n) countCourses addWhere allocation = E.subSelectCount . E.from $ \allocationCourse -> E.where_ $ allocationCourse E.^. AllocationCourseAllocation E.==. allocation E.^. AllocationId E.&&. addWhere allocationCourse - + queryAvailable :: Getter AllocationTableExpr (E.SqlExpr (E.Value Natural)) queryAvailable = queryAllocation . to (countCourses $ const E.true) - + queryApplied :: UserId -> Getter AllocationTableExpr (E.SqlExpr (E.Value Natural)) queryApplied uid = queryAllocation . to (\allocation -> countCourses (addWhere allocation) allocation) where @@ -51,7 +51,7 @@ resultApplied = _dbrOutput . _3 allocationTermLink :: TermId -> SomeRoute UniWorX allocationTermLink tid = SomeRoute (AllocationListR, [(dbFilterKey allocationListIdent "term", toPathPiece tid)]) - + allocationSchoolLink :: SchoolId -> SomeRoute UniWorX allocationSchoolLink ssh = SomeRoute (AllocationListR, [(dbFilterKey allocationListIdent "school", toPathPiece ssh)]) diff --git a/src/Handler/Allocation/Prios.hs b/src/Handler/Allocation/Prios.hs index 20b3f5127..9d5621c1e 100644 --- a/src/Handler/Allocation/Prios.hs +++ b/src/Handler/Allocation/Prios.hs @@ -26,7 +26,7 @@ instance Finite AllocationPrioritiesMode nullaryPathPiece ''AllocationPrioritiesMode $ camelToPathPiece' 2 embedRenderMessage ''UniWorX ''AllocationPrioritiesMode id - + getAPriosR, postAPriosR :: TermId -> SchoolId -> AllocationShorthand -> Handler Html getAPriosR = postAPriosR @@ -37,7 +37,7 @@ postAPriosR tid ssh ash = do numericPrios <- E.selectCountRows . E.from $ \allocationUser -> do E.where_ $ allocationUser E.^. AllocationUserAllocation E.==. E.val aId E.where_ . E.maybe E.false sqlAllocationPriorityNumeric $ allocationUser E.^. AllocationUserPriority - + ordinalPrios <- E.selectCountRows . E.from $ \allocationUser -> do E.where_ $ allocationUser E.^. AllocationUserAllocation E.==. E.val aId E.where_ . E.maybe E.false (E.not_ . sqlAllocationPriorityNumeric) $ allocationUser E.^. AllocationUserPriority @@ -59,7 +59,7 @@ postAPriosR tid ssh ash = do let sourcePrios = case mode of AllocationPrioritiesNumeric -> transPipe liftHandler fInfo .| fileSourceCsvPositional Csv.NoHeader AllocationPrioritiesOrdinal -> transPipe liftHandler fInfo .| fileSourceCsvPositional Csv.NoHeader .| C.map Csv.fromOnly .| ordinalPriorities - + (matrSunk, matrMissing) <- runDB $ do Entity aId _ <- getBy404 $ TermSchoolAllocationShort tid ssh ash updateWhere @@ -77,7 +77,7 @@ postAPriosR tid ssh ash = do E.&&. courseApplication E.^. CourseApplicationAllocation E.==. E.just (E.val aId) return (matrSunk, matrMissing) - when (matrSunk > 0) $ + when (matrSunk > 0) $ addMessageI Success $ MsgAllocationPrioritiesSunk matrSunk when (matrMissing > 0) $ addMessageI Error $ MsgAllocationPrioritiesMissing matrMissing diff --git a/src/Handler/Allocation/Register.hs b/src/Handler/Allocation/Register.hs index c502ab48a..9629335c7 100644 --- a/src/Handler/Allocation/Register.hs +++ b/src/Handler/Allocation/Register.hs @@ -46,7 +46,7 @@ postARegisterR tid ssh ash = do formResult registerRes $ \AllocationRegisterForm{..} -> runDB $ do aId <- getKeyBy404 $ TermSchoolAllocationShort tid ssh ash isRegistered <- existsBy $ UniqueAllocationUser aId uid - void $ upsert AllocationUser + void $ upsert AllocationUser { allocationUserAllocation = aId , allocationUserUser = uid , allocationUserTotalCourses = arfTotalCourses @@ -57,5 +57,5 @@ postARegisterR tid ssh ash = do if | isRegistered -> addMessageI Success MsgAllocationRegistrationEdited | otherwise -> addMessageI Success MsgAllocationRegistered - + redirect $ AllocationR tid ssh ash AShowR :#: ("allocation-participation" :: Text) diff --git a/src/Handler/Allocation/Show.hs b/src/Handler/Allocation/Show.hs index 6015f2820..c374501e0 100644 --- a/src/Handler/Allocation/Show.hs +++ b/src/Handler/Allocation/Show.hs @@ -4,7 +4,7 @@ module Handler.Allocation.Show import Import import Handler.Utils - + import Handler.Allocation.Register import Handler.Allocation.Application diff --git a/src/Handler/Allocation/Users.hs b/src/Handler/Allocation/Users.hs index 08260f683..e150f1d1b 100644 --- a/src/Handler/Allocation/Users.hs +++ b/src/Handler/Allocation/Users.hs @@ -63,11 +63,11 @@ type UserTableData = DBRow ( Entity User , Int -- ^ Applied , Int -- ^ Assigned , Int -- ^ Vetoed - ) + ) resultUser :: Lens' UserTableData (Entity User) resultUser = _dbrOutput . _1 - + resultAllocationUser :: Lens' UserTableData (Entity AllocationUser) resultAllocationUser = _dbrOutput . _2 @@ -83,7 +83,7 @@ data AllocationUserTableCsv = AllocationUserTableCsv , csvAUserName :: Text , csvAUserMatriculation :: Maybe Text , csvAUserRequested - , csvAUserApplied + , csvAUserApplied , csvAUserVetos , csvAUserAssigned :: Natural , csvAUserPriority :: Maybe AllocationPriority @@ -94,10 +94,10 @@ allocationUserTableCsvOptions :: Csv.Options allocationUserTableCsvOptions = Csv.defaultOptions { Csv.fieldLabelModifier = camelToPathPiece' 3} instance Csv.ToNamedRecord AllocationUserTableCsv where - toNamedRecord = Csv.genericToNamedRecord allocationUserTableCsvOptions + toNamedRecord = Csv.genericToNamedRecord allocationUserTableCsvOptions instance Csv.DefaultOrdered AllocationUserTableCsv where - headerOrder = Csv.genericHeaderOrder allocationUserTableCsvOptions + headerOrder = Csv.genericHeaderOrder allocationUserTableCsvOptions instance CsvColumnsExplained AllocationUserTableCsv where csvColumnsExplanations = genericCsvColumnsExplanations allocationUserTableCsvOptions $ mconcat diff --git a/src/Handler/Course/Application/Files.hs b/src/Handler/Course/Application/Files.hs index c608aa94e..05b229560 100644 --- a/src/Handler/Course/Application/Files.hs +++ b/src/Handler/Course/Application/Files.hs @@ -42,7 +42,7 @@ getCAppsFilesR :: TermId -> SchoolId -> CourseShorthand -> Handler TypedContent getCAppsFilesR tid ssh csh = do runDB . existsBy404 $ TermSchoolCourseShort tid ssh csh MsgRenderer mr <- getMsgRenderer - + archiveName <- fmap (flip addExtension (unpack extensionZip) . unpack) . ap getMessageRender . pure $ MsgCourseAllApplicationsArchiveName tid ssh csh let @@ -61,12 +61,12 @@ getCAppsFilesR tid ssh csh = do hasReadAccessTo $ CApplicationR tid ssh csh cID CAFilesR let applicationAllocs = setOf (folded . _1) apps' - + allocations = applicationAllocs ^.. folded . _Just . _entityVal . $(multifocusG 3) _allocationTerm _allocationSchool _allocationShorthand allEqualOn :: Eq x => Getter _ x -> Bool allEqualOn l = maybe True (\x -> allOf (folded . l) (== x) allocations) (allocations ^? _head . l) - + mkAllocationDir mbAlloc | not $ allEqualOn _1 , Just Allocation{..} <- mbAlloc @@ -92,7 +92,7 @@ getCAppsFilesR tid ssh csh = do fileEntitySource = E.selectSource . E.from $ \courseApplicationFile -> do E.where_ $ courseApplicationFile E.^. CourseApplicationFileApplication E.==. E.val appId return courseApplicationFile - + yield $ _FileReference # ( FileReference { fileReferenceModified = courseApplicationTime , fileReferenceTitle = mkAppDir "" diff --git a/src/Handler/Course/Application/List.hs b/src/Handler/Course/Application/List.hs index 6a98c7e48..b2b7200b4 100644 --- a/src/Handler/Course/Application/List.hs +++ b/src/Handler/Course/Application/List.hs @@ -47,7 +47,7 @@ type CourseApplicationsTableData = DBRow ( Entity CourseApplication , Maybe (Entity StudyDegree) , Bool -- isParticipant ) - + courseApplicationsIdent :: Text courseApplicationsIdent = "applications" @@ -120,7 +120,7 @@ instance Csv.FromField CourseApplicationsTableVeto where (CI.map Text.strip -> t :: CI Text) <- Csv.parseField f return . CourseApplicationsTableVeto $ elem t [ "veto", "v", "yes", "y", "ja", "j", "wahr", "w", "true", "t", "1" ] - + data CourseApplicationsTableCsv = CourseApplicationsTableCsv { csvCAAllocation :: Maybe AllocationShorthand , csvCAApplication :: Maybe CryptoFileNameCourseApplication @@ -223,7 +223,7 @@ instance Exception CourseApplicationsTableCsvException embedRenderMessage ''UniWorX ''CourseApplicationsTableCsvException id - + data ButtonAcceptApplications = BtnAcceptApplications deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable) instance Universe ButtonAcceptApplications @@ -277,7 +277,7 @@ postCApplicationsR tid ssh csh = do applicationLink appId = liftHandler $ do cID <- encrypt appId return . SomeRoute $ CApplicationR tid ssh csh cID CAEditR - + dbtSQLQuery :: CourseApplicationsTableExpr -> E.SqlQuery _ dbtSQLQuery = runReaderT $ do courseApplication <- view queryCourseApplication @@ -415,13 +415,13 @@ postCApplicationsR tid ssh csh = do -> return () -- no addition DBCsvDiffExisting{..} -> do let appId = dbCsvOld ^. resultCourseApplication . _entityKey - + newFeatures <- lift $ lookupStudyFeatures dbCsvNew when (newFeatures /= dbCsvOld ^? resultStudyFeatures . _entityKey) $ yield $ CourseApplicationsTableCsvSetFieldData appId newFeatures let mVeto = dbCsvNew ^? _csvCAVeto . _Just . _CourseApplicationsTableVeto - whenIsJust mVeto $ \veto -> + whenIsJust mVeto $ \veto -> when (veto /= dbCsvOld ^. resultCourseApplication . _entityVal . _courseApplicationRatingVeto) $ yield $ CourseApplicationsTableCsvSetVetoData appId veto @@ -638,7 +638,7 @@ postCApplicationsR tid ssh csh = do let title = prependCourseTitle tid ssh csh MsgCourseApplicationsListTitle registrationOpen = maybe True (now <) - + ((acceptRes, acceptWgt'), acceptEnc) <- runFormPost . identifyForm BtnAcceptApplications . renderAForm FormStandard $ (,) <$> apopt (selectField optionsFinite) (fslI MsgAcceptApplicationsMode & setTooltip MsgAcceptApplicationsModeTip) (Just AcceptApplicationsInvite) <*> apopt (selectField optionsFinite) (fslI MsgAcceptApplicationsSecondary & setTooltip MsgAcceptApplicationsSecondaryTip) (Just AcceptApplicationsSecondaryTime) @@ -679,7 +679,7 @@ postCApplicationsR tid ssh csh = do AcceptApplicationsSecondaryRandom -> comparing $ view ratingL sortedApplications <- unstableSortBy cmp applications - + let applicants = sortedApplications & nubOn (view $ _1 . _entityKey) & maybe id take openCapacity @@ -687,7 +687,7 @@ postCApplicationsR tid ssh csh = do AcceptApplicationsDirect -> folded . _1 . _entityKey . to Right AcceptApplicationsInvite -> folded . _1 . _entityVal . _userEmail . to Left ) - + mapM_ addMessage' <=< execWriterT $ registerUsers cid applicants redirect $ CourseR tid ssh csh CUsersR diff --git a/src/Handler/Course/Communication.hs b/src/Handler/Course/Communication.hs index dd833eccd..005aca3ae 100644 --- a/src/Handler/Course/Communication.hs +++ b/src/Handler/Course/Communication.hs @@ -94,7 +94,7 @@ postCCommR tid ssh csh = do E.where_ $ courseParticipant E.^. CourseParticipantCourse E.==. E.val cid E.&&. courseParticipant E.^. CourseParticipantUser E.==. user E.^. UserId E.&&. courseParticipant E.^. CourseParticipantState E.==. E.val CourseParticipantActive - return user + return user ) ] ++ tuts ++ exams ++ sheets , crRecipientAuth = Just $ \uid -> do diff --git a/src/Handler/Course/Edit.hs b/src/Handler/Course/Edit.hs index 8ba44473e..2bc825445 100644 --- a/src/Handler/Course/Edit.hs +++ b/src/Handler/Course/Edit.hs @@ -88,7 +88,7 @@ courseToForm cEnt@(Entity cid Course{..}) lecs lecInvites alloc = CourseForm where selectAppFiles = E.selectSource . E.from $ \courseAppInstructionFile -> do E.where_ $ courseAppInstructionFile E.^. CourseAppInstructionFileCourse E.==. E.val cid return courseAppInstructionFile - + allocationCourseToForm :: Entity Course -> Entity AllocationCourse -> AllocationCourseForm allocationCourseToForm (Entity _ Course{..}) (Entity _ AllocationCourse{..}) = AllocationCourseForm @@ -134,7 +134,7 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB , not $ Set.null existing -> FormFailure [mr MsgCourseLecturerAlreadyAdded] | otherwise - -> FormSuccess . Map.fromList . zip [maybe 0 succ . fmap fst $ Map.lookupMax oldDat ..] $ Set.toList newDat + -> FormSuccess . Map.fromList . zip [maybe 0 (succ . fst) $ Map.lookupMax oldDat ..] $ Set.toList newDat addView' = $(widgetFile "course/lecturerMassInput/add") return (addRes'', addView') @@ -194,9 +194,9 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB (Just cform) | (Just _cid) <- cfCourseId cform -> return (Nothing,Nothing,Nothing) _allIOtherCases -> do mbLastTerm <- liftHandler $ runDB $ selectFirst [TermActive ==. True] [Desc TermName] - return ( (Just . toMidnight . termStart . entityVal) <$> mbLastTerm - , (Just . beforeMidnight . termEnd . entityVal) <$> mbLastTerm - , (Just . beforeMidnight . termEnd . entityVal) <$> mbLastTerm ) + return ( Just . toMidnight . termStart . entityVal <$> mbLastTerm + , Just . beforeMidnight . termEnd . entityVal <$> mbLastTerm + , Just . beforeMidnight . termEnd . entityVal <$> mbLastTerm ) let allocationForm :: AForm Handler (Maybe AllocationCourseForm) @@ -208,7 +208,7 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB E.exists . E.from $ \allocationCourse -> E.where_ $ allocationCourse E.^. AllocationCourseCourse E.==. E.val cid E.&&. allocationCourse E.^. AllocationCourseAllocation E.==. allocation E.^. AllocationId - + E.where_ $ term E.^. TermActive E.||. alreadyParticipates E.||. allocation E.^. AllocationSchool `E.in_` E.valList adminSchools @@ -238,8 +238,8 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB let userAdmin = not $ null adminSchools - mayChange = fromMaybe True $ (|| userAdmin) <$> currentAllocationAvailable - + mayChange = Just False /= fmap (|| userAdmin) currentAllocationAvailable + allocationForm' = let ainp :: Field Handler a -> FieldSettings UniWorX -> Maybe a -> AForm Handler a ainp @@ -260,8 +260,8 @@ makeCourseForm miButtonAction template = identifyForm FIDcourse . validateFormDB multipleTermsMsg <- messageI Warning MsgCourseSemesterMultipleTip (result, widget) <- flip (renderAForm FormStandard) html $ CourseForm - <$> pure (cfCourseId =<< template) - <*> areq (textField & cfStrip & cfCI) (fslI MsgCourseName) (cfName <$> template) + (cfCourseId =<< template) + <$> areq (textField & cfStrip & cfCI) (fslI MsgCourseName) (cfName <$> template) <*> areq (textField & cfStrip & cfCI) (fslpI MsgCourseShorthand "ProMo, LinAlg1, AlgoDat, Ana2, EiP, …" -- & addAttr "disabled" "disabled" & setTooltip MsgCourseShorthandUnique) (cfShort <$> template) @@ -322,7 +322,7 @@ validateCourse = do guardValidation MsgCourseRegistrationEndMustBeAfterStart $ NTop cfRegFrom <= NTop cfRegTo guardValidation MsgCourseDeregistrationEndMustBeAfterStart - $ fromMaybe True $ (<=) <$> cfRegFrom <*> cfDeRegUntil + $ Just False /= ((<=) <$> cfRegFrom <*> cfDeRegUntil) unless userAdmin $ guardValidation MsgCourseUserMustBeLecturer $ anyOf (traverse . _Right . _1) (== uid) cfLecturers @@ -335,7 +335,7 @@ validateCourse = do warnValidation MsgCourseShorthandTooLong $ length (CI.original cfShort) <= 10 - + getCourseNewR :: Handler Html -- call via toTextUrl getCourseNewR = do @@ -521,7 +521,7 @@ courseEditHandler miButtonAction mbCourseForm = do insert_ $ CourseEdit aid now cid let mkFilter CourseAppInstructionFileResidual{..} = [ CourseAppInstructionFileCourse ==. courseAppInstructionFileResidualCourse ] - in void . replaceFileReferences mkFilter (CourseAppInstructionFileResidual cid) . traverse_ id $ cfAppInstructionFiles res + in void . replaceFileReferences mkFilter (CourseAppInstructionFileResidual cid) . sequence_ $ cfAppInstructionFiles res upsertAllocationCourse cid $ cfAllocation res diff --git a/src/Handler/Course/Events/Delete.hs b/src/Handler/Course/Events/Delete.hs index 609fa93a5..3dd5d06fb 100644 --- a/src/Handler/Course/Events/Delete.hs +++ b/src/Handler/Course/Events/Delete.hs @@ -8,13 +8,13 @@ import Handler.Utils.Occurrences import Handler.Utils.Delete import qualified Data.Set as Set - + getCEvDeleteR, postCEvDeleteR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseEvent -> Handler Html getCEvDeleteR = postCEvDeleteR postCEvDeleteR tid ssh csh cID = do nId <- decrypt cID - + let drRecords :: Set (Key CourseEvent) drRecords = Set.singleton nId @@ -31,23 +31,23 @@ postCEvDeleteR tid ssh csh cID = do : ^{occurrencesWidget courseEventTime} |] - + drRecordConfirmString :: Entity CourseEvent -> DB Text drRecordConfirmString _ = return "" - + drCaption, drSuccessMessage :: SomeMessage UniWorX drCaption = SomeMessage MsgCourseEventDeleteQuestion drSuccessMessage = SomeMessage MsgCourseEventDeleted - + drAbort, drSuccess :: SomeRoute UniWorX drAbort = SomeRoute $ CourseR tid ssh csh CShowR :#: [st|event-#{toPathPiece cID}|] drSuccess = SomeRoute $ CourseR tid ssh csh CShowR - + drFormMessage :: [Entity CourseEvent] -> DB (Maybe Message) drFormMessage _ = return Nothing - + drDelete :: forall a. CourseEventId -> JobDB a -> JobDB a drDelete _ = id - + deleteR DeleteRoute{..} diff --git a/src/Handler/Course/Events/Edit.hs b/src/Handler/Course/Events/Edit.hs index 5ac391d5d..0dcfaa30a 100644 --- a/src/Handler/Course/Events/Edit.hs +++ b/src/Handler/Course/Events/Edit.hs @@ -4,7 +4,7 @@ module Handler.Course.Events.Edit import Import import Handler.Utils - + import Handler.Course.Events.Form diff --git a/src/Handler/Course/Events/Form.hs b/src/Handler/Course/Events/Form.hs index 3cb291f89..ecc01b8e9 100644 --- a/src/Handler/Course/Events/Form.hs +++ b/src/Handler/Course/Events/Form.hs @@ -31,7 +31,7 @@ courseEventForm template = identifyForm FIDCourseEvent . renderWForm FormStandar ) let courseEventTypes = optionsPairs [ (courseEventType, courseEventType) | Entity _ CourseEvent{..} <- existingEvents ] courseEventRooms = optionsPairs [ (courseEventRoom, courseEventRoom) | Entity _ CourseEvent{..} <- existingEvents ] - + cefType' <- wreq (textField & cfStrip & cfCI & addDatalist courseEventTypes) (fslI MsgCourseEventType & addPlaceholder (mr MsgCourseEventTypePlaceholder)) (cefType <$> template) cefRoom' <- wreq (textField & cfStrip & addDatalist courseEventRooms) (fslI MsgCourseEventRoom) (cefRoom <$> template) cefTime' <- aFormToWForm $ occurrencesAForm ("time" :: Text) (cefTime <$> template) diff --git a/src/Handler/Course/Events/New.hs b/src/Handler/Course/Events/New.hs index b01f17af5..b389de9de 100644 --- a/src/Handler/Course/Events/New.hs +++ b/src/Handler/Course/Events/New.hs @@ -4,7 +4,7 @@ module Handler.Course.Events.New import Import import Handler.Utils - + import Handler.Course.Events.Form getCEventsNewR, postCEventsNewR :: TermId -> SchoolId -> CourseShorthand -> Handler Html diff --git a/src/Handler/Course/News/Delete.hs b/src/Handler/Course/News/Delete.hs index 2311f9335..8fda2c3a0 100644 --- a/src/Handler/Course/News/Delete.hs +++ b/src/Handler/Course/News/Delete.hs @@ -12,7 +12,7 @@ getCNDeleteR, postCNDeleteR :: TermId -> SchoolId -> CourseShorthand -> CryptoUU getCNDeleteR = postCNDeleteR postCNDeleteR tid ssh csh cID = do nId <- decrypt cID - + let drRecords :: Set (Key CourseNews) drRecords = Set.singleton nId @@ -26,22 +26,22 @@ postCNDeleteR tid ssh csh cID = do [ toWidget <$> courseNewsTitle , toWidget <$> courseNewsSummary ] - + drRecordConfirmString :: Entity CourseNews -> DB Text drRecordConfirmString _ = return "" - + drCaption, drSuccessMessage :: SomeMessage UniWorX drCaption = SomeMessage MsgCourseNewsDeleteQuestion drSuccessMessage = SomeMessage MsgCourseNewsDeleted - + drAbort, drSuccess :: SomeRoute UniWorX drAbort = SomeRoute $ CourseR tid ssh csh CShowR :#: [st|news-#{toPathPiece cID}|] drSuccess = SomeRoute $ CourseR tid ssh csh CShowR drFormMessage :: [Entity CourseNews] -> DB (Maybe Message) drFormMessage _ = return Nothing - + drDelete :: forall a. CourseNewsId -> JobDB a -> JobDB a drDelete _ = id - + deleteR DeleteRoute{..} diff --git a/src/Handler/Course/News/Download.hs b/src/Handler/Course/News/Download.hs index b898c7f7f..59cfaabe8 100644 --- a/src/Handler/Course/News/Download.hs +++ b/src/Handler/Course/News/Download.hs @@ -25,7 +25,7 @@ getCNArchiveR tid ssh csh cID = do serveSomeFiles archiveName getFilesQuery - + getCNFileR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> FilePath -> Handler TypedContent getCNFileR _ _ _ cID title = do nId <- decrypt cID diff --git a/src/Handler/Course/News/Edit.hs b/src/Handler/Course/News/Edit.hs index 14c30f7b2..cf4f4377a 100644 --- a/src/Handler/Course/News/Edit.hs +++ b/src/Handler/Course/News/Edit.hs @@ -34,7 +34,7 @@ postCNEditR tid ssh csh cID = do , courseNewsLastEdit = now } let mkFilter CourseNewsFileResidual{} = [ CourseNewsFileNews ==. nId ] - in void . replaceFileReferences mkFilter (CourseNewsFileResidual nId) $ traverse_ id cnfFiles + in void . replaceFileReferences mkFilter (CourseNewsFileResidual nId) $ sequence_ cnfFiles addMessageI Success MsgCourseNewsEdited redirect $ CourseR tid ssh csh CShowR :#: [st|news-#{toPathPiece cID}|] diff --git a/src/Handler/Course/News/Form.hs b/src/Handler/Course/News/Form.hs index 0d52e3001..5d5aeb599 100644 --- a/src/Handler/Course/News/Form.hs +++ b/src/Handler/Course/News/Form.hs @@ -16,7 +16,7 @@ data CourseNewsForm = CourseNewsForm , cnfContent :: Html , cnfParticipantsOnly :: Bool , cnfVisibleFrom :: Maybe UTCTime - , cnfFiles :: Maybe FileUploads + , cnfFiles :: Maybe FileUploads } courseNewsForm :: Maybe CourseNewsForm -> Form CourseNewsForm diff --git a/src/Handler/Course/ParticipantInvite.hs b/src/Handler/Course/ParticipantInvite.hs index f461816b8..dab5b62e2 100644 --- a/src/Handler/Course/ParticipantInvite.hs +++ b/src/Handler/Course/ParticipantInvite.hs @@ -96,7 +96,7 @@ participantInvitationConfig = InvitationConfig{..} now <- liftIO getCurrentTime studyFeatures <- wreq (studyFeaturesFieldFor Nothing False [] $ Just uid) (fslI MsgCourseStudyFeature & setTooltip MsgCourseStudyFeatureTip) Nothing - return . fmap (, ()) $ JunctionParticipant <$> pure now <*> studyFeatures <*> pure Nothing <*> pure CourseParticipantActive + return . fmap (, ()) $ JunctionParticipant now <$> studyFeatures <*> pure Nothing <*> pure CourseParticipantActive invitationInsertHook _ _ (_, InvTokenDataParticipant{..}) CourseParticipant{..} _ act = do deleteBy $ UniqueParticipant courseParticipantUser courseParticipantCourse -- there are no foreign key references to @{CourseParticipant}; therefor we can delete and recreate to simulate upsert res <- act -- insertUnique @@ -138,7 +138,7 @@ postCAddUserR tid ssh csh = do formResultModal usersToEnlist (CourseR tid ssh csh CUsersR) $ hoist runDBJobs . registerUsers' cid - + let heading = prependCourseTitle tid ssh csh MsgCourseParticipantsRegisterHeading @@ -169,7 +169,7 @@ addParticipantsResultMessages :: (MonadHandler m, HandlerSite m ~ UniWorX) => AddParticipantsResult -> ReaderT (YesodPersistBackend UniWorX) m [Message] addParticipantsResultMessages AddParticipantsResult{..} = execWriterT $ do - (aurAlreadyRegistered', aurNoUniquePrimaryField') <- + (aurAlreadyRegistered', aurNoUniquePrimaryField') <- (,) <$> fmap sort (lift . mapM (fmap userEmail . getJust) $ Set.toList aurAlreadyRegistered) <*> fmap sort (lift . mapM (fmap userEmail . getJust) $ Set.toList aurNoUniquePrimaryField) diff --git a/src/Handler/Course/Register.hs b/src/Handler/Course/Register.hs index 139af8444..117f99b38 100644 --- a/src/Handler/Course/Register.hs +++ b/src/Handler/Course/Register.hs @@ -63,7 +63,7 @@ courseRegisterForm (Entity cid Course{..}) = liftHandler $ do isRegistered = btn `elem` [BtnCourseRetractApplication, BtnCourseDeregister] return . (, btn) . wFormToAForm $ do MsgRenderer mr <- getMsgRenderer - + secretRes <- if | Just secret <- courseRegisterSecret , not isRegistered @@ -112,7 +112,7 @@ courseRegisterForm (Entity cid Course{..}) = liftHandler $ do let appFilesInfo = (,) <$> hasFiles <*> appCID filesMsg = bool MsgCourseRegistrationFiles MsgCourseApplicationFiles courseApplicationsRequired - when (isn't _NoUpload courseApplicationsFiles || fromMaybe False hasFiles) $ + when (isn't _NoUpload courseApplicationsFiles || Just True == hasFiles) $ let filesLinkField = Field{..} where fieldParse _ _ = return $ Right Nothing @@ -130,7 +130,7 @@ courseRegisterForm (Entity cid Course{..}) = liftHandler $ do |] in void $ wforced filesLinkField (fslI filesMsg) Nothing - when (fromMaybe False hasFiles && isn't _NoUpload courseApplicationsFiles) $ + when (Just True == hasFiles && isn't _NoUpload courseApplicationsFiles) $ wformMessage <=< messageIconI Info IconFileUpload $ bool MsgCourseRegistrationFilesNeedReupload MsgCourseApplicationFilesNeedReupload courseApplicationsRequired appFilesRes <- let mkFs | courseApplicationsRequired = bool MsgCourseApplicationFile MsgCourseApplicationArchive @@ -145,14 +145,14 @@ courseRegisterForm (Entity cid Course{..}) = liftHandler $ do wformMessage =<< messageIconI Warning IconExamRegisterFalse MsgCourseDeregistrationAllocationLog when (is _Just (registration >>= courseParticipantAllocated . entityVal) && courseDeregisterNoShow) $ wformMessage =<< messageIconI Warning IconEnrolFalse MsgCourseDeregistrationNoShow - + return $ CourseRegisterForm <$ secretRes <*> fieldRes <*> appTextRes <*> appFilesRes - + -- | Workaround for klicking register button without being logged in. -- After log in, the user sees a "get request not supported" error. getCRegisterR :: TermId -> SchoolId -> CourseShorthand -> Handler Html @@ -193,8 +193,8 @@ postCRegisterR tid ssh csh = do return $ Just prevId - whenIsJust appRes $ - audit . TransactionCourseApplicationEdit cid uid + whenIsJust appRes $ + audit . TransactionCourseApplicationEdit cid uid whenIsJust ((,) <$> appRes <*> crfApplicationFiles) $ \(appId, fSource) -> do runConduit $ transPipe liftHandler fSource .| C.mapM_ (insert_ . review _FileReference . (, CourseApplicationFileResidual appId)) return appRes @@ -275,7 +275,7 @@ deregisterParticipant uid cid = do forM_ examRegistrations $ \(Entity erId ExamRegistration{..}) -> do delete erId audit $ TransactionExamDeregister examRegistrationExam uid - + E.delete . E.from $ \tutorialParticipant -> do let tutorialCourse = E.subSelectForeign tutorialParticipant TutorialParticipantTutorial (E.^. TutorialCourse) diff --git a/src/Handler/Course/Show.hs b/src/Handler/Course/Show.hs index d8cd57425..0ea29fc68 100644 --- a/src/Handler/Course/Show.hs +++ b/src/Handler/Course/Show.hs @@ -103,16 +103,15 @@ getCShowR tid ssh csh = do E.where_ $ submissionGroupUser E.^. SubmissionGroupUserUser E.==. E.val uid return $ submissionGroup E.^. SubmissionGroupName let submissionGroup = guardOnM (hasSubmissionGroups && is _Just registration) submissionGroup' - + return (cid,course,schoolName,participants,registration,lecturers,assistants,correctors,tutors,mAllocation,hasApplicationTemplate,mApplication,news,events,submissionGroup) let mDereg' = maybe id min (allocationOverrideDeregister =<< mAllocation) <$> courseDeregisterUntil course - mDereg <- traverse (formatTime SelFormatDateTime) mDereg' + mDereg <- traverse (formatTime SelFormatDateTime) mDereg' cID <- encrypt cid :: Handler CryptoUUIDCourse - mAllocation' <- for mAllocation $ \alloc@Allocation{..} -> (,) - <$> pure alloc - <*> toTextUrl (AllocationR allocationTerm allocationSchool allocationShorthand AShowR :#: cID) + mAllocation' <- for mAllocation $ \alloc@Allocation{..} -> (alloc, ) + <$> toTextUrl (AllocationR allocationTerm allocationSchool allocationShorthand AShowR :#: cID) regForm <- if | is _Just mbAid -> do (courseRegisterForm', regButton) <- courseRegisterForm (Entity cid course) @@ -125,9 +124,9 @@ getCShowR tid ssh csh = do | otherwise -> return . modal $(widgetFile "course/login-to-register") . Left . SomeRoute $ AuthR LoginR registrationOpen <- hasWriteAccessTo $ CourseR tid ssh csh CRegisterR - + MsgRenderer mr <- getMsgRenderer - + let tutorialDBTable = DBTable{..} where diff --git a/src/Handler/Course/User.hs b/src/Handler/Course/User.hs index 690d02099..e7ad89d12 100644 --- a/src/Handler/Course/User.hs +++ b/src/Handler/Course/User.hs @@ -60,7 +60,7 @@ postCUserR tid ssh csh uCId = do registered <- exists [ CourseParticipantCourse ==. cid, CourseParticipantUser ==. uid, CourseParticipantState ==. CourseParticipantActive ] return (course, Entity uid user, registered) - + sections <- mapM (runMaybeT . ($ user) . ($ course)) [ courseUserProfileSection , courseUserNoteSection @@ -202,11 +202,11 @@ courseUserProfileSection (Entity cid Course{..}) (Entity uid User{ userShowSex = return $(widgetFile "course/user/profile") - + courseUserNoteSection :: Entity Course -> Entity User -> MaybeT Handler Widget courseUserNoteSection (Entity cid Course{..}) (Entity uid _) = do guardM . hasWriteAccessTo $ CourseR courseTerm courseSchool courseShorthand CUsersR - + currentRoute <- MaybeT getCurrentRoute (thisUniqueNote, noteText, noteEdits) <- lift . runDB $ do @@ -306,7 +306,7 @@ courseUserExamsSection (Entity cid Course{..}) (Entity uid _) = do guardM . hasWriteAccessTo $ CourseR courseTerm courseSchool courseShorthand CExamNewR uCID <- encrypt uid - + let examDBTable = DBTable{..} where diff --git a/src/Handler/Course/Users.hs b/src/Handler/Course/Users.hs index f7454ab38..c685164e2 100644 --- a/src/Handler/Course/Users.hs +++ b/src/Handler/Course/Users.hs @@ -137,7 +137,7 @@ _userSheets = _dbrOutput . _8 colUserComment :: IsDBTable m c => TermId -> SchoolId -> CourseShorthand -> Colonnade Sortable UserTableData (DBCell m c) colUserComment tid ssh csh = - sortable (Just "note") (i18nCell MsgCourseUserNote) $ views (_dbrOutput . $(multifocusG 2) (_1 . _entityKey) _3) $ \(uid, mbNoteKey) -> + sortable (Just "note") (i18nCell MsgCourseUserNote) $ views (_dbrOutput . $(multifocusG 2) (_1 . _entityKey) _3) $ \(uid, mbNoteKey) -> maybeEmpty mbNoteKey $ const $ anchorCellM (courseLink <$> encrypt uid) (hasComment True) where @@ -189,15 +189,15 @@ colUserSubmissionGroup = sortable (Just "submission-group") (i18nCell MsgSubmiss colUserSheets :: forall m c. IsDBTable m c => [SheetName] -> Cornice Sortable ('Cap 'Base) UserTableData (DBCell m c) colUserSheets shns = cap (Sortable Nothing caption) $ foldMap userSheetCol shns where - caption = i18nCell MsgCourseUserSheets + caption = i18nCell MsgCourseUserSheets & cellAttrs <>~ [ ("uw-hide-column-header", "sheets") , ("uw-hide-column-default-hidden", "") ] - + userSheetCol :: SheetName -> Colonnade Sortable UserTableData (DBCell m c) userSheetCol shn = sortable (Just . SortingKey $ "sheet-" <> shn) (i18nCell shn) . views (_userSheets . at shn) $ \case Just (preview _grading -> Just Points{..}, Just points) -> i18nCell $ MsgAchievedOf points maxPoints - Just (preview _grading -> Just grading', Just points) -> i18nCell . bool MsgNotPassed MsgPassed . fromMaybe False $ gradingPassed grading' points + Just (preview _grading -> Just grading', Just points) -> i18nCell . bool MsgNotPassed MsgPassed $ Just True == gradingPassed grading' points _other -> mempty @@ -208,7 +208,7 @@ data UserTableCsvStudyFeature = UserTableCsvStudyFeature , csvUserType :: StudyFieldType } deriving (Eq, Ord, Read, Show, Generic, Typeable) makeLenses_ ''UserTableCsvStudyFeature - + data UserTableCsv = UserTableCsv { csvUserName :: Text , csvUserSex :: Maybe Sex @@ -387,33 +387,33 @@ makeCourseUserTable cid acts restrict colChoices psValidator csvColumns = do , single $ sortUserEmail queryUser , single $ sortUserMatriclenr queryUser , sortUserSex (to queryUser . to (E.^. UserSex)) - , single $ ("degree" , SortColumn $ queryFeaturesDegree >>> (E.?. StudyDegreeName)) - , single $ ("degree-short", SortColumn $ queryFeaturesDegree >>> (E.?. StudyDegreeShorthand)) - , single $ ("field" , SortColumn $ queryFeaturesField >>> (E.?. StudyTermsName)) - , single $ ("field-short" , SortColumn $ queryFeaturesField >>> (E.?. StudyTermsShorthand)) - , single $ ("semesternr" , SortColumn $ queryFeaturesStudy >>> (E.?. StudyFeaturesSemester)) - , single $ ("registration", SortColumn $ queryParticipant >>> (E.^. CourseParticipantRegistration)) - , single $ ("note" , SortColumn $ queryUserNote >>> \note -> -- sort by last edit date + , single ("degree" , SortColumn $ queryFeaturesDegree >>> (E.?. StudyDegreeName)) + , single ("degree-short", SortColumn $ queryFeaturesDegree >>> (E.?. StudyDegreeShorthand)) + , single ("field" , SortColumn $ queryFeaturesField >>> (E.?. StudyTermsName)) + , single ("field-short" , SortColumn $ queryFeaturesField >>> (E.?. StudyTermsShorthand)) + , single ("semesternr" , SortColumn $ queryFeaturesStudy >>> (E.?. StudyFeaturesSemester)) + , single ("registration", SortColumn $ queryParticipant >>> (E.^. CourseParticipantRegistration)) + , single ("note" , SortColumn $ queryUserNote >>> \note -> -- sort by last edit date E.subSelectMaybe . E.from $ \edit -> do E.where_ $ note E.?. CourseUserNoteId E.==. E.just (edit E.^. CourseUserNoteEditNote) return . E.max_ $ edit E.^. CourseUserNoteEditTime ) - , single $ ("tutorials" , SortColumn $ queryUser >>> \user -> + , single ("tutorials" , SortColumn $ queryUser >>> \user -> E.subSelectMaybe . E.from $ \(tutorial `E.InnerJoin` participant) -> do E.on $ tutorial E.^. TutorialId E.==. participant E.^. TutorialParticipantTutorial E.&&. tutorial E.^. TutorialCourse E.==. E.val cid E.where_ $ participant E.^. TutorialParticipantUser E.==. user E.^. UserId return . E.min_ $ tutorial E.^. TutorialName ) - , single $ ("exams" , SortColumn $ queryUser >>> \user -> + , single ("exams" , SortColumn $ queryUser >>> \user -> E.subSelectMaybe . E.from $ \(exam `E.InnerJoin` examRegistration) -> do E.on $ exam E.^. ExamId E.==. examRegistration E.^. ExamRegistrationExam E.&&. exam E.^. ExamCourse E.==. E.val cid E.where_ $ examRegistration E.^. ExamRegistrationUser E.==. user E.^. UserId return . E.min_ $ exam E.^. ExamName ) - , single $ ("submission-group", SortColumn $ querySubmissionGroup >>> (E.?. SubmissionGroupName)) - , single $ ("state", SortColumn $ queryParticipant >>> (E.^. CourseParticipantState)) + , single ("submission-group", SortColumn $ querySubmissionGroup >>> (E.?. SubmissionGroupName)) + , single ("state", SortColumn $ queryParticipant >>> (E.^. CourseParticipantState)) , mconcat [ single ( SortingKey $ "sheet-" <> sheetName , SortColumn $ \(queryUser -> user) -> E.subSelectMaybe . E.from $ \(submission `E.InnerJoin` submissionUser) -> do @@ -421,8 +421,8 @@ makeCourseUserTable cid acts restrict colChoices psValidator csvColumns = do E.where_ $ submissionUser E.^. SubmissionUserUser E.==. user E.^. UserId E.where_ $ submission E.^. SubmissionSheet E.==. E.val shId return $ submission E.^. SubmissionRatingPoints - - ) + + ) | Entity shId Sheet{..} <- sheets ] ] @@ -433,38 +433,38 @@ makeCourseUserTable cid acts restrict colChoices psValidator csvColumns = do , single $ fltrUserMatriclenr queryUser , single $ fltrUserNameEmail queryUser , fltrUserSex (to queryUser . to (E.^. UserSex)) - , single $ ("field-name" , FilterColumn $ E.mkContainsFilter $ queryFeaturesField >>> (E.?. StudyTermsName)) - , single $ ("field-short" , FilterColumn $ E.mkContainsFilter $ queryFeaturesField >>> (E.?. StudyTermsShorthand)) - , single $ ("field-key" , FilterColumn $ E.mkExactFilter $ queryFeaturesField >>> (E.?. StudyTermsKey)) - , single $ ("field" , FilterColumn $ E.anyFilter + , single ("field-name" , FilterColumn $ E.mkContainsFilter $ queryFeaturesField >>> (E.?. StudyTermsName)) + , single ("field-short" , FilterColumn $ E.mkContainsFilter $ queryFeaturesField >>> (E.?. StudyTermsShorthand)) + , single ("field-key" , FilterColumn $ E.mkExactFilter $ queryFeaturesField >>> (E.?. StudyTermsKey)) + , single ("field" , FilterColumn $ E.anyFilter [ E.mkContainsFilterWith Just $ queryFeaturesField >>> E.joinV . (E.?. StudyTermsName) , E.mkContainsFilterWith Just $ queryFeaturesField >>> E.joinV . (E.?. StudyTermsShorthand) , E.mkExactFilterWith readMay $ queryFeaturesField >>> (E.?. StudyTermsKey) ] ) - , single $ ("degree" , FilterColumn $ E.anyFilter + , single ("degree" , FilterColumn $ E.anyFilter [ E.mkContainsFilterWith Just $ queryFeaturesDegree >>> E.joinV . (E.?. StudyDegreeName) , E.mkContainsFilterWith Just $ queryFeaturesDegree >>> E.joinV . (E.?. StudyDegreeShorthand) , E.mkExactFilterWith readMay $ queryFeaturesDegree >>> (E.?. StudyDegreeKey) ] ) - , single $ ("semesternr" , FilterColumn $ E.mkExactFilter $ queryFeaturesStudy >>> (E.?. StudyFeaturesSemester)) - , single $ ("tutorial" , FilterColumn $ E.mkExistsFilter $ \row criterion -> + , single ("semesternr" , FilterColumn $ E.mkExactFilter $ queryFeaturesStudy >>> (E.?. StudyFeaturesSemester)) + , single ("tutorial" , FilterColumn $ E.mkExistsFilter $ \row criterion -> E.from $ \(tutorial `E.InnerJoin` tutorialParticipant) -> do E.on $ tutorial E.^. TutorialId E.==. tutorialParticipant E.^. TutorialParticipantTutorial E.where_ $ tutorial E.^. TutorialCourse E.==. E.val cid E.&&. E.hasInfix (tutorial E.^. TutorialName) (E.val criterion :: E.SqlExpr (E.Value (CI Text))) E.&&. tutorialParticipant E.^. TutorialParticipantUser E.==. queryUser row E.^. UserId ) - , single $ ("exam" , FilterColumn $ E.mkExistsFilter $ \row criterion -> + , single ("exam" , FilterColumn $ E.mkExistsFilter $ \row criterion -> E.from $ \(exam `E.InnerJoin` examRegistration) -> do E.on $ exam E.^. ExamId E.==. examRegistration E.^. ExamRegistrationExam E.where_ $ exam E.^. ExamCourse E.==. E.val cid E.&&. E.hasInfix (exam E.^. ExamName) (E.val criterion :: E.SqlExpr (E.Value (CI Text))) E.&&. examRegistration E.^. ExamRegistrationUser E.==.queryUser row E.^. UserId ) - -- , ("course-registration", error "TODO") -- TODO - -- , ("course-user-note", error "TODO") -- TODO - , single $ ("submission-group", FilterColumn $ E.mkContainsFilter $ querySubmissionGroup >>> (E.?. SubmissionGroupName)) - , single $ ("active", FilterColumn $ E.mkExactFilter $ queryParticipant >>> (E.==. E.val CourseParticipantActive) . (E.^. CourseParticipantState)) + + + , single ("submission-group", FilterColumn $ E.mkContainsFilter $ querySubmissionGroup >>> (E.?. SubmissionGroupName)) + , single ("active", FilterColumn $ E.mkExactFilter $ queryParticipant >>> (E.==. E.val CourseParticipantActive) . (E.^. CourseParticipantState)) ] where single = uncurry Map.singleton dbtFilterUI mPrev = mconcat $ @@ -498,7 +498,7 @@ makeCourseUserTable cid acts restrict colChoices psValidator csvColumns = do { dbtCsvExportForm = UserCsvExportData <$> apopt checkBoxField (fslI MsgUserSimplifiedFeaturesOfStudyCsv & setTooltip MsgUserSimplifiedFeaturesOfStudyCsvTip) (Just $ csvUserSimplifiedFeaturesOfStudy def) <*> apopt checkBoxField (fslI MsgCourseUserCsvIncludeSheets & setTooltip MsgCourseUserCsvIncludeSheetsTip) (Just $ csvUserIncludeSheets def) - , dbtCsvDoEncode = \UserCsvExportData{..} -> C.mapM $ \(E.Value uid, row) -> flip runReaderT row $ + , dbtCsvDoEncode = \UserCsvExportData{..} -> C.mapM $ \(E.Value uid, row) -> flip runReaderT row $ UserTableCsv <$> view (hasUser . _userDisplayName) <*> view (hasUser . _userSex) @@ -615,7 +615,7 @@ postCUsersR tid ssh csh = do hasExams = not $ null exams examOccActs :: Map ExamId (AForm Handler (ExamId, Maybe ExamOccurrenceId)) examOccActs = examOccurrencesPerExam - & (map (bimap entityKey hoistMaybe)) + & map (bimap entityKey hoistMaybe) & Map.fromListWith (<>) & imap (\k v -> case v of [] -> pure (k, Nothing) @@ -684,7 +684,7 @@ postCUsersR tid ssh csh = do addMessageI Success $ MsgCourseUsersDeregistered nrDel redirect $ CourseR tid ssh csh CUsersR (CourseUserRegisterTutorialData{..}, selectedUsers) -> do - runDB . forM_ selectedUsers $ + runDB . forM_ selectedUsers $ void . insertUnique . TutorialParticipant registerTutorial addMessageI Success . MsgCourseUsersTutorialRegistered . fromIntegral $ Set.size selectedUsers redirect $ CourseR tid ssh csh CUsersR @@ -725,7 +725,7 @@ postCUsersR tid ssh csh = do ] [ CourseParticipantState =. CourseParticipantActive , CourseParticipantRegistration =. now - , CourseParticipantAllocated =. Nothing + , CourseParticipantAllocated =. Nothing ] guard $ didUpdate > 0 lift $ deleteWhere [ AllocationDeregisterCourse ==. Just cid, AllocationDeregisterUser ==. uid ] diff --git a/src/Handler/CryptoIDDispatch.hs b/src/Handler/CryptoIDDispatch.hs index 66c152c9f..2dbfece2a 100644 --- a/src/Handler/CryptoIDDispatch.hs +++ b/src/Handler/CryptoIDDispatch.hs @@ -62,7 +62,7 @@ instance (CryptoRoute ciphertext plaintext, Dispatch ciphertext ps) => Dispatch handleCryptoID :: CryptoIDError -> Handler (Maybe a) handleCryptoID _ = return Nothing dispatchTail = dispatchID (Proxy :: Proxy ps) ciphertext - + getCryptoUUIDDispatchR :: UUID -> Handler () getCryptoUUIDDispatchR uuid = dispatchID p uuid >>= maybe notFound (redirectAccessWith movedPermanently301) @@ -75,5 +75,5 @@ getCryptoUUIDDispatchR uuid = dispatchID p uuid >>= maybe notFound (redirectAcce getCryptoFileNameDispatchR :: CI FilePath -> Handler () getCryptoFileNameDispatchR path = dispatchID p path >>= maybe notFound (redirectAccessWith movedPermanently301) where - p :: Proxy '[ SubmissionId ] + p :: Proxy '[ SubmissionId ] p = Proxy diff --git a/src/Handler/Exam/AddUser.hs b/src/Handler/Exam/AddUser.hs index aeef1facc..912e52054 100644 --- a/src/Handler/Exam/AddUser.hs +++ b/src/Handler/Exam/AddUser.hs @@ -8,15 +8,15 @@ import Handler.Exam.RegistrationInvite import Handler.Utils import Handler.Utils.Exam import Handler.Utils.Invitations - + import qualified Data.Set as Set import Data.Semigroup (Option(..)) - + import Control.Monad.Error.Class (MonadError(..)) import Jobs.Queue - + import Generics.Deriving.Monoid @@ -43,7 +43,7 @@ postEAddUserR tid ssh csh examn = do ((usersToEnlist,formWgt),formEncoding) <- runFormPost . renderWForm FormStandard $ do now <- liftIO getCurrentTime occurrences <- liftHandler . runDB $ selectList [ExamOccurrenceExam ==. eid] [] - + let localNow = utcToLocalTime now tomorrowEndOfDay = case localTimeToUTC (LocalTime (addDays 2 $ localDay localNow) midnight) of @@ -65,7 +65,7 @@ postEAddUserR tid ssh csh examn = do = max tomorrowEndOfDay earliestDate' | otherwise = tomorrowEndOfDay - + deadline <- wreq utcTimeField (fslI MsgExamRegistrationInviteDeadline) (Just defDeadline) enlist <- wpopt checkBoxField (fslI MsgExamRegistrationEnlistDirectly & setTooltip MsgExamRegistrationEnlistDirectlyTip) (Just False) registerCourse <- wpopt checkBoxField (fslI MsgExamRegistrationRegisterCourse & setTooltip MsgExamRegistrationRegisterCourseTip) (Just False) @@ -132,7 +132,7 @@ postEAddUserR tid ssh csh examn = do lift $ lift examRegister throwError $ mempty { aurSuccess = pure userEmail } - unless registerCourse $ + unless registerCourse $ throwError $ mempty { aurNoCourseRegistration = pure userEmail } guardAuthResult =<< lift (lift $ evalAccessDB (CourseR tid ssh csh CAddUserR) True) diff --git a/src/Handler/Exam/AutoOccurrence.hs b/src/Handler/Exam/AutoOccurrence.hs index 1f38a7910..7f135b552 100644 --- a/src/Handler/Exam/AutoOccurrence.hs +++ b/src/Handler/Exam/AutoOccurrence.hs @@ -52,7 +52,7 @@ examAutoOccurrenceCalculateForm :: ExamAutoOccurrenceCalculateForm -> Form ExamA examAutoOccurrenceCalculateForm ExamAutoOccurrenceCalculateForm{ eaofConfig } = identifyForm FIDExamAutoOccurrenceCalculate . renderAForm FormStandard $ ExamAutoOccurrenceCalculateForm <$> eaocForm where - eaocForm = + eaocForm = (set _eaocMinimizeRooms <$> apopt checkBoxField (fslI MsgExamAutoOccurrenceMinimizeRooms & setTooltip MsgExamAutoOccurrenceMinimizeRoomsTip) (Just $ eaofConfig ^. _eaocMinimizeRooms)) <*> pure def @@ -62,7 +62,7 @@ examAutoOccurrenceNudgeForm occId protoForm html = do (btnRes, wgt) <- identifyForm (FIDExamAutoOccurrenceNudge $ ciphertext cID) (buttonForm' [BtnExamAutoOccurrenceNudgeUp, BtnExamAutoOccurrenceNudgeDown]) html oldDataRes <- globalPostParamField PostExamAutoOccurrencePrevious secretJsonField oldDataId <- newIdent - + let protoForm' = fromMaybe def $ oldDataRes <|> protoForm genForm btn = protoForm' & _eaofConfig . _eaocNudge %~ Map.insertWith (+) occId n where n = case btn of @@ -83,12 +83,12 @@ examAutoOccurrenceAcceptForm confirmData = identifyForm FIDExamAutoOccurrenceCon examAutoOccurrenceCalculateWidget :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Widget examAutoOccurrenceCalculateWidget tid ssh csh examn = do (formView, formEncoding) <- liftHandler . generateFormPost $ examAutoOccurrenceCalculateForm def - + wrapForm' BtnExamAutoOccurrenceCalculate $(i18nWidgetFile "exam-auto-occurrence-calculate") def { formAction = Just . SomeRoute $ CExamR tid ssh csh examn EAutoOccurrenceR , formEncoding } - + postEAutoOccurrenceR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html postEAutoOccurrenceR tid ssh csh examn = do @@ -96,8 +96,8 @@ postEAutoOccurrenceR tid ssh csh examn = do exam@(Entity eId _) <- fetchExam tid ssh csh examn occurrences <- selectList [ ExamOccurrenceExam ==. eId ] [ Asc ExamOccurrenceName ] return (exam, occurrences) - - + + ((calculateRes, _), _) <- runFormPost $ examAutoOccurrenceCalculateForm def nudgeRes <- sequence . flip Map.fromSet (setOf (folded . _entityKey) occurrences) $ \occId -> diff --git a/src/Handler/Exam/Correct.hs b/src/Handler/Exam/Correct.hs index 7e85169c9..2f66d8903 100644 --- a/src/Handler/Exam/Correct.hs +++ b/src/Handler/Exam/Correct.hs @@ -84,15 +84,15 @@ getECorrectR tid ssh csh examn = do return (exam, entityVal <$> examParts) mayEditResults <- hasWriteAccessTo $ CExamR tid ssh csh examn EUsersR - + let heading = prependCourseTitle tid ssh csh $ (mr . MsgExamCorrectHeading . CI.original) examName - + ptsInput :: ExamPartNumber -> Widget ptsInput n = do name <- newIdent fieldView (pointsField :: Field Handler Points) ("exam-correct__" <> toPathPiece n) name [("uw-exam-correct--part-input", toPathPiece n)] (Left "") False - + examGrades :: [ExamGrade] examGrades = universeF @@ -111,12 +111,12 @@ postECorrectR tid ssh csh examn = do CorrectInterfaceRequest{..} <- requireCheckJsonBody mayEditResults <- hasWriteAccessTo $ CExamR tid ssh csh examn EUsersR - + response <- runDB . exceptT (<$ transactionUndo) return $ do Entity eId Exam{} <- lift $ fetchExam tid ssh csh examn euid <- traverse decrypt ciqUser - guardMExceptT (maybe True ((>= 3) . length) $ euid ^? _Left) $ + guardMExceptT (maybe True ((>= 3) . length) $ euid ^? _Left) $ CorrectInterfaceResponseFailure Nothing <$> (getMessageRender <*> pure MsgExamCorrectErrorNeedleTooShort) @@ -188,7 +188,7 @@ postECorrectR tid ssh csh examn = do in CorrectInterfaceResponseFailure <$> (Just <$> userToResponse match) <*> (getMessageRender <*> pure msg) - + newExamPartResult <- lift $ upsert ExamPartResult { examPartResultExamPart = examPartId , examPartResultUser = uid @@ -230,7 +230,7 @@ postECorrectR tid ssh csh examn = do return $ newResult ^? _entityVal . _examResultResult | otherwise -> return $ mOldResult ^? _Just . _entityVal . _examResultResult | otherwise -> return Nothing - + user <- userToResponse match return CorrectInterfaceResponseSuccess { cirsUser = user @@ -252,7 +252,7 @@ postECorrectR tid ssh csh examn = do { ciraMessage = mr MsgExamCorrectErrorMultipleMatchingParticipants , ciraUsers = Set.fromList users } - + let responseStatus = case response of CorrectInterfaceResponseSuccess{} -> ok200 @@ -261,5 +261,5 @@ postECorrectR tid ssh csh examn = do whenM acceptsJson $ sendResponseStatus responseStatus $ toJSON response - + redirect $ CExamR tid ssh csh examn EShowR diff --git a/src/Handler/Exam/CorrectorInvite.hs b/src/Handler/Exam/CorrectorInvite.hs index c55da69f2..871fb8d12 100644 --- a/src/Handler/Exam/CorrectorInvite.hs +++ b/src/Handler/Exam/CorrectorInvite.hs @@ -18,7 +18,7 @@ import Data.Aeson hiding (Result(..)) import qualified Data.HashSet as HashSet - + instance IsInvitableJunction ExamCorrector where type InvitationFor ExamCorrector = Exam data InvitableJunction ExamCorrector = JunctionExamCorrector diff --git a/src/Handler/Exam/Form.hs b/src/Handler/Exam/Form.hs index d5781165c..1bfa7f79a 100644 --- a/src/Handler/Exam/Form.hs +++ b/src/Handler/Exam/Form.hs @@ -96,7 +96,7 @@ examForm template html = do <*> apopt checkBoxField (fslI MsgExamPublicStatistics & setTooltip MsgExamPublicStatisticsTip) (efPublicStatistics <$> template <|> Just True) <*> optionalActionA (examGradingRuleForm $ efGradingRule =<< template) (fslI MsgExamAutomaticGrading & setTooltip MsgExamAutomaticGradingTip) (is _Just . efGradingRule <$> template) <*> optionalActionA (examBonusRuleForm $ efBonusRule =<< template) (fslI MsgExamBonus) (is _Just . efBonusRule <$> template) - <*> (examOccurrenceRuleForm $ efOccurrenceRule <$> template) + <*> examOccurrenceRuleForm (efOccurrenceRule <$> template) <* aformSection MsgExamFormCorrection <*> examCorrectorsForm (efCorrectors <$> template) <* aformSection MsgExamFormParts @@ -117,7 +117,7 @@ examCorrectorsForm mPrev = wFormToAForm $ do (addRes, addView) <- mpreq (multiUserInvitationField . MUILookupAnyUser $ Just corrUserSuggestions) (fslI MsgExamCorrectorEmail & addName (nudge "email") & addPlaceholder (mr MsgLdapIdentificationOrEmail)) Nothing let addRes' - | otherwise + = addRes <&> \newDat oldDat -> if | existing <- newDat `Set.intersection` Set.fromList oldDat , not $ Set.null existing @@ -201,7 +201,7 @@ examPartsForm prev = wFormToAForm $ do fmap (fmap Set.fromList) . massInputAccumEditW miAdd' miCell' miButtonAction' miLayout' miIdent' (fslI MsgExamParts) False $ Set.toList <$> prev where examPartForm' nudge mPrev csrf = do - (epfIdRes, epfIdView) <- mopt hiddenField ("" & addName (nudge "id")) (Just $ epfId =<< mPrev) + (epfIdRes, epfIdView) <- mopt hiddenField ("" & addName (nudge "id")) (Just $ epfId =<< mPrev) (epfNumberRes, epfNumberView) <- mpreq (isoField (from _ExamPartNumber) $ textField & cfStrip & cfCI) (fslI MsgExamPartNumber & addName (nudge "number") & addPlaceholder "1, 6a, 3.1.4, ...") (epfNumber <$> mPrev) (epfNameRes, epfNameView) <- mopt (textField & cfStrip & cfCI) (fslI MsgExamPartName & addName (nudge "name")) (epfName <$> mPrev) (epfMaxPointsRes, epfMaxPointsView) <- mopt pointsField (fslI MsgExamPartMaxPoints & addName (nudge "max-points")) (epfMaxPoints <$> mPrev) @@ -221,7 +221,7 @@ examPartsForm prev = wFormToAForm $ do (res, formWidget) <- examPartForm' nudge Nothing csrf let addRes = res <&> \newDat (Set.fromList -> oldDat) -> if - | any (\old -> fromMaybe False $ (==) <$> epfName newDat <*> epfName old) oldDat + | any (\old -> Just True == ((==) <$> epfName newDat <*> epfName old)) oldDat -> FormFailure [mr MsgExamPartAlreadyExists] | otherwise -> FormSuccess $ pure newDat return (addRes, $(widgetFile "widgets/massinput/examParts/add")) @@ -336,10 +336,10 @@ validateExam = do guardValidation MsgExamRegisterToMustBeAfterRegisterFrom $ NTop efRegisterTo >= NTop efRegisterFrom guardValidation MsgExamDeregisterUntilMustBeAfterRegisterFrom $ NTop efDeregisterUntil >= NTop efRegisterFrom - guardValidation MsgExamStartMustBeAfterPublishOccurrenceAssignments . fromMaybe True $ (>=) <$> efStart <*> efPublishOccurrenceAssignments + guardValidation MsgExamStartMustBeAfterPublishOccurrenceAssignments $ Just False /= ((>=) <$> efStart <*> efPublishOccurrenceAssignments) guardValidation MsgExamEndMustBeAfterStart $ NTop efEnd >= NTop efStart - guardValidation MsgExamFinishedMustBeAfterEnd . fromMaybe True $ (>=) <$> efFinished <*> efEnd - guardValidation MsgExamFinishedMustBeAfterStart . fromMaybe True $ (>=) <$> efFinished <*> efStart + guardValidation MsgExamFinishedMustBeAfterEnd $ Just False /= ((>=) <$> efFinished <*> efEnd) + guardValidation MsgExamFinishedMustBeAfterStart $ Just False /= ((>=) <$> efFinished <*> efStart) forM_ efOccurrences $ \ExamOccurrenceForm{..} -> do guardValidation (MsgExamOccurrenceEndMustBeAfterStart eofName) $ NTop eofEnd >= NTop (Just eofStart) diff --git a/src/Handler/Exam/List.hs b/src/Handler/Exam/List.hs index 45c670559..e0c96add7 100644 --- a/src/Handler/Exam/List.hs +++ b/src/Handler/Exam/List.hs @@ -6,7 +6,7 @@ module Handler.Exam.List import Import import Handler.Utils - + import qualified Data.Map as Map import qualified Database.Esqueleto as E @@ -75,7 +75,7 @@ mkExamTable (Entity cid Course{..}) = do examDBTableValidator = def & defaultSorting [SortAscBy "time"] & forceFilter "may-read" (Any True) - + dbTable examDBTableValidator examDBTable diff --git a/src/Handler/Exam/New.hs b/src/Handler/Exam/New.hs index 5c9e2d2c3..ebc1fcde8 100644 --- a/src/Handler/Exam/New.hs +++ b/src/Handler/Exam/New.hs @@ -12,7 +12,7 @@ import Handler.Utils import Handler.Utils.Invitations import Jobs.Queue - + import qualified Data.Conduit.Combinators as C @@ -29,7 +29,7 @@ postCExamNewR tid ssh csh = do formResult newExamResult $ \ExamForm{..} -> do insertRes <- runDBJobs $ do now <- liftIO getCurrentTime - + insertRes <- insertUnique Exam { examName = efName , examCourse = cid @@ -90,7 +90,7 @@ postCExamNewR tid ssh csh = do when didRecord $ audit $ TransactionExamResultEdit examid courseParticipantUser runConduit $ selectSource [ CourseParticipantCourse ==. cid, CourseParticipantState ==. CourseParticipantInactive True ] [] .| C.mapM_ recordNoShow - + return insertRes case insertRes of Nothing -> addMessageI Error $ MsgExamNameTaken efName diff --git a/src/Handler/Exam/Register.hs b/src/Handler/Exam/Register.hs index 15e2a02eb..0ed4c1385 100644 --- a/src/Handler/Exam/Register.hs +++ b/src/Handler/Exam/Register.hs @@ -21,7 +21,7 @@ data ButtonExamRegister = BtnExamRegisterOccurrence instance Universe ButtonExamRegister instance Finite ButtonExamRegister nullaryPathPiece ''ButtonExamRegister $ camelToPathPiece' 2 - + instance Button UniWorX ButtonExamRegister where btnClasses BtnExamRegisterOccurrence = [BCIsButton, BCPrimary] btnClasses BtnExamSwitchOccurrence = [BCIsButton, BCPrimary] @@ -70,7 +70,7 @@ postERegisterOccR tid ssh csh examn occn = do return (eId, occ) ((btnResult, _), _) <- runFormPost buttonForm - + formResult btnResult $ \case BtnExamDeregister -> do runDB $ do @@ -89,4 +89,4 @@ postERegisterOccR tid ssh csh examn occn = do _other -> error "Unexpected due to definition of buttonForm'" redirect $ CExamR tid ssh csh examn EShowR - + diff --git a/src/Handler/Exam/RegistrationInvite.hs b/src/Handler/Exam/RegistrationInvite.hs index 0087c26c0..05703e42a 100644 --- a/src/Handler/Exam/RegistrationInvite.hs +++ b/src/Handler/Exam/RegistrationInvite.hs @@ -16,13 +16,13 @@ import Handler.Utils.Invitations import qualified Data.Set as Set import Text.Hamlet (ihamlet) - + import Data.Aeson hiding (Result(..)) import Jobs.Queue import qualified Data.HashSet as HashSet - + instance IsInvitableJunction ExamRegistration where type InvitationFor ExamRegistration = Exam @@ -98,7 +98,7 @@ examRegistrationInvitationConfig = InvitationConfig{..} (False, True ) -> do fieldRes <- wreq (studyFeaturesFieldFor Nothing False [] $ Just uid) (fslI MsgCourseStudyFeature) Nothing return $ (JunctionExamRegistration invDBExamRegistrationOccurrence now, ) . Just <$> fieldRes - (True , _ ) -> return $ pure (JunctionExamRegistration invDBExamRegistrationOccurrence now, Nothing) + (True , _ ) -> return $ pure (JunctionExamRegistration invDBExamRegistrationOccurrence now, Nothing) invitationInsertHook _ (Entity eid Exam{..}) _ ExamRegistration{..} mField act = do whenIsJust mField $ \cpField -> do void $ upsert @@ -110,7 +110,7 @@ examRegistrationInvitationConfig = InvitationConfig{..} ] queueDBJob . JobQueueNotification $ NotificationCourseRegistered examRegistrationUser examCourse audit $ TransactionCourseParticipantEdit examCourse examRegistrationUser - + let doAudit = audit $ TransactionExamRegister eid examRegistrationUser act <* doAudit invitationSuccessMsg (Entity _ Exam{..}) _ = return . SomeMessage $ MsgExamRegistrationInvitationAccepted examName diff --git a/src/Handler/Exam/Show.hs b/src/Handler/Exam/Show.hs index c86985c46..e8b306d85 100644 --- a/src/Handler/Exam/Show.hs +++ b/src/Handler/Exam/Show.hs @@ -96,9 +96,9 @@ getEShowR tid ssh csh examn = do sumRegisteredCount = sumOf (folded . _3) occurrences - noBonus = fromMaybe False $ do + noBonus = (Just True ==) $ do guardM $ bonusOnlyPassed <$> examBonusRule - return . fromMaybe True $ result ^? _Just . _entityVal . _examResultResult . _examResult . to (either id $ view passingGrade) . _Wrapped . to not + return $ Just False /= result ^? _Just . _entityVal . _examResultResult . _examResult . to (either id $ view passingGrade) . _Wrapped . to not sumPoints = fmap getSum . mconcat $ catMaybes [ Just $ foldMap (fmap Sum . examPartResultResult . entityVal) results @@ -187,5 +187,5 @@ getEShowR tid ssh csh examn = do examBonusW bonusRule = $(widgetFile "widgets/bonusRule") occurrenceMapping :: ExamOccurrenceName -> Maybe Widget - occurrenceMapping occName = examOccurrenceMappingDescriptionWidget <$> fmap examOccurrenceMappingRule examExamOccurrenceMapping <*> (fmap examOccurrenceMappingMapping examExamOccurrenceMapping >>= Map.lookup occName) + occurrenceMapping occName = examOccurrenceMappingDescriptionWidget <$> fmap examOccurrenceMappingRule examExamOccurrenceMapping <*> (examExamOccurrenceMapping >>= Map.lookup occName . examOccurrenceMappingMapping) $(widgetFile "exam-show") diff --git a/src/Handler/Exam/Users.hs b/src/Handler/Exam/Users.hs index 1a5c67420..55545bbff 100644 --- a/src/Handler/Exam/Users.hs +++ b/src/Handler/Exam/Users.hs @@ -88,7 +88,7 @@ queryExamOccurrence = $(sqlLOJproj 6 2) queryCourseParticipant :: ExamUserTableExpr -> E.SqlExpr (Maybe (Entity CourseParticipant)) queryCourseParticipant = $(sqlLOJproj 2 1) . $(sqlLOJproj 6 3) - + queryStudyFeatures :: ExamUserTableExpr -> E.SqlExpr (Maybe (Entity StudyFeatures)) queryStudyFeatures = $(sqlIJproj 3 1) . $(sqlLOJproj 2 2) . $(sqlLOJproj 6 3) @@ -184,7 +184,7 @@ csvExamPartHeader = prism' toHeader fromHeader review _ExamPartNumber . CI.mk <$> stripPrefix partPrefix tHdr partPrefix = "part-" - + data ExamUserTableCsv = ExamUserTableCsv { csvEUserSurname :: Maybe Text @@ -498,7 +498,7 @@ postEUsersR tid ssh csh examn = do [ (epId, (examPart, mbRes)) | (Entity epId examPart, mbRes) <- rawResults ] - + dbtColonnade = mconcat $ catMaybes [ pure $ dbSelect (_2 . applying _2) _1 $ return . view (resultExamRegistration . _entityKey) , pure $ colUserNameLink (CourseR tid ssh csh . CUserR) @@ -507,7 +507,7 @@ postEUsersR tid ssh csh examn = do , pure $ colDegreeShort resultStudyDegree , pure $ colFeaturesSemester resultStudyFeatures , pure $ sortable (Just "occurrence") (i18nCell MsgExamOccurrence) $ maybe mempty (anchorCell' (\n -> CExamR tid ssh csh examn EShowR :#: [st|exam-occurrence__#{n}|]) id . examOccurrenceName . entityVal) . view _userTableOccurrence - , guardOn showPasses $ sortable Nothing (i18nCell MsgAchievedPasses) $ \(view $ resultUser . _entityKey -> uid) -> + , guardOn showPasses $ sortable Nothing (i18nCell MsgAchievedPasses) $ \(view $ resultUser . _entityKey -> uid) -> let SheetGradeSummary{achievedPasses} = examBonusAchieved uid bonus SheetGradeSummary{numSheetsPasses} = examBonusPossible uid bonus in propCell (getSum achievedPasses) (getSum numSheetsPasses) @@ -516,7 +516,7 @@ postEUsersR tid ssh csh examn = do SheetGradeSummary{sumSheetsPoints} = examBonusPossible uid bonus in propCell (getSum achievedPoints) (getSum sumSheetsPoints) , guardOn doBonus $ sortable (Just "bonus") (i18nCell MsgExamBonusAchieved) . automaticCell $ resultExamBonus . _entityVal . _examBonusBonus . to Right <> resultAutomaticExamBonus' . to Left - , pure $ mconcat + , pure $ mconcat [ sortable (Just $ fromText [st|part-#{toPathPiece examPartNumber}|]) (i18nCell $ MsgExamPartNumbered examPartNumber) $ maybe mempty i18nCell . preview (resultExamPartResult epId . _Just . _entityVal . _examPartResultResult) | Entity epId ExamPart{..} <- sortOn (examPartNumber . entityVal) examParts ] @@ -597,7 +597,7 @@ postEUsersR tid ssh csh examn = do tell =<< optionsF [ ExamUserDeregister, ExamUserAssignOccurrence ] when (is _Just examGradingRule) $ tell =<< optionsF [ ExamUserAcceptComputedResult, ExamUserResetToComputedResult ] - when (not $ null examParts) $ + unless (null examParts) $ tell =<< optionsF [ ExamUserSetPartResult ] when doBonus $ tell =<< optionsF [ ExamUserSetBonus ] @@ -651,7 +651,7 @@ postEUsersR tid ssh csh examn = do (isPart, uid) <- lift $ guessUser' dbCsvNew if | isPart -> do - yieldM $ ExamUserCsvRegisterData <$> pure uid <*> lookupOccurrence dbCsvNew + yieldM $ ExamUserCsvRegisterData uid <$> lookupOccurrence dbCsvNew newFeatures <- lift $ lookupStudyFeatures dbCsvNew Entity cpId CourseParticipant{ courseParticipantField = oldFeatures } <- lift . getJustBy $ UniqueParticipant uid examCourse when (newFeatures /= oldFeatures) $ @@ -662,10 +662,10 @@ postEUsersR tid ssh csh examn = do iforMOf_ (ifolded <. _Just) (csvEUserExamPartResults dbCsvNew) $ \epNumber epRes -> when (epNumber `elem` examPartNumbers) $ yield $ ExamUserCsvSetPartResultData uid epNumber (Just epRes) - + when (doBonus && is _Just (join $ csvEUserBonus dbCsvNew)) $ yield . ExamUserCsvSetBonusData False uid . join $ csvEUserBonus dbCsvNew - + whenIsJust (csvEUserExamResult dbCsvNew) $ \res -> do yield . ExamUserCsvSetResultData False uid $ csvEUserExamResult dbCsvNew guardResultKind res @@ -693,7 +693,7 @@ postEUsersR tid ssh csh examn = do let newResults :: Maybe (Map ExamPartNumber ExamResultPoints) newResults = sequence (csvEUserExamPartResults dbCsvNew) - <|> sequence (toMapOf (resultExamParts .> ito (over _1 $ examPartNumber) <. to (fmap $ examPartResultResult . entityVal)) dbCsvOld) + <|> sequence (toMapOf (resultExamParts .> ito (over _1 examPartNumber) <. to (fmap $ examPartResultResult . entityVal)) dbCsvOld) newBonus, oldBonus :: Maybe Points newBonus = join (csvEUserBonus dbCsvNew) @@ -702,7 +702,7 @@ postEUsersR tid ssh csh examn = do newResult, oldResult :: Maybe ExamResultPassedGrade newResult = fmap (fmap $ bool Right (Left . view passingGrade) $ is _ExamGradingGrades examGradingMode) . examGrade examVal (newBonus <|> oldBonus) =<< newResults oldResult = dbCsvOld ^? (resultExamResult . _entityVal . _examResultResult <> resultAutomaticExamResult') - + when doBonus $ case newBonus of _ | newBonus == oldBonus @@ -715,7 +715,7 @@ postEUsersR tid ssh csh examn = do -> yield $ ExamUserCsvSetBonusData False uid newBonus Just _ -> yield $ ExamUserCsvSetBonusData True uid newBonus - + case newResult of _ | csvEUserExamResult dbCsvNew == oldResult -> return () @@ -964,15 +964,15 @@ postEUsersR tid ssh csh examn = do | is (_ExamAttended . _Left) res -> ExamGradingPass | otherwise -> ExamGradingGrades | otherwise = return () - + registeredUserName :: Map (E.Value ExamRegistrationId) ExamUserTableData -> ExamRegistrationId -> Widget registeredUserName existing (E.Value -> registration) = nameWidget userDisplayName userSurname where Entity _ User{..} = view resultUser $ existing ! registration - + guessUser' :: ExamUserTableCsv -> DB (Bool, UserId) guessUser' ExamUserTableCsv{..} = do - let criteria = Set.fromList $ catMaybes + let criteria = Set.fromList $ catMaybes [ GuessUserMatrikelnummer <$> csvEUserMatriculation , GuessUserDisplayName <$> csvEUserName , GuessUserSurname <$> csvEUserSurname @@ -1088,7 +1088,7 @@ postEUsersR tid ssh csh examn = do audit $ TransactionExamBonusEdit eId uid | otherwise -> return () - + insert_ ExamResult { examResultExam = eId , examResultUser = uid diff --git a/src/Handler/ExamOffice/Course.hs b/src/Handler/ExamOffice/Course.hs index 2db5ecf76..6ed103c3d 100644 --- a/src/Handler/ExamOffice/Course.hs +++ b/src/Handler/ExamOffice/Course.hs @@ -28,7 +28,7 @@ getCExamOfficeR = postCExamOfficeR postCExamOfficeR tid ssh csh = do uid <- requireAuthId isModal <- hasCustomHeader HeaderIsModal - + (cid, optOuts, hasForced) <- runDB $ do cid <- getKeyBy404 (TermSchoolCourseShort tid ssh csh) optOuts <- selectList [ CourseUserExamOfficeOptOutCourse ==. cid, CourseUserExamOfficeOptOutUser ==. uid ] [] @@ -65,7 +65,7 @@ postCExamOfficeR tid ssh csh = do setTitleI MsgMenuCourseExamOffice let explanation = $(i18nWidgetFile "course-exam-office-explanation") - + [whamlet| $newline never
diff --git a/src/Handler/ExamOffice/Exam.hs b/src/Handler/ExamOffice/Exam.hs index 25458c0dd..e5be277ea 100644 --- a/src/Handler/ExamOffice/Exam.hs +++ b/src/Handler/ExamOffice/Exam.hs @@ -34,7 +34,7 @@ embedRenderMessage ''UniWorX ''ButtonCloseExam id instance Button UniWorX ButtonCloseExam where btnClasses BtnCloseExam = [BCIsButton] - + examCloseWidget :: SomeRoute UniWorX -> ExamId -> Handler Widget examCloseWidget dest eId = do Exam{..} <- runDB $ get404 eId @@ -47,7 +47,7 @@ examCloseWidget dest eId = do unless (is _Nothing examClosed) $ invalidArgs ["Exam is already closed"] - + runDB $ update eId [ ExamClosed =. Just now ] addMessageI Success MsgExamDidClose redirect dest @@ -189,7 +189,7 @@ newtype ExamUserCsvExportData = ExamUserCsvExportData { csvEUserMarkSynchronised :: Bool } deriving (Eq, Ord, Read, Show, Generic, Typeable) - + -- | View a list of all users' grades that the current user has access to getEGradesR, postEGradesR :: TermId -> SchoolId -> CourseShorthand -> ExamName -> Handler Html getEGradesR = postEGradesR @@ -271,7 +271,7 @@ postEGradesR tid ssh csh examn = do E.where_ $ examResult E.^. ExamResultExam E.==. E.val eid - unless isLecturer $ + unless isLecturer $ E.where_ $ Exam.examOfficeExamResultAuth (E.val uid) examResult return (examResult, user, occurrence, studyFeatures, studyDegree, studyField, examRegistration, isSynced) @@ -314,9 +314,9 @@ postEGradesR tid ssh csh examn = do syncs' = [ Right sync | sync@(_, _, t, _) <- syncs, t > lastChange] ++ [ Left lastChange ] ++ [ Right sync | sync@(_, _, t, _) <- syncs, t <= lastChange] - + syncIcon :: Widget - syncIcon + syncIcon | not isSynced , not hasSyncs = mempty @@ -324,7 +324,7 @@ postEGradesR tid ssh csh examn = do = toWidget iconNotOK | otherwise = toWidget iconOK - + syncsModal :: Widget syncsModal = $(widgetFile "exam-office/exam-result-synced") lift $ bool id (flip modal $ Right syncsModal) hasSyncs syncIcon diff --git a/src/Handler/ExamOffice/Exams.hs b/src/Handler/ExamOffice/Exams.hs index be99b1737..c2f4f1c75 100644 --- a/src/Handler/ExamOffice/Exams.hs +++ b/src/Handler/ExamOffice/Exams.hs @@ -30,7 +30,7 @@ queryExam = to $ $(E.sqlIJproj 2 1) . $(E.sqlFOJproj 2 1) queryCourse :: Getter ExamsTableExpr (E.SqlExpr (Maybe (Entity Course))) queryCourse = to $ $(E.sqlIJproj 2 2) . $(E.sqlFOJproj 2 1) - + queryExternalExam :: Getter ExamsTableExpr (E.SqlExpr (Maybe (Entity ExternalExam))) queryExternalExam = to $(E.sqlFOJproj 2 2) @@ -48,7 +48,7 @@ querySynchronised office = to . runReader $ do E.where_ $ ExternalExam.examOfficeExternalExamResultAuth office externalExamResult E.where_ $ ExternalExam.resultIsSynced office externalExamResult return $ E.maybe (E.val 0) examSynchronised (exam' E.?. ExamId) E.+. E.maybe (E.val 0) externalExamSynchronised (externalExam' E.?. ExternalExamId) - + queryResults :: E.SqlExpr (E.Value UserId) -> Getter ExamsTableExpr (E.SqlExpr (E.Value Natural)) queryResults office = to . runReader $ do exam' <- view queryExam @@ -75,7 +75,7 @@ queryIsSynced now office = to . runReader $ do E.where_ $ externalExamResult E.^. ExternalExamResultExam E.==. externalExamId E.where_ $ ExternalExam.examOfficeExternalExamResultAuth office externalExamResult E.where_ . E.not_ $ ExternalExam.resultIsSynced office externalExamResult - open examClosed' = E.maybe E.true (E.>. E.val now) $ examClosed' + open examClosed' = E.maybe E.true (E.>. E.val now) examClosed' return $ E.maybe E.false examSynchronised (exam' E.?. ExamId) E.||. E.maybe E.false open (exam' E.?. ExamClosed) E.||. E.maybe E.false externalExamSynchronised (externalExam' E.?. ExternalExamId) @@ -95,7 +95,7 @@ resultResults = _dbrOutput . _3 resultIsSynced :: Getter ExamsTableData Bool resultIsSynced = to $ (>=) <$> view resultSynchronised <*> view resultResults - + -- | List of all exams where the current user may (in her function as -- exam-office) access users grades getEOExamsR :: Handler Html @@ -106,15 +106,15 @@ getEOExamsR = do examsTable <- runDB $ do let examLink :: Course -> Exam -> SomeRoute UniWorX - examLink Course{..} Exam{..} + examLink Course{..} Exam{..} = SomeRoute $ CExamR courseTerm courseSchool courseShorthand examName EGradesR courseLink :: Course -> SomeRoute UniWorX courseLink Course{..} = SomeRoute $ CourseR courseTerm courseSchool courseShorthand CShowR - + externalExamLink :: ExternalExam -> SomeRoute UniWorX - externalExamLink ExternalExam{..} + externalExamLink ExternalExam{..} = SomeRoute $ EExamR externalExamTerm externalExamSchool externalExamCourseName externalExamExamName EEGradesR querySynchronised' = querySynchronised $ E.val uid @@ -150,11 +150,9 @@ getEOExamsR = do case (exam, course, externalExam) of (Just exam', Just course', Nothing) -> - (,,) - <$> pure (Right (exam', course')) <*> view (_4 . _Value) <*> view (_5 . _Value) + (Right (exam', course'),,) <$> view (_4 . _Value) <*> view (_5 . _Value) (Nothing, Nothing, Just externalExam') -> - (,,) - <$> pure (Left externalExam') <*> view (_4 . _Value) <*> view (_5 . _Value) + (Left externalExam',,) <$> view (_4 . _Value) <*> view (_5 . _Value) _other -> return $ error "Got exam & externalExam in same result" @@ -182,7 +180,7 @@ getEOExamsR = do & cellAttrs <>~ [ ("class", "heated") , ("style", [st|--hotness: #{tshow (heat results synced)}|]) ] - + dbtColonnade :: Colonnade Sortable _ _ dbtColonnade = mconcat @@ -192,7 +190,7 @@ getEOExamsR = do ) $ emptyOpticColonnade (resultExam . _entityVal . _examName <> resultExternalExam . _entityVal . _externalExamExamName) colExamName , emptyOpticColonnade (resultExam . _entityVal . $(multifocusG 2) _examStart _examEnd) colExamTime - , emptyOpticColonnade (resultExam . _entityVal . _examFinished) colExamFinishedOffice + , emptyOpticColonnade (resultExam . _entityVal . _examFinished) colExamFinishedOffice , emptyOpticColonnade (resultExam . _entityVal . _examClosed) colExamClosed , maybeAnchorColonnade (previews (resultCourse . _entityVal) courseLink) $ emptyOpticColonnade (resultCourse . _entityVal . _courseName <> resultExternalExam . _entityVal . _externalExamCourseName) colCourseName diff --git a/src/Handler/ExamOffice/ExternalExam.hs b/src/Handler/ExamOffice/ExternalExam.hs index 1e7bafffd..8ca0c6c8e 100644 --- a/src/Handler/ExamOffice/ExternalExam.hs +++ b/src/Handler/ExamOffice/ExternalExam.hs @@ -7,7 +7,7 @@ import Import import Handler.Utils import Handler.Utils.ExternalExam.Users - + getEEGradesR, postEEGradesR :: TermId -> SchoolId -> CourseName -> ExamName -> Handler Html getEEGradesR = postEEGradesR postEEGradesR tid ssh coursen examn = do diff --git a/src/Handler/ExamOffice/Fields.hs b/src/Handler/ExamOffice/Fields.hs index 58f7bc57a..53395acfc 100644 --- a/src/Handler/ExamOffice/Fields.hs +++ b/src/Handler/ExamOffice/Fields.hs @@ -11,7 +11,7 @@ import qualified Database.Esqueleto as E import qualified Data.Set as Set import qualified Data.Map as Map - + data ExamOfficeFieldMode = EOFNotSubscribed | EOFSubscribed @@ -78,7 +78,7 @@ postEOFieldsR = do oldFields <- runDB $ do fields <- E.select . E.from $ \examOfficeField -> do E.where_ $ examOfficeField E.^. ExamOfficeFieldOffice E.==. E.val uid - return $ (examOfficeField E.^. ExamOfficeFieldField, examOfficeField E.^. ExamOfficeFieldForced) + return (examOfficeField E.^. ExamOfficeFieldField, examOfficeField E.^. ExamOfficeFieldForced) return $ toMapOf (folded .> ito (over _1 E.unValue . over _2 E.unValue)) fields ((fieldsRes, fieldsView), fieldsEnc) <- runFormPost . makeExamOfficeFieldsForm uid $ Just oldFields diff --git a/src/Handler/ExamOffice/Users.hs b/src/Handler/ExamOffice/Users.hs index 878e228b2..1592298db 100644 --- a/src/Handler/ExamOffice/Users.hs +++ b/src/Handler/ExamOffice/Users.hs @@ -21,7 +21,7 @@ import qualified Data.Map as Map import Data.Map ((!), (!?)) import qualified Data.HashSet as HashSet - + instance IsInvitableJunction ExamOfficeUser where type InvitationFor ExamOfficeUser = User @@ -84,11 +84,11 @@ examOfficeUserInvitationConfig = InvitationConfig{..} return $ SomeMessage MsgExamOfficeUserInvitationAccepted invitationUltDest _ _ = return $ SomeRoute NewsR - + makeExamOfficeUsersForm :: Maybe (Set (Either UserEmail UserId)) -> Form (Set (Either UserEmail UserId)) makeExamOfficeUsersForm template = renderWForm FormStandard $ do cRoute <- fromMaybe (error "makeExamOfficeUsersForm called from 404-handler") <$> getCurrentRoute - + let miAdd' :: (Text -> Text) -> FieldView UniWorX @@ -132,7 +132,7 @@ makeExamOfficeUsersForm template = renderWForm FormStandard $ do return $ map Left invitations ++ map Right knownUsers' fmap Set.fromList <$> massInputAccumW miAdd' miCell' miButtonAction' miLayout' miIdent' fSettings fRequired template' - + -- | Manage the list of users this user (in her function as exam-office) -- has an interest in, i.e. that authorize her to view their grades diff --git a/src/Handler/ExternalExam/Edit.hs b/src/Handler/ExternalExam/Edit.hs index 6240fd6b5..48f4d70a0 100644 --- a/src/Handler/ExternalExam/Edit.hs +++ b/src/Handler/ExternalExam/Edit.hs @@ -39,7 +39,7 @@ postEEEditR tid ssh coursen examn = do , eefOfficeSchools = schools , eefStaff = staff } - + ((examResult, examWidget'), examEnctype) <- runFormPost . externalExamForm $ Just template formResult examResult $ \ExternalExamForm{..} -> do @@ -54,7 +54,7 @@ postEEEditR tid ssh coursen examn = do } when (is _Nothing replaceRes) $ do audit $ TransactionExternalExamEdit eeId - + forM_ (eefStaff `setSymmDiff` staff) $ \change -> if | change `Set.member` eefStaff -> case change of Left invEmail -> do diff --git a/src/Handler/ExternalExam/Form.hs b/src/Handler/ExternalExam/Form.hs index 93c4273d5..9d54f3c04 100644 --- a/src/Handler/ExternalExam/Form.hs +++ b/src/Handler/ExternalExam/Form.hs @@ -5,7 +5,7 @@ module Handler.ExternalExam.Form import Import import Handler.Utils - + import Handler.ExternalExam.StaffInvite () import qualified Data.Set as Set @@ -104,7 +104,7 @@ externalExamForm template = validateForm validateExternalExam $ \html -> do validateExternalExam :: (MonadThrow m, MonadHandler m, HandlerSite m ~ UniWorX) => FormValidator ExternalExamForm m () validateExternalExam = do State.modify $ \eeForm -> eeForm & over _eefOfficeSchools (Set.delete $ eeForm ^. _eefSchool) - + ExternalExamForm{..} <- State.get isAdmin <- hasWriteAccessTo $ SchoolR eefSchool SchoolEditR diff --git a/src/Handler/ExternalExam/List.hs b/src/Handler/ExternalExam/List.hs index edd02e199..afcdf2e8f 100644 --- a/src/Handler/ExternalExam/List.hs +++ b/src/Handler/ExternalExam/List.hs @@ -3,7 +3,7 @@ module Handler.ExternalExam.List ) where import Import - + import Handler.Utils import qualified Database.Esqueleto as E @@ -24,7 +24,7 @@ getEExamListR = do queryEExam = $(E.sqlIJproj 2 1) querySchool = $(E.sqlIJproj 2 2) - + dbtSQLQuery (eexam `E.InnerJoin` school) = do E.on $ eexam E.^. ExternalExamSchool E.==. school E.^. SchoolId let diff --git a/src/Handler/ExternalExam/New.hs b/src/Handler/ExternalExam/New.hs index fb89f6418..e4f7dffac 100644 --- a/src/Handler/ExternalExam/New.hs +++ b/src/Handler/ExternalExam/New.hs @@ -32,7 +32,7 @@ postEExamNewR = do } whenIsJust insertRes $ \eeId -> do audit $ TransactionExternalExamEdit eeId - + let eefOfficeSchools' = do externalExamOfficeSchoolSchool <- Set.toList eefOfficeSchools guard $ externalExamOfficeSchoolSchool /= eefSchool @@ -41,7 +41,7 @@ postEExamNewR = do insertMany_ eefOfficeSchools' forM_ eefOfficeSchools' $ \ExternalExamOfficeSchool{..} -> audit $ TransactionExternalExamOfficeSchoolEdit eeId externalExamOfficeSchoolSchool - + let (invites, adds) = partitionEithers $ Set.toList eefStaff eefStaff' = do externalExamStaffUser <- adds @@ -50,7 +50,7 @@ postEExamNewR = do insertMany_ eefStaff' forM_ eefStaff' $ \ExternalExamStaff{..} -> audit $ TransactionExternalExamStaffEdit eeId externalExamStaffUser - + sinkInvitationsF externalExamStaffInvitationConfig $ map (, eeId, (InvDBDataExternalExamStaff, InvTokenDataExternalExamStaff)) invites forM_ invites $ \invEmail -> audit $ TransactionExternalExamStaffInviteEdit eeId invEmail diff --git a/src/Handler/Help.hs b/src/Handler/Help.hs index 28bf3e804..4c2bd4f0b 100644 --- a/src/Handler/Help.hs +++ b/src/Handler/Help.hs @@ -10,7 +10,7 @@ import qualified Data.Map as Map import qualified Data.Yaml as Yaml import qualified Control.Monad.State.Class as State - + data HelpIdentOptions = HIUser | HIEmail | HIAnonymous deriving (Eq, Ord, Bounded, Enum, Show, Read) @@ -58,7 +58,7 @@ helpForm mReferer mUid = renderWForm FormStandard $ do Nothing -> return $ pure Nothing Just err -> let prettyErr = decodeUtf8 $ Yaml.encode err - in optionalActionW + in optionalActionW (err <$ aforced textareaField (fslI MsgHelpError) (Textarea prettyErr)) (fslI MsgHelpSendLastError) (Just True) @@ -69,7 +69,7 @@ helpForm mReferer mUid = renderWForm FormStandard $ do <*> hfSubject' <*> hfRequest' <*> hfError' - + validateHelpForm :: FormValidator HelpForm Handler () validateHelpForm = do HelpForm{..} <- State.get @@ -99,7 +99,7 @@ postHelpR = do whenIsJust hfError $ \error' -> modifySessionJson SessionError $ assertM (/= error') - + tell . pure =<< messageI Success MsgHelpSent defaultLayout $ do @@ -111,5 +111,5 @@ postHelpR = do } mFaqs <- (>>= \(mWgt, truncated) -> (, truncated) <$> mWgt) <$> traverse (faqsWidget $ Just 5) (Just <$> mReferer) - + $(widgetFile "help") diff --git a/src/Handler/Info.hs b/src/Handler/Info.hs index acb282192..9c37026ab 100644 --- a/src/Handler/Info.hs +++ b/src/Handler/Info.hs @@ -53,7 +53,7 @@ getInfoLecturerR = $(i18nWidgetFile "info-lecturer") where allocationInfo = $(i18nWidgetFile "allocation-info") - + tooltipNew, tooltipProblem, tooltipPlanned, tooltipNewU2W :: WidgetFor UniWorX () tooltipNew = [whamlet| _{MsgLecturerInfoTooltipNew} |] tooltipProblem = [whamlet| _{MsgLecturerInfoTooltipProblem} |] @@ -64,7 +64,7 @@ getInfoLecturerR = probFeatInline = [whamlet| ^{iconTooltip tooltipProblem (Just IconProblem) True} |] -- to be used inside text blocks plannedFeat = [whamlet| ^{iconTooltip tooltipPlanned (Just IconPlanned) False} |] plannedFeatInline = [whamlet| ^{iconTooltip tooltipPlanned (Just IconPlanned) True} |] -- to be used inside text blocks - + -- new feature with given introduction date newFeat :: Integer -> Int -> Int -> WidgetFor UniWorX () newFeat year month day = do diff --git a/src/Handler/Material.hs b/src/Handler/Material.hs index 817ae41f9..c0679cd31 100644 --- a/src/Handler/Material.hs +++ b/src/Handler/Material.hs @@ -21,7 +21,7 @@ data MaterialForm = MaterialForm , mfType :: Maybe (CI Text) , mfDescription :: Maybe Html , mfVisibleFrom :: Maybe UTCTime - , mfFiles :: Maybe FileUploads + , mfFiles :: Maybe FileUploads } makeMaterialForm :: CourseId -> Maybe MaterialForm -> Form MaterialForm @@ -135,7 +135,7 @@ getMaterialListR tid ssh csh = do , ( "last-edit" , SortColumn (E.^. MaterialLastEdit) ) ] , dbtFilter = mconcat - [ singletonMap "may-access" . FilterProjected $ \(Any b) dbr + [ singletonMap "may-access" . FilterProjected $ \(Any b) dbr -> (== b) <$> hasReadAccessTo (matLink . materialName $ row2material dbr) :: DB Bool ] , dbtFilterUI = mempty @@ -347,4 +347,4 @@ getMArchiveR tid ssh csh mnm = do return materialFile serveSomeFiles archiveName getMatQuery - + diff --git a/src/Handler/Metrics.hs b/src/Handler/Metrics.hs index 92bed0bc1..0250e9851 100644 --- a/src/Handler/Metrics.hs +++ b/src/Handler/Metrics.hs @@ -28,7 +28,7 @@ getMetricsR = selectRep $ do guardM . lift . existsBy $ UniqueUserGroupMember UserGroupMetrics uid encodeBearer =<< bearerToken (HashSet.singleton . Left $ toJSON UserGroupMetrics) (Just $ HashSet.singleton MetricsR) Nothing (Just Nothing) Nothing - + defaultLayout $ do setTitleI MsgTitleMetrics $(widgetFile "metrics") diff --git a/src/Handler/News.hs b/src/Handler/News.hs index ee46deb25..04ee47d74 100644 --- a/src/Handler/News.hs +++ b/src/Handler/News.hs @@ -29,7 +29,7 @@ getNewsR = do when (is _Nothing muid) $ notificationWidget NotificationBroad Info $(i18nWidgetFile "pitch") - + case muid of Just uid -> do newsUpcomingExams uid @@ -51,7 +51,7 @@ newsSystemMessages = do mkHideForm smId SystemMessage{..} = liftHandler $ do cID <- encrypt smId hidden <- getSystemMessageState smId <&> \UserSystemMessageState{..} -> userSystemMessageHidden > Just systemMessageLastUnhide - + (btnView, btnEnctype) <- generateFormPost . buttonForm' $ bool [BtnSystemMessageHide] [BtnSystemMessageUnhide] hidden return $ wrapForm btnView def { formSubmit = FormNoSubmit @@ -65,7 +65,7 @@ newsSystemMessages = do tell $ Any hidden return $ guardOn (not hidden || showHidden) (smId, sm, trans, hidden) - + (messages', Any anyHidden) <- liftHandler . runDB . runConduit . C.runWriterLC $ transPipe lift (selectKeys [] []) .| C.filterM (hasReadAccessTo . MessageR <=< encrypt) @@ -87,7 +87,7 @@ newsUpcomingSheets :: UserId -> Widget newsUpcomingSheets uid = do cTime <- liftIO getCurrentTime let noActiveToCutoff = toMidnight . addGregorianDurationRollOver (scaleCalendarDiffDays (-1) calendarMonth) $ utctDay cTime - + let tableData :: E.LeftOuterJoin (E.InnerJoin (E.InnerJoin (E.SqlExpr (Entity CourseParticipant)) (E.SqlExpr (Entity Course))) (E.SqlExpr (Entity Sheet))) (E.InnerJoin (E.SqlExpr (Maybe (Entity Submission))) (E.SqlExpr (Maybe (Entity SubmissionUser)))) @@ -104,12 +104,12 @@ newsUpcomingSheets uid = do E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse E.on $ course E.^. CourseId E.==. participant E.^. CourseParticipantCourse - let showSheetNoActiveTo = + let showSheetNoActiveTo = E.maybe E.false (E.>=. E.val noActiveToCutoff) (sheet E.^. SheetActiveFrom) E.||. E.maybe E.false (E.>=. E.val noActiveToCutoff) (sheet E.^. SheetVisibleFrom) E.||. E.maybe E.false (E.>=. E.val noActiveToCutoff) (sheet E.^. SheetHintFrom) E.||. E.maybe E.false (E.>=. E.val noActiveToCutoff) (sheet E.^. SheetSolutionFrom) - + E.where_ $ participant E.^. CourseParticipantUser E.==. E.val uid E.&&. participant E.^. CourseParticipantState E.==. E.val CourseParticipantActive E.&&. E.maybe showSheetNoActiveTo (E.>=. E.val cTime) (sheet E.^. SheetActiveTo) diff --git a/src/Handler/Participants.hs b/src/Handler/Participants.hs index c9af17d51..1bd09384c 100644 --- a/src/Handler/Participants.hs +++ b/src/Handler/Participants.hs @@ -35,7 +35,7 @@ instance ToNamedRecord ParticipantEntry where instance DefaultOrdered ParticipantEntry where headerOrder _ = Csv.header ["course", "email"] - + getParticipantsListR :: Handler Html getParticipantsListR = do @@ -52,10 +52,10 @@ getParticipantsListR = do schoolTerms' <- flip filterM schoolTerms'' $ \(E.Value ssh, E.Value tid) -> hasReadAccessTo $ ParticipantsR tid ssh - + let schoolTerms :: Set (SchoolId, TermId) schoolTerms = setOf (folded . $(multifocusG 2) (_1 . _Value) (_2 . _Value)) schoolTerms' - + siteLayoutMsg MsgMenuParticipantsList $ do setTitleI MsgMenuParticipantsList diff --git a/src/Handler/Profile.hs b/src/Handler/Profile.hs index acec907f9..e93498ecb 100644 --- a/src/Handler/Profile.hs +++ b/src/Handler/Profile.hs @@ -227,7 +227,7 @@ notificationForm template = wFormToAForm $ do validateSettings :: User -> FormValidator SettingsForm Handler () validateSettings User{..} = do userDisplayName' <- use _stgDisplayName - + guardValidation MsgUserDisplayNameInvalid $ validDisplayName userTitle userFirstName userSurname userDisplayName' @@ -812,7 +812,7 @@ postSetDisplayEmailR = do siteLayoutMsg MsgTitleChangeUserDisplayEmail $ do setTitleI MsgTitleChangeUserDisplayEmail $(i18nWidgetFile "set-display-email") - + getCsvOptionsR, postCsvOptionsR :: Handler Html getCsvOptionsR = postCsvOptionsR postCsvOptionsR = do diff --git a/src/Handler/School.hs b/src/Handler/School.hs index 72de78d79..4c72381bf 100644 --- a/src/Handler/School.hs +++ b/src/Handler/School.hs @@ -8,14 +8,14 @@ import qualified Database.Esqueleto as E import qualified Data.Set as Set import qualified Data.CaseInsensitive as CI import qualified Data.Text as Text - + getSchoolListR :: Handler Html getSchoolListR = do let schoolLink :: SchoolId -> SomeRoute UniWorX schoolLink ssh = SomeRoute $ SchoolR ssh SchoolEditR - + dbtSQLQuery :: E.SqlExpr (Entity School) -> E.SqlQuery _ dbtSQLQuery = return @@ -49,7 +49,7 @@ getSchoolListR = do psValidator = def & defaultSorting [SortAscBy "school-name"] - + table <- runDB $ dbTableWidget' psValidator DBTable{..} @@ -89,7 +89,7 @@ getSchoolEditR, postSchoolEditR :: SchoolId -> Handler Html getSchoolEditR = postSchoolEditR postSchoolEditR ssh = do sForm <- runDB $ schoolToForm ssh - + ((sfResult, sfView), sfEnctype) <- runFormPost sForm formResult sfResult $ \SchoolForm{..} -> do diff --git a/src/Handler/Sheet.hs b/src/Handler/Sheet.hs index d174152f5..1d8270e8d 100644 --- a/src/Handler/Sheet.hs +++ b/src/Handler/Sheet.hs @@ -19,7 +19,7 @@ import Handler.Sheet.Download as Handler.Sheet import Handler.Sheet.New as Handler.Sheet import Handler.Sheet.Show as Handler.Sheet - + getSIsCorrR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html -- NOTE: The route SIsCorrR is only used to verfify corrector access rights to given sheet! getSIsCorrR _ _ _ shn = diff --git a/src/Handler/Sheet/Current.hs b/src/Handler/Sheet/Current.hs index 996199913..1646785f2 100644 --- a/src/Handler/Sheet/Current.hs +++ b/src/Handler/Sheet/Current.hs @@ -6,7 +6,7 @@ module Handler.Sheet.Current import Import import Utils.Sheet - + getSheetCurrentR :: TermId -> SchoolId -> CourseShorthand -> Handler Void getSheetCurrentR tid ssh csh = do diff --git a/src/Handler/Sheet/Download.hs b/src/Handler/Sheet/Download.hs index 0f5bfb70d..866718d3d 100644 --- a/src/Handler/Sheet/Download.hs +++ b/src/Handler/Sheet/Download.hs @@ -43,7 +43,7 @@ getSArchiveR tid ssh csh shn = do E.where_ $ sFile E.^. SheetFileSheet E.==. E.val shId E.&&. sFile E.^. SheetFileType E.==. E.val sft return . E.max_ $ sFile E.^. SheetFileModified - + serveZipArchive archiveName $ do forM_ sftDirectories $ \(sft, mTime) -> yield $ SheetFile { sheetFileType = sft diff --git a/src/Handler/Sheet/Edit.hs b/src/Handler/Sheet/Edit.hs index c7cde432e..addbde42a 100644 --- a/src/Handler/Sheet/Edit.hs +++ b/src/Handler/Sheet/Edit.hs @@ -112,11 +112,11 @@ handleSheetEdit tid ssh csh msId template dbAction = do deleteWhere [InvitationFor ==. invRef @SheetCorrector sid, InvitationEmail /<-. toListOf (folded . _1) invites] sinkInvitationsF correctorInvitationConfig invites - + return True when saveOkay $ redirect $ CSheetR tid ssh csh sfName SShowR -- redirect must happen outside of runDB - (FormFailure msgs) -> forM_ msgs $ (addMessage Error) . toHtml + (FormFailure msgs) -> forM_ msgs $ addMessage Error . toHtml _ -> runDB $ warnTermDays tid $ Map.fromList [ (date,name) | (Just date, name) <- [(sfVisibleFrom =<< template, MsgSheetVisibleFrom) ,(sfActiveFrom =<< template, MsgSheetActiveFrom) diff --git a/src/Handler/Sheet/Form.hs b/src/Handler/Sheet/Form.hs index 82a710a6f..0f60181c0 100644 --- a/src/Handler/Sheet/Form.hs +++ b/src/Handler/Sheet/Form.hs @@ -1,7 +1,7 @@ module Handler.Sheet.Form ( SheetForm(..), Loads , makeSheetForm - , getFtIdMap + , getFtIdMap ) where import Import @@ -44,7 +44,7 @@ data SheetForm = SheetForm -- Keine SheetId im Formular! } - + getFtIdMap :: Key Sheet -> DB (SheetFileType -> Set FileReference) getFtIdMap sId = do allSheetFiles <- E.select . E.from $ \sheetFile -> do @@ -88,16 +88,16 @@ makeSheetForm cId msId template = identifyForm FIDsheet . validateForm validateS <*> apopt checkBoxField (fslI MsgAutoAssignCorrs) (sfAutoDistribute <$> template) <*> aopt htmlField (fslI MsgSheetMarking) (sfMarkingText <$> template) <*> apopt checkBoxField (fslI MsgSheetAnonymousCorrection & setTooltip MsgSheetAnonymousCorrectionTip) (sfAnonymousCorrection <$> template) - <*> correctorForm (fromMaybe mempty $ sfCorrectors <$> template) + <*> correctorForm (maybe mempty sfCorrectors template) where validateSheet :: FormValidator SheetForm Handler () validateSheet = do SheetForm{..} <- State.get - guardValidation MsgSheetErrVisibility $ NTop sfVisibleFrom <= NTop sfActiveFrom - guardValidation MsgSheetErrDeadlineEarly $ NTop sfActiveFrom <= NTop sfActiveTo - guardValidation MsgSheetErrHintEarly $ NTop sfHintFrom >= NTop sfActiveFrom - guardValidation MsgSheetErrSolutionEarly $ NTop sfSolutionFrom >= NTop sfActiveTo + guardValidation MsgSheetErrVisibility $ NTop sfVisibleFrom <= NTop sfActiveFrom + guardValidation MsgSheetErrDeadlineEarly $ NTop sfActiveFrom <= NTop sfActiveTo + guardValidation MsgSheetErrHintEarly $ NTop sfHintFrom >= NTop sfActiveFrom + guardValidation MsgSheetErrSolutionEarly $ NTop sfSolutionFrom >= NTop sfActiveTo guardValidation MsgSheetErrVisibleWithoutActive $ is _Just sfActiveFrom || is _Nothing sfVisibleFrom @@ -113,7 +113,7 @@ correctorForm loads' = wFormToAForm $ do loads :: Map (Either UserEmail UserId) (CorrectorState, Load) loads = loads' <&> \(InvDBDataSheetCorrector load cState, InvTokenDataSheetCorrector) -> (cState, load) - countTutRes <- wpopt checkBoxField (fslI MsgCountTutProp & setTooltip MsgCountTutPropTip) . Just . any (\(_, Load{..}) -> fromMaybe False byTutorial) $ Map.elems loads + countTutRes <- wpopt checkBoxField (fslI MsgCountTutProp & setTooltip MsgCountTutPropTip) . Just . any (\(_, Load{..}) -> Just True == byTutorial) $ Map.elems loads let @@ -124,7 +124,7 @@ correctorForm loads' = wFormToAForm $ do E.on $ sheet E.^. SheetId E.==. sheetCorrector E.^. SheetCorrectorSheet E.on $ sheetCorrector E.^. SheetCorrectorUser E.==. user E.^. UserId E.where_ $ lecturer E.^. LecturerUser E.==. E.val userId - E.orderBy $ [E.asc $ user E.^. UserSurname, E.asc $ user E.^. UserDisplayName] + E.orderBy [E.asc $ user E.^. UserSurname, E.asc $ user E.^. UserDisplayName] return user miAdd :: ListPosition @@ -150,7 +150,7 @@ correctorForm loads' = wFormToAForm $ do miCell _ userIdent initRes nudge csrf = do (stateRes, stateView) <- mreq (selectField optionsFinite) (fslI MsgSheetCorrectorState & addName (nudge "state")) $ (fst <$> initRes) <|> Just CorrectorNormal (byTutRes, byTutView) <- mreq checkBoxField ("" & addName (nudge "bytut")) $ (isJust . byTutorial . snd <$> initRes) <|> Just False - (propRes, propView) <- mreq (checkBool (>= 0) MsgProportionNegative $ rationalField) (fslI MsgSheetCorrectorProportion & addName (nudge "prop")) $ (byProportion . snd <$> initRes) <|> Just 0 + (propRes, propView) <- mreq (checkBool (>= 0) MsgProportionNegative rationalField) (fslI MsgSheetCorrectorProportion & addName (nudge "prop")) $ (byProportion . snd <$> initRes) <|> Just 0 let res :: FormResult (CorrectorState, Load) res = (,) <$> stateRes <*> (Load <$> tutRes' <*> propRes) @@ -202,7 +202,7 @@ correctorForm loads' = wFormToAForm $ do postProcess :: Map ListPosition (Either UserEmail UserId, (CorrectorState, Load)) -> Loads postProcess = Map.fromList . map postProcess' . Map.elems - where + where postProcess' :: (Either UserEmail UserId, (CorrectorState, Load)) -> (Either UserEmail UserId, (InvitationDBData SheetCorrector, InvitationTokenData SheetCorrector)) postProcess' = over _2 $ \(cState, load) -> (InvDBDataSheetCorrector load cState, InvTokenDataSheetCorrector) diff --git a/src/Handler/Sheet/List.hs b/src/Handler/Sheet/List.hs index 7421017df..e616e81ab 100644 --- a/src/Handler/Sheet/List.hs +++ b/src/Handler/Sheet/List.hs @@ -76,7 +76,7 @@ getSheetListR tid ssh csh = do return $ CSubmissionR tid ssh csh sheetName cid' SubShowR in anchorCellM mkRoute (mkCid >>= \cid2 -> [whamlet|#{cid2}|]) , sortable (Just "rating") (i18nCell MsgRating) - $ \DBRow{dbrOutput=(Entity _ Sheet{..}, _, mbSub,_)} -> + $ \DBRow{dbrOutput=(Entity _ Sheet{..}, _, mbSub,_)} -> let stats = sheetTypeSum sheetType in -- for statistics over all shown rows case mbSub of Nothing -> cellTell mempty $ stats Nothing diff --git a/src/Handler/StorageKey.hs b/src/Handler/StorageKey.hs index 2bb5cf233..fc9de6e62 100644 --- a/src/Handler/StorageKey.hs +++ b/src/Handler/StorageKey.hs @@ -11,6 +11,8 @@ import qualified Data.ByteString.Base64 as Base64 (encode, decodeLenient) import qualified Data.Binary as Binary (encode) import qualified Crypto.KDF.HKDF as HKDF +{-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-} + data StorageKeyType = SKTExamCorrect @@ -64,7 +66,7 @@ postStorageKeyR = do timestamp = if | Just ts <- skReqTimestamp, timestampInBounds -> ts | otherwise -> now - + salt <- let sltSize = hashDigestSize SHA3_256 in if | Just slt <- Base64.decodeLenient . encodeUtf8 <$> skReqSalt , timestampInBounds diff --git a/src/Handler/Submission.hs b/src/Handler/Submission.hs index f81ecef61..aae806f26 100644 --- a/src/Handler/Submission.hs +++ b/src/Handler/Submission.hs @@ -32,7 +32,7 @@ import Handler.Utils import qualified Database.Esqueleto as E - + getSubmissionOwnR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html getSubmissionOwnR tid ssh csh shn = do authId <- requireAuthId diff --git a/src/Handler/Submission/Assign.hs b/src/Handler/Submission/Assign.hs index 53aec90d0..929df786e 100644 --- a/src/Handler/Submission/Assign.hs +++ b/src/Handler/Submission/Assign.hs @@ -3,7 +3,7 @@ module Handler.Submission.Assign , getCAssignR, postCAssignR , getSAssignR, postSAssignR ) where - + import Import hiding (link, unzip) import Handler.Utils hiding (colSchool) @@ -74,7 +74,7 @@ postSAssignR tid ssh csh shn = do assignHandler :: TermId -> SchoolId -> CourseShorthand -> CourseId -> [SheetId] -> Handler Html assignHandler tid ssh csh cid assignSids = do currentRoute <- fromMaybe (error "assignHandler called from 404-handler") <$> liftHandler getCurrentRoute - + -- gather data (orderedSheetNames, assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment, ((btnViews, btnCsrf), btnEncoding)) <- runDB $ do -- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh @@ -97,7 +97,7 @@ assignHandler tid ssh csh cid assignSids = do assignSheetNames' = sheetName <$> mapMaybe (`Map.lookup` sheets) assignSids' assignButtons = Map.fromSet (maybe BtnSubmissionsAssignAll BtnSubmissionsAssign) $ Set.fromList . bool (Nothing :) id (null sheetList) $ map Just assignSheetNames' - + ((btnResult, btnViews'), btnEncoding) <- runFormPost . identifyForm FIDAssignSubmissions $ \csrf -> fmap (over _1 (asum . fmap (hoistMaybe =<<)) . over _2 (, csrf) . unzip) . for assignButtons $ \btn -> mopt (buttonField btn) "" Nothing @@ -132,7 +132,7 @@ assignHandler tid ssh csh cid assignSids = do | otherwise -> do addMessageI Error $ MsgSheetsUnassignable $ CI.original shn return Nothing - if | null sub_ok && null sub_fail -> + if | null sub_ok && null sub_fail -> return $ Map.insert shn (status, countMapElems plan, deficit) acc | otherwise -> do (plan', deficit') <- lift $ handle ignoreExceptions $ planSubmissions sid Nothing @@ -280,7 +280,7 @@ assignHandler tid ssh csh cid assignSids = do doWrap $(widgetFile "corrections-overview") - + data ButtonSubmissionsAssign = BtnSubmissionsAssign SheetName | BtnSubmissionsAssignAll diff --git a/src/Handler/Submission/Correction.hs b/src/Handler/Submission/Correction.hs index 1130e9a0e..0de27b056 100644 --- a/src/Handler/Submission/Correction.hs +++ b/src/Handler/Submission/Correction.hs @@ -51,7 +51,7 @@ postCorrectionR tid ssh csh shn cid = do MsgRenderer mr <- getMsgRenderer case results of [(Entity cId Course{..}, Entity shId Sheet{..}, Entity _ subm@Submission{..}, corrector, E.Value filesCorrected)] -> do - let ratingComment = fmap Text.strip submissionRatingComment >>= (\c -> c <$ guard (not $ null c)) + let ratingComment = submissionRatingComment >>= (\c -> c <$ guard (not $ null c)) . Text.strip pointsForm = case sheetType of NotGraded -> pure Nothing @@ -67,7 +67,7 @@ postCorrectionR tid ssh csh shn cid = do | not isLecturer = wFormToAForm $ pure . Just <$> requireAuthId | otherwise = wFormToAForm $ do let correctors = E.from $ \user -> do - let isCorrector = E.exists . E.from $ \sheetCorrector -> + let isCorrector = E.exists . E.from $ \sheetCorrector -> E.where_ $ sheetCorrector E.^. SheetCorrectorUser E.==. user E.^. UserId E.&&. sheetCorrector E.^. SheetCorrectorSheet E.==. E.val shId isLecturer' = E.exists . E.from $ \lecturer -> @@ -151,7 +151,7 @@ postCorrectionR tid ssh csh shn cid = do getCorrectionUserR tid ssh csh shn cid = do - + sub <- decrypt cid results <- runDB $ correctionData tid ssh csh shn sub diff --git a/src/Handler/Submission/Helper.hs b/src/Handler/Submission/Helper.hs index 286481651..59cca93b8 100644 --- a/src/Handler/Submission/Helper.hs +++ b/src/Handler/Submission/Helper.hs @@ -104,9 +104,9 @@ makeSubmissionForm cid msmid uploadMode grouping isLecturer prefillUsers = ident submittorsForm' = maybeT submittorsForm $ do restr <- MaybeT (maybeCurrentBearerRestrictions @Value) >>= hoistMaybe . preview (_Object . ix "submittors" . _Array) let _Submittor = prism (either toJSON toJSON) $ \x -> first (const x) $ JSON.parseEither (\x' -> fmap Right (parseJSON x') <|> fmap Left (parseJSON x')) x - submittors <- fmap (pure @FormResult @([Either UserEmail CryptoUUIDUser])) . forM (toList restr) $ hoistMaybe . preview _Submittor + submittors <- fmap (pure @FormResult @[Either UserEmail CryptoUUIDUser]) . forM (toList restr) $ hoistMaybe . preview _Submittor fmap Set.fromList <$> forMOf (traverse . traverse . _Right) submittors decrypt - + submittorsForm | isLecturer = do -- Form is being used by lecturer; allow Everything™ @@ -165,7 +165,7 @@ makeSubmissionForm cid msmid uploadMode grouping isLecturer prefillUsers = ident guard $ Map.size dat > 1 -- User may drop from submission only if it already exists; no directly creating submissions for other people - guard $ maybe True (/= Right uid) (dat !? delPos) || isJust msmid + guard $ Just (Right uid) /= dat !? delPos || isJust msmid miDeleteList dat delPos @@ -304,7 +304,7 @@ submissionHelper tid ssh csh shn mcid = do return (userName, submissionEdit E.^. SubmissionEditTime) forM raw $ \(E.Value name, E.Value time) -> (name, ) <$> formatTime SelFormatDateTime time - corrector <- fmap join $ traverse getEntity submissionRatingBy + corrector <- join <$> traverse getEntity submissionRatingBy return (csheet,buddies,lastEdits,maySubmit,isLecturer,isOwner,Just sub,corrector) @@ -336,9 +336,9 @@ submissionHelper tid ssh csh shn mcid = do when ( is _Nothing muid && is _Nothing msubmission && not isLecturer - ) + ) notAuthenticated - + -- Determine old submission users subUsersOld <- if | Just smid <- msmid -> Set.union @@ -411,7 +411,7 @@ submissionHelper tid ssh csh shn mcid = do } audit $ TransactionSubmissionEdit sid shid return sid - + -- Determine new submission users subUsers <- if | isLecturer -> return adhocMembers @@ -461,7 +461,7 @@ submissionHelper tid ssh csh shn mcid = do audit $ TransactionSubmissionUserDelete smid subUid unless (Just subUid == muid) $ queueDBJob . JobQueueNotification $ NotificationSubmissionUserDeleted subUid shid smid - + addMessageI Success $ if | Nothing <- msmid -> MsgSubmissionCreated | otherwise -> MsgSubmissionUpdated return smid @@ -558,7 +558,7 @@ submissionHelper tid ssh csh shn mcid = do courseSchool = ssh courseShorthand = csh in $(widgetFile "correction-user") - + defaultLayout $ do setTitleI $ MsgSubmissionEditHead tid ssh csh shn diff --git a/src/Handler/Submission/List.hs b/src/Handler/Submission/List.hs index 12544e87d..27dff4edb 100644 --- a/src/Handler/Submission/List.hs +++ b/src/Handler/Submission/List.hs @@ -193,7 +193,7 @@ colPointsField :: Colonnade Sortable CorrectionTableData (DBCell _ (FormResult ( colPointsField = sortable (Just "rating") (i18nCell MsgColumnRatingPoints) $ formCell id (\DBRow{ dbrOutput=(Entity subId _, _, _, _, _, _, _, _) } -> return subId) (\DBRow{ dbrOutput=(Entity _ Submission{..}, Entity _ Sheet{..}, _, _, _, _, _, _) } mkUnique -> case sheetType of - NotGraded -> over (_1.mapped) (_2 .~) <$> pure (FormSuccess Nothing, mempty) + NotGraded -> pure $ over (_1.mapped) (_2 .~) (FormSuccess Nothing, mempty) _other -> over (_1.mapped) (_2 .~) . over _2 fvWidget <$> mopt (pointsFieldMax $ preview (_grading . _maxPoints) sheetType) (fsUniq mkUnique "points") (Just submissionRatingPoints) ) @@ -201,7 +201,7 @@ colMaxPointsField :: _ => Colonnade Sortable CorrectionTableData (DBCell m (Form colMaxPointsField = sortable (Just "sheet-type") (i18nCell MsgSheetType) $ i18nCell . (\DBRow{ dbrOutput=(_, Entity _ Sheet{sheetType}, _, _, _, _, _, _) } -> sheetType) colCommentField :: Colonnade Sortable CorrectionTableData (DBCell _ (FormResult (DBFormResult SubmissionId (a, b, Maybe Text) CorrectionTableData))) -colCommentField = sortable (Just "comment") (i18nCell MsgRatingComment) $ fmap (cellAttrs <>~ [("style","width:60%")]) $ formCell id +colCommentField = sortable (Just "comment") (i18nCell MsgRatingComment) $ (cellAttrs <>~ [("style","width:60%")]) <$> formCell id (\DBRow{ dbrOutput=(Entity subId _, _, _, _, _, _, _, _) } -> return subId) (\DBRow{ dbrOutput=(Entity _ Submission{..}, _, _, _, _, _, _, _) } mkUnique -> over (_1.mapped) ((_3 .~) . assertM (not . null) . fmap (Text.strip . unTextarea)) . over _2 fvWidget <$> mopt textareaField (fsUniq mkUnique "comment") (Just $ Textarea <$> submissionRatingComment)) @@ -398,11 +398,11 @@ makeCorrectionsTable whereClause dbtColonnade dbtFilterUI psValidator dbtParams , FilterProjected $ \(DBRow{..} :: CorrectionTableData) (criteria :: Set Text) -> let cid = map CI.mk . unpack . toPathPiece $ dbrOutput ^. _7 criteria' = map CI.mk . unpack <$> Set.toList criteria - in any (\c -> c `isInfixOf` cid) criteria' + in any (`isInfixOf` cid) criteria' ) ] , dbtFilterUI = fromMaybe mempty dbtFilterUI - , dbtStyle = def { dbsFilterLayout = maybe (\_ _ _ -> id) (\_ -> defaultDBSFilterLayout) dbtFilterUI } + , dbtStyle = def { dbsFilterLayout = maybe (\_ _ _ -> id) (const defaultDBSFilterLayout) dbtFilterUI } , dbtParams , dbtIdent = "corrections" :: Text , dbtCsvEncode = noCsvEncode @@ -465,8 +465,8 @@ correctionsR' whereClause displayColumns dbtFilterUI psValidator actions = do -- let statistics = gradeSummaryWidget MsgSubmissionGradingSummaryTitle gradingSummary -- return (tableRes, statistics) - let actionRes = actionRes' & mapped._2 %~ Map.keysSet . Map.filter id . getDBFormResult (const False) - & mapped._1 %~ fromMaybe (error "By consctruction the form should always return an action") . getLast + let actionRes = actionRes' <&> _2 %~ Map.keysSet . Map.filter id . getDBFormResult (const False) + <&> _1 %~ fromMaybe (error "By consctruction the form should always return an action") . getLast auditAllSubEdit = mapM_ $ \sId -> getJust sId >>= \sub -> audit $ TransactionSubmissionEdit sId $ sub ^. _submissionSheet formResult actionRes $ \case @@ -610,7 +610,7 @@ assignAction selId = ( CorrSetCorrector E.where_ $ either (\cId -> course E.^. CourseId E.==. E.val cId) (\shId -> sheet E.^. SheetId E.==. E.val shId) selId - E.orderBy $ [E.asc $ user E.^. UserSurname, E.asc $ user E.^. UserDisplayName] + E.orderBy [E.asc $ user E.^. UserSurname, E.asc $ user E.^. UserDisplayName] E.distinct $ return user diff --git a/src/Handler/Submission/SubmissionUserInvite.hs b/src/Handler/Submission/SubmissionUserInvite.hs index 1b8491d57..1fd36903e 100644 --- a/src/Handler/Submission/SubmissionUserInvite.hs +++ b/src/Handler/Submission/SubmissionUserInvite.hs @@ -15,7 +15,7 @@ import Text.Hamlet (ihamlet) import qualified Data.HashSet as HashSet - + instance IsInvitableJunction SubmissionUser where type InvitationFor SubmissionUser = Submission data InvitableJunction SubmissionUser = JunctionSubmissionUser diff --git a/src/Handler/Submission/Upload.hs b/src/Handler/Submission/Upload.hs index 026677686..9e66ef7b4 100644 --- a/src/Handler/Submission/Upload.hs +++ b/src/Handler/Submission/Upload.hs @@ -31,7 +31,7 @@ explainSubmissionDoneMode SubmissionDoneNever = return $(i18nWidgetFile "submis 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 diff --git a/src/Handler/SystemMessage.hs b/src/Handler/SystemMessage.hs index 1eb650483..79ee42ae6 100644 --- a/src/Handler/SystemMessage.hs +++ b/src/Handler/SystemMessage.hs @@ -57,9 +57,8 @@ postMessageR cID = do runFormPost . identifyForm (FIDSystemMessageModifyTranslation $ ciphertext cID') . renderAForm FormStandard $ (,) <$> fmap (Entity tId) - ( SystemMessageTranslation - <$> pure systemMessageTranslationMessage - <*> areq (langField False) (fslpI MsgSystemMessageLanguage (mr MsgRFC1766)) (Just systemMessageTranslationLanguage) + ( SystemMessageTranslation systemMessageTranslationMessage + <$> areq (langField False) (fslpI MsgSystemMessageLanguage (mr MsgRFC1766)) (Just systemMessageTranslationLanguage) <*> areq htmlField (fslI MsgSystemMessageContent) (Just systemMessageTranslationContent) <*> aopt htmlField (fslI MsgSystemMessageSummary) (Just systemMessageTranslationSummary) ) @@ -71,9 +70,8 @@ postMessageR cID = do & filter (\l -> none (`langMatches` l) $ Map.keys ts') ((addTransRes, addTransView), addTransEnctype) <- runFormPost . identifyForm FIDSystemMessageAddTranslation . renderAForm FormStandard - $ SystemMessageTranslation - <$> pure smId - <*> areq (langField False) (fslpI MsgSystemMessageLanguage (mr MsgRFC1766)) (listToMaybe nextLang) + $ SystemMessageTranslation smId + <$> areq (langField False) (fslpI MsgSystemMessageLanguage (mr MsgRFC1766)) (listToMaybe nextLang) <*> areq htmlField (fslI MsgSystemMessageContent) Nothing <*> aopt htmlField (fslI MsgSystemMessageSummary) Nothing diff --git a/src/Handler/Term.hs b/src/Handler/Term.hs index 94ae7ee53..329dcf839 100644 --- a/src/Handler/Term.hs +++ b/src/Handler/Term.hs @@ -40,13 +40,13 @@ guessDay tid@TermIdentifier{ year, season = Winter } TermDayLectureStart guessDay tid@TermIdentifier{ year, season = Winter } TermDayLectureEnd = fromWeekDate (succ year) ((wWeekStart + 21) `div` bool 53 54 longYear) 5 where longYear = is _Just $ fromWeekDateValid year 53 1 - (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart + (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart guessDay tid@TermIdentifier{ year, season = Summer } TermDayLectureStart = fromWeekDate year (wWeekStart + 2) 1 - where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart + where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart guessDay tid@TermIdentifier{ year, season = Summer } TermDayLectureEnd = fromWeekDate year (wWeekStart + 17) 5 - where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart + where (_, wWeekStart, _) = toWeekDate $ guessDay tid TermDayStart validateTerm :: (MonadHandler m, HandlerSite m ~ UniWorX) diff --git a/src/Handler/Tutorial/Edit.hs b/src/Handler/Tutorial/Edit.hs index be1b1d36d..d15dc1c76 100644 --- a/src/Handler/Tutorial/Edit.hs +++ b/src/Handler/Tutorial/Edit.hs @@ -68,7 +68,7 @@ postTEditR tid ssh csh tutn = do } when (is _Nothing insertRes) $ do audit $ TransactionTutorialEdit tutid - + let (invites, adds) = partitionEithers $ Set.toList tfTutors deleteWhere [ TutorTutorial ==. tutid ] diff --git a/src/Handler/Tutorial/Form.hs b/src/Handler/Tutorial/Form.hs index bba53a709..4b7aed8a2 100644 --- a/src/Handler/Tutorial/Form.hs +++ b/src/Handler/Tutorial/Form.hs @@ -43,7 +43,7 @@ tutorialForm cid template html = do (addRes, addView) <- mpreq (multiUserInvitationField . MUILookupAnyUser . Just $ tutUserSuggestions uid) (fslI MsgTutorEmail & addName (nudge "email") & addPlaceholder (mr MsgLdapIdentificationOrEmail)) Nothing let addRes' - | otherwise + = addRes <&> \newDat oldDat -> if | existing <- newDat `Set.intersection` Set.fromList oldDat , not $ Set.null existing diff --git a/src/Handler/Tutorial/New.hs b/src/Handler/Tutorial/New.hs index 0e6e65cfc..da9ca7f16 100644 --- a/src/Handler/Tutorial/New.hs +++ b/src/Handler/Tutorial/New.hs @@ -39,7 +39,7 @@ postCTutorialNewR tid ssh csh = do } whenIsJust insertRes $ \tutid -> do audit $ TransactionTutorialEdit tutid - + let (invites, adds) = partitionEithers $ Set.toList tfTutors insertMany_ $ map (Tutor tutid) adds sinkInvitationsF tutorInvitationConfig $ map (, tutid, (InvDBDataTutor, InvTokenDataTutor)) invites diff --git a/src/Handler/Users.hs b/src/Handler/Users.hs index 15de58bf3..88d0340fd 100644 --- a/src/Handler/Users.hs +++ b/src/Handler/Users.hs @@ -57,7 +57,7 @@ instance Finite UserAction nullaryPathPiece ''UserAction $ camelToPathPiece' 1 embedRenderMessage ''UniWorX ''UserAction id - + data AllUsersAction = AllUsersLdapSync deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable) @@ -74,7 +74,7 @@ getUsersR = postUsersR postUsersR = do MsgRenderer mr <- getMsgRenderer let - dbtColonnade = mconcat $ + dbtColonnade = mconcat [ dbSelect (applying _2) id (return . view (_dbrOutput . _entityKey)) , sortable (Just "name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM (AdminUserR <$> encrypt uid) @@ -136,7 +136,7 @@ postUsersR = do (First (Just act), usrMap) <- inp let usrSet = Map.keysSet . Map.filter id $ getDBFormResult (const False) usrMap return (act, usrSet) - + over _1 postprocess <$> dbTable psValidator DBTable { dbtSQLQuery = return :: E.SqlExpr (Entity User) -> E.SqlQuery (E.SqlExpr (Entity User)) , dbtRowKey = (E.^. UserId) @@ -233,7 +233,7 @@ postUsersR = do formResult allUsersRes $ \case AllUsersLdapSync -> do runDBJobs . runConduit $ selectSource [] [] .| C.mapM_ (queueDBJob . JobSynchroniseLdapUser . entityKey) - addMessageI Success $ MsgSynchroniseLdapAllUsersQueued + addMessageI Success MsgSynchroniseLdapAllUsersQueued redirect UsersR let allUsersWgt' = wrapForm allUsersWgt def { formSubmit = FormNoSubmit @@ -329,10 +329,10 @@ postAdminUserR uuid = do | otherwise -> addMessageI Info MsgAccessRightsNotChanged redirect $ AdminUserR uuid - + userAuthenticationAction = \case BtnAuthLDAP -> do - let + let campusHandler :: MonadPlus m => Auth.CampusUserException -> m a campusHandler _ = mzero campusResult <- runMaybeT . handle campusHandler $ do @@ -347,7 +347,7 @@ postAdminUserR uuid = do runDBJobs $ do update uid [ UserAuthentication =. AuthLDAP ] queueDBJob . JobQueueNotification $ NotificationUserAuthModeUpdate uid userAuthentication - + addMessageI Success MsgAuthLDAPConfigured redirect $ AdminUserR uuid BtnAuthPWHash -> do @@ -569,7 +569,7 @@ functionInvitationConfig = InvitationConfig{..} itStartsAt = Nothing return InvitationTokenConfig{..} invitationRestriction _ _ = return Authorized - invitationForm _ (_, InvTokenDataUserFunction{..}) _ = pure $ (JunctionUserFunction invTokenUserFunctionFunction, ()) + invitationForm _ (_, InvTokenDataUserFunction{..}) _ = pure (JunctionUserFunction invTokenUserFunctionFunction, ()) invitationInsertHook _ _ _ _ _ = id invitationSuccessMsg (Entity _ School{..}) (Entity _ UserFunction{..}) = do MsgRenderer mr <- getMsgRenderer @@ -583,8 +583,8 @@ functionInvitationConfig = InvitationConfig{..} return . SomeRoute $ case currentTerm of [E.Value tid] -> TermSchoolCourseListR tid ssh _other -> CourseListR - - + + getAdminNewFunctionaryInviteR, postAdminNewFunctionaryInviteR :: Handler Html getAdminNewFunctionaryInviteR = postAdminNewFunctionaryInviteR postAdminNewFunctionaryInviteR = do @@ -593,7 +593,7 @@ postAdminNewFunctionaryInviteR = do E.where_ $ userAdmin E.^. UserFunctionUser E.==. E.val uid E.&&. userAdmin E.^. UserFunctionFunction E.==. E.val SchoolAdmin return $ userAdmin E.^. UserFunctionSchool - + ((invitesResult, invitesWgt), invitesEncoding) <- runFormPost . renderWForm FormStandard $ do now <- liftIO getCurrentTime let @@ -619,9 +619,9 @@ postAdminNewFunctionaryInviteR = do sinkInvitationsF functionInvitationConfig [ (mail, schoolId, (InvDBDataUserFunction deadline, InvTokenDataUserFunction (unSchoolKey schoolId) function)) | mail <- emails ] - unless (null emails) $ + unless (null emails) $ tell . pure <=< messageI Success . MsgFunctionariesInvited $ length emails - unless (null uids) $ + unless (null uids) $ tell . pure <=< messageI Success . MsgFunctionariesAdded $ length uids siteLayoutMsg MsgFunctionaryInviteHeading $ do diff --git a/src/Handler/Users/Add.hs b/src/Handler/Users/Add.hs index 07858b9f1..bcdd889ce 100644 --- a/src/Handler/Users/Add.hs +++ b/src/Handler/Users/Add.hs @@ -100,7 +100,7 @@ postAdminUserAddR = do when (aufAuth == AuthKindPWHash) $ lift . queueDBJob $ JobSendPasswordReset uid return uid - + case didInsert of Just uid -> do addMessageI Success MsgUserAdded diff --git a/src/Handler/Utils.hs b/src/Handler/Utils.hs index de308ce3d..b8a9f9375 100644 --- a/src/Handler/Utils.hs +++ b/src/Handler/Utils.hs @@ -27,7 +27,7 @@ import Handler.Utils.Database as Handler.Utils import Handler.Utils.Occurrences as Handler.Utils import Handler.Utils.Memcached as Handler.Utils import Handler.Utils.Files as Handler.Utils - + import Handler.Utils.Term as Handler.Utils import Control.Monad.Logger @@ -58,7 +58,7 @@ serveOneFile source = do serveSomeFiles :: forall file. HasFileReference file => FilePath -> ConduitT () file (YesodDB UniWorX) () -> Handler TypedContent serveSomeFiles archiveName source = serveSomeFiles' archiveName $ source .| C.map Left -serveSomeFiles' :: forall file. HasFileReference file => FilePath -> ConduitT () (Either file File) (YesodDB UniWorX) () -> Handler TypedContent +serveSomeFiles' :: forall file. HasFileReference file => FilePath -> ConduitT () (Either file File) (YesodDB UniWorX) () -> Handler TypedContent serveSomeFiles' archiveName source = do results <- runDB . runConduit $ source .| peekN 2 diff --git a/src/Handler/Utils/Allocation.hs b/src/Handler/Utils/Allocation.hs index 27e3c3d81..be5ef5a57 100644 --- a/src/Handler/Utils/Allocation.hs +++ b/src/Handler/Utils/Allocation.hs @@ -19,7 +19,7 @@ import qualified Database.Esqueleto.Utils as E import Control.Monad.Trans.State (execStateT) import qualified Control.Monad.State.Class as State (get, modify') -import Data.List (genericLength, elemIndex) +import Data.List (genericLength) import qualified Data.Vector as Vector import Data.Vector.Lens (vector) import qualified Data.Set as Set @@ -36,7 +36,7 @@ import qualified Data.Conduit.List as C import Data.Generics.Product.Param import qualified Crypto.Hash as Crypto - + import Language.Haskell.TH (nameBase) @@ -50,7 +50,7 @@ data MatchingExcludedReason nullaryPathPiece ''MatchingExcludedReason $ camelToPathPiece' 2 pathPieceJSON ''MatchingExcludedReason - + data MatchingLogRun = MatchingLogRun { matchingLogRunCourseRestriction :: Maybe (Set CourseId) , matchingLogRunCoursesExcluded :: Set CourseId @@ -73,7 +73,7 @@ allocationStarted allocId = fmap (E.unValue <=< listToMaybe) . E.select . E.from ordinalPriorities :: Monad m => ConduitT UserMatriculation (Map UserMatriculation AllocationPriority) m () ordinalPriorities = evalStateC 0 . C.mapM $ \matr -> singletonMap matr <$> (AllocationPriorityOrdinal <$> State.get <* State.modify' succ) - + sinkAllocationPriorities :: AllocationId -> ConduitT (Map UserMatriculation AllocationPriority) Void DB Int64 sinkAllocationPriorities allocId = fmap getSum . C.foldMapM . ifoldMapM $ \matr prio -> @@ -84,12 +84,12 @@ sinkAllocationPriorities allocId = fmap getSum . C.foldMapM . ifoldMapM $ \matr E.where_ $ user E.^. UserId E.==. allocationUser E.^. AllocationUserUser E.&&. user E.^. UserMatrikelnummer E.==. E.val (Just matr) - + computeAllocation :: Entity Allocation -> Maybe (Set CourseId) -- ^ Optionally restrict allocation to only consider the given courses -> DB ( AllocationFingerprint , Set (UserId, CourseId) - , Seq MatchingLogRun + , Seq MatchingLogRun ) computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = do allocations <- selectList [ CourseParticipantAllocated ==. Just allocId, CourseParticipantState ==. CourseParticipantActive ] [] @@ -106,7 +106,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d let deregistrations' = deregistrations & map ((, Sum 1) . E.unValue) & Map.fromListWith (<>) - + users' <- selectList [ AllocationUserAllocation ==. allocId ] [] let users'' = users' & mapMaybe ( runMaybeT $ do @@ -149,7 +149,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d let tellExcluded :: MatchingExcludedReason -> StateT _ _ () tellExcluded reason = State.modify' $ Map.insertWith (<>) (courseApplicationUser, courseApplicationCourse) (opoint reason :: NonNull (Set MatchingExcludedReason)) - + when (courseApplicationRatingVeto || maybe False not (courseApplicationRatingPoints ^? _Just . passingGrade . _Wrapped)) $ tellExcluded MatchingExcludedVeto @@ -184,7 +184,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d _other -> mempty gradeOrdinalPlaces :: Natural gradeOrdinalPlaces = round . abs $ ordinalUsers * gradeOrdinalProportion - + let centralNudge user cloneIndex grade = case allocationPrio user of AllocationPriorityNumeric{..} -> let allocationPriorities' = under vector (sortOn Down) allocationPriorities @@ -193,7 +193,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d in AllocationPriorityComparisonNumeric . withNumericGrade . fromInteger . fromMaybe minPrio $ allocationPriorities Vector.!? fromIntegral cloneIndex AllocationPriorityOrdinal{..} | gradeOrdinalPlaces > 0 - -> let allocationOrdinal' = gradeScale / fromIntegral gradeOrdinalPlaces * fromIntegral allocationOrdinal + -> let allocationOrdinal' = gradeScale / fromIntegral gradeOrdinalPlaces * fromIntegral allocationOrdinal in AllocationPriorityComparisonOrdinal (Down cloneIndex) $ withNumericGrade allocationOrdinal' AllocationPriorityOrdinal{..} -> AllocationPriorityComparisonOrdinal (Down cloneIndex) $ fromIntegral allocationOrdinal @@ -201,7 +201,7 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d withNumericGrade :: Rational -> Rational withNumericGrade | Just grade' <- grade - = let numberGrade' = fromMaybe (error "non-passing grade") (fromIntegral <$> elemIndex grade' passingGrades) / pred (genericLength passingGrades) + = let numberGrade' = maybe (error "non-passing grade") fromIntegral (elemIndex grade' passingGrades) / pred (genericLength passingGrades) passingGrades = sort $ filter (view $ passingGrade . _Wrapped) universeF numericGrade = -gradeScale + numberGrade' * 2 * gradeScale in (+) numericGrade @@ -210,10 +210,10 @@ computeAllocation (Entity allocId Allocation{allocationMatchingSeed}) cRestr = d let inputs = Binary.encode (users'', capacities, preferences, gradeScale, gradeOrdinalPlaces) - + fingerprint :: AllocationFingerprint fingerprint = Crypto.hashlazy inputs - + g = onCryptoFailure (\_ -> error "Could not create DRG") id . fmap drgNewSeed . seedFromBinary $ kmaclazy @(SHAKE256 320) (encodeUtf8 . (pack :: String -> Text) $ nameBase 'computeAllocation) allocationMatchingSeed inputs let @@ -244,7 +244,7 @@ doAllocation :: AllocationId -> DB () doAllocation allocId now regs = forM_ regs $ \(uid, cid) -> do - mField <- (courseApplicationField . entityVal =<<) . listToMaybe <$> selectList [CourseApplicationCourse ==. cid, CourseApplicationUser ==. uid, CourseApplicationAllocation ==. Just allocId] [] + mField <- (courseApplicationField . entityVal <=< listToMaybe) <$> selectList [CourseApplicationCourse ==. cid, CourseApplicationUser ==. uid, CourseApplicationAllocation ==. Just allocId] [] void $ upsert (CourseParticipant cid uid now mField (Just allocId) CourseParticipantActive) [ CourseParticipantRegistration =. now diff --git a/src/Handler/Utils/Communication.hs b/src/Handler/Utils/Communication.hs index 0743d8902..153ba69ea 100644 --- a/src/Handler/Utils/Communication.hs +++ b/src/Handler/Utils/Communication.hs @@ -3,7 +3,7 @@ module Handler.Utils.Communication , CommunicationRoute(..) , Communication(..) , commR - , crJobsCourseCommunication, crTestJobsCourseCommunication + , crJobsCourseCommunication, crTestJobsCourseCommunication -- * Re-Exports , Job(..) ) where diff --git a/src/Handler/Utils/Course.hs b/src/Handler/Utils/Course.hs index a595c37ca..c3f39056e 100644 --- a/src/Handler/Utils/Course.hs +++ b/src/Handler/Utils/Course.hs @@ -6,7 +6,7 @@ import Handler.Utils.Delete import qualified Database.Esqueleto as E import qualified Data.Set as Set - + courseDeleteRoute :: Set CourseId -> DeleteRoute Course courseDeleteRoute drRecords = DeleteRoute @@ -20,7 +20,7 @@ courseDeleteRoute drRecords = DeleteRoute return [whamlet| #{cName} (_{ShortTermIdentifier (unTermKey tid')}, #{sName}) |] - , drRecordConfirmString = \(E.Value cName, E.Value ssh', _, E.Value tid') -> + , drRecordConfirmString = \(E.Value cName, E.Value ssh', _, E.Value tid') -> return [st|#{termToText (unTermKey tid')}/#{ssh'}/#{cName}|] , drCaption = SomeMessage MsgCourseDeleteQuestion , drSuccessMessage = SomeMessage MsgCourseDeleted diff --git a/src/Handler/Utils/Csv.hs b/src/Handler/Utils/Csv.hs index 128b94b3b..2a38b6b7f 100644 --- a/src/Handler/Utils/Csv.hs +++ b/src/Handler/Utils/Csv.hs @@ -55,7 +55,7 @@ decodeCsv' fromCsv' = do encOpts <- maybe def (userCsvOptions . entityVal) <$> lift maybeAuth let - recode' + recode' | enc == "UTF8" = id | otherwise @@ -132,7 +132,7 @@ decodeCsv' fromCsv' = do newline = 10 cr = 13 - + encodeCsv :: ( ToNamedRecord csv , MonadHandler m @@ -151,7 +151,7 @@ encodeCsv hdr = do | otherwise = encodeLazyByteString enc . decodeLazyByteString UTF8 where enc = csvOpts ^. _csvFormat . _csvEncoding - fmap (encodeByNameWith (csvOpts ^. _csvFormat . _CsvEncodeOptions) hdr) (C.foldMap pure) >>= C.sourceLazy . recode' + C.foldMap pure >>= (C.sourceLazy . recode') . encodeByNameWith (csvOpts ^. _csvFormat . _CsvEncodeOptions) hdr timestampCsv :: ( MonadHandler m , HandlerSite m ~ UniWorX @@ -181,7 +181,7 @@ encodeDefaultOrderedCsv :: forall csv m. => ConduitT csv ByteString m () encodeDefaultOrderedCsv = encodeCsv $ headerOrder (error "headerOrder" :: csv) - + respondCsv :: ToNamedRecord csv => Header -> ConduitT () csv Handler () diff --git a/src/Handler/Utils/DateTime.hs b/src/Handler/Utils/DateTime.hs index c800b8857..7fd3c4c54 100644 --- a/src/Handler/Utils/DateTime.hs +++ b/src/Handler/Utils/DateTime.hs @@ -175,7 +175,7 @@ validDateTimeFormats TimeLocale{..} SelFormatTime = Set.fromList . concat . catM ] , do guard $ uncurry (/=) amPm - guard $ any (any $ not . Char.isLower) [fst amPm, snd amPm] + guard . not $ all (all Char.isLower) [fst amPm, snd amPm] Just [ DateTimeFormat "%I:%M %P" , DateTimeFormat "%I:%M:%S %P" @@ -310,7 +310,7 @@ instance Csv.FromField ZonedTime where utcRes = localTimeToUTC localRes LTUUnique{_ltuResult} <- pure utcRes return $ utcToZonedTime _ltuResult - + parseFormats = do date <- ["%Y-%m-%d", "%d.%m.%Y"] sep <- ["T", " "] diff --git a/src/Handler/Utils/Delete.hs b/src/Handler/Utils/Delete.hs index 4fc926ffa..56cf00420 100644 --- a/src/Handler/Utils/Delete.hs +++ b/src/Handler/Utils/Delete.hs @@ -111,7 +111,7 @@ deleteR' DeleteRoute{..} = do redirect drSuccess False -> redirect drAbort - + targetRoute <- fromMaybe (error "getDeleteR called from 404-handler") <$> getCurrentRoute let deleteForm = wrapForm' BtnDelete deleteFormWdgt def { formAction = Just $ SomeRoute targetRoute diff --git a/src/Handler/Utils/Exam.hs b/src/Handler/Utils/Exam.hs index e54f9c3f4..e192dc688 100644 --- a/src/Handler/Utils/Exam.hs +++ b/src/Handler/Utils/Exam.hs @@ -96,7 +96,7 @@ examBonus (Entity eId Exam{..}) = runConduit $ E.on $ examRegistration E.^. ExamRegistrationOccurrence E.==. examOccurrence E.?. ExamOccurrenceId E.where_ $ sheet E.^. SheetCourse E.==. E.val examCourse E.&&. examRegistration E.^. ExamRegistrationExam E.==. E.val eId - E.where_ $ E.case_ + E.where_ $ E.case_ [ E.when_ ( E.not_ . E.isNothing $ examRegistration E.^. ExamRegistrationOccurrence ) E.then_ @@ -137,8 +137,8 @@ getRelevantSheetsUpTo cid uid mCutoff postprocess = Map.fromList . map postprocess' where postprocess' (E.Value sId, E.Value sType, fmap entityVal -> sub) = (sId, ) . (sType, ) $ assertM submissionRatingDone sub >>= submissionRatingPoints - - + + examResultBonus :: ExamBonusRule @@ -158,7 +158,7 @@ examResultBonus bonusRule bonusPossible bonusAchieved = case bonusRule of where achieved = toRational (getSum $ achievedPoints bonusAchieved) + scalePasses (getSum $ achievedPasses bonusAchieved) possible = toRational (getSum $ sumSheetsPoints bonusPossible) + scalePasses (getSum $ numSheetsPasses bonusPossible) - + scalePasses :: Integer -> Rational -- ^ Rescale passes so count of all sheets with pass is worth as many points as sum of all sheets with points scalePasses passes @@ -179,7 +179,7 @@ examResultBonus bonusRule bonusPossible bonusAchieved = case bonusRule of -> succ whole | otherwise -> pred whole - + examGrade :: ( MonoFoldable mono , Element mono ~ ExamResultPoints ) @@ -204,7 +204,7 @@ examGrade Exam{..} mBonus (otoList -> results) -> ps | otherwise = ps - + pointsToGrade :: Points -> Maybe ExamGrade pointsToGrade ps = examGradingRule <&> \case ExamGradingKey{..} @@ -234,9 +234,9 @@ examBonusGrade exam@Exam{..} bonusInp = (mBonus, ) . examGrade exam mBonus bonusPossible = normalSummary <$> sheetSummary bonusAchieved = (<>) <$> fmap normalSummary sheetSummary <*> fmap bonusSummary sheetSummary - - + + data ExamAutoOccurrenceConfig = ExamAutoOccurrenceConfig { eaocMinimizeRooms :: Bool , eaocFinenessCost :: Rational -- ^ Cost factor incentivising shorter common prefixes on breaks between rooms @@ -257,7 +257,7 @@ makeLenses_ ''ExamAutoOccurrenceConfig deriveJSON defaultOptions { fieldLabelModifier = camelToPathPiece' 1 } ''ExamAutoOccurrenceConfig - + examAutoOccurrence :: forall seed. Hashable seed @@ -290,7 +290,7 @@ examAutoOccurrence (hash -> seed) rule ExamAutoOccurrenceConfig{..} occurrences nullResult = (Nothing, view _2 <$> users) usersCount :: forall a. Num a => a usersCount = getSum $ foldMap (Sum . fromIntegral . Set.size) users' - + users' :: Map [CI Char] (Set UserId) -- ^ Finest partition of users users' = case rule of @@ -367,7 +367,7 @@ examAutoOccurrence (hash -> seed) rule ExamAutoOccurrenceConfig{..} occurrences wordMap = Map.fromListWith (+) wordLengths wordIx :: Iso' wordId Int - wordIx = iso (\wId -> let Just ix' = findIndex (== wId) $ Array.elems collapsedWords + wordIx = iso (\wId -> let Just ix' = elemIndex wId $ Array.elems collapsedWords in ix' ) (collapsedWords Array.!) @@ -448,7 +448,7 @@ examAutoOccurrence (hash -> seed) rule ExamAutoOccurrenceConfig{..} occurrences | otherwise -> return (accCost', accMap') lineIxs = reverse $ map (view _1) lineLengths in accumResult 0 (Map.size wordMap) (0, []) - + widthCost :: Maybe lineId -> Natural -> Natural -> Extended Rational widthCost l lineWidth w @@ -463,7 +463,7 @@ examAutoOccurrence (hash -> seed) rule ExamAutoOccurrenceConfig{..} occurrences where longestLine = maximum . mapNonNull (view _2) $ impureNonNull occurrences' - + lcp :: Eq a => [a] -> [a] -> [a] -- ^ Longest common prefix lcp [] _ = [] @@ -588,7 +588,7 @@ examAutoOccurrence (hash -> seed) rule ExamAutoOccurrenceConfig{..} occurrences occSize :: Num a => ExamOccurrenceId -> a occSize occId = fromIntegral . length $ Map.filter (== Just occId) resultUsers - + rangeAlphabet :: Set (CI Char) rangeAlphabet | ExamRoomSurname <- rule diff --git a/src/Handler/Utils/ExamOffice/Exam.hs b/src/Handler/Utils/ExamOffice/Exam.hs index 30f1d30c9..2a21e24c7 100644 --- a/src/Handler/Utils/ExamOffice/Exam.hs +++ b/src/Handler/Utils/ExamOffice/Exam.hs @@ -15,7 +15,7 @@ resultIsSynced authId examResult = (hasSchool E.&&. allSchools) E.||. (E.not_ ha anySync = E.exists . E.from $ \synced -> E.where_ $ synced E.^. ExamOfficeResultSyncedResult E.==. examResult E.^. ExamResultId E.&&. synced E.^. ExamOfficeResultSyncedTime E.>=. examResult E.^. ExamResultLastChanged - + hasSchool = E.exists . E.from $ \userFunction -> E.where_ $ userFunction E.^. UserFunctionUser E.==. authId E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice @@ -27,7 +27,7 @@ resultIsSynced authId examResult = (hasSchool E.&&. allSchools) E.||. (E.not_ ha E.&&. synced E.^. ExamOfficeResultSyncedResult E.==. examResult E.^. ExamResultId E.&&. synced E.^. ExamOfficeResultSyncedTime E.>=. examResult E.^. ExamResultLastChanged - + examOfficeExamResultAuth :: E.SqlExpr (E.Value UserId) -- ^ office -> E.SqlExpr (Entity ExamResult) -> E.SqlExpr (E.Value Bool) diff --git a/src/Handler/Utils/ExamOffice/ExternalExam.hs b/src/Handler/Utils/ExamOffice/ExternalExam.hs index 76a24139c..9dcac4d84 100644 --- a/src/Handler/Utils/ExamOffice/ExternalExam.hs +++ b/src/Handler/Utils/ExamOffice/ExternalExam.hs @@ -16,7 +16,7 @@ resultIsSynced authId eexamResult = (hasSchool E.&&. allSchools) E.||. (E.not_ h anySync = E.exists . E.from $ \synced -> E.where_ $ synced E.^. ExamOfficeExternalResultSyncedResult E.==. eexamResult E.^. ExternalExamResultId E.&&. synced E.^. ExamOfficeExternalResultSyncedTime E.>=. eexamResult E.^. ExternalExamResultLastChanged - + hasSchool = E.exists . E.from $ \userFunction -> E.where_ $ userFunction E.^. UserFunctionUser E.==. authId E.&&. userFunction E.^. UserFunctionFunction E.==. E.val SchoolExamOffice @@ -28,7 +28,7 @@ resultIsSynced authId eexamResult = (hasSchool E.&&. allSchools) E.||. (E.not_ h E.&&. synced E.^. ExamOfficeExternalResultSyncedResult E.==. eexamResult E.^. ExternalExamResultId E.&&. synced E.^. ExamOfficeExternalResultSyncedTime E.>=. eexamResult E.^. ExternalExamResultLastChanged - + examOfficeExternalExamResultAuth :: E.SqlExpr (E.Value UserId) -- ^ office -> E.SqlExpr (Entity ExternalExamResult) -> E.SqlExpr (E.Value Bool) diff --git a/src/Handler/Utils/ExternalExam/Users.hs b/src/Handler/Utils/ExternalExam/Users.hs index 3aaf8b7e2..75d52b3ff 100644 --- a/src/Handler/Utils/ExternalExam/Users.hs +++ b/src/Handler/Utils/ExternalExam/Users.hs @@ -18,7 +18,7 @@ import qualified Database.Esqueleto.Utils as E import Data.Csv ((.:)) import qualified Data.Csv as Csv - + import qualified Handler.Utils.ExamOffice.ExternalExam as ExternalExam import qualified Data.Text as Text @@ -181,7 +181,7 @@ makeExternalExamUsersTable mode (Entity eeId ExternalExam{..}) = do ssh = externalExamSchool coursen = externalExamCourseName examn = externalExamExamName - + uid <- requireAuthId csvName <- getMessageRender <*> pure (MsgExternalExamUserCsvName tid ssh coursen examn) isLecturer <- hasReadAccessTo $ EExamR tid ssh coursen examn EEUsersR @@ -245,7 +245,7 @@ makeExternalExamUsersTable mode (Entity eeId ExternalExam{..}) = do ++ [ Right sync | sync@(_, _, t, _) <- syncs, t <= lastChange] syncIcon :: Widget - syncIcon + syncIcon | not isSynced , not hasSyncs = mempty @@ -407,7 +407,7 @@ makeExternalExamUsersTable mode (Entity eeId ExternalExam{..}) = do yield $ ExternalExamUserCsvRegisterData pid occTime csvEUserExamResult DBCsvDiffExisting{..} -> do let ExternalExamUserTableCsv{..} = dbCsvNew - whenIsJust (zonedTimeToUTC <$> csvEUserOccurrenceStart) $ \occTime -> + whenIsJust (zonedTimeToUTC <$> csvEUserOccurrenceStart) $ \occTime -> when (occTime /= dbCsvOld ^. resultResult . _entityVal . _externalExamResultTime) $ yield $ ExternalExamUserCsvSetTimeData (E.unValue dbCsvOldKey) occTime @@ -485,10 +485,10 @@ makeExternalExamUsersTable mode (Entity eeId ExternalExam{..}) = do registeredUserName existing (E.Value -> registration) = nameWidget userDisplayName userSurname where Entity _ User{..} = view resultUser $ existing Map.! registration - + guessUser' :: ExternalExamUserTableCsv -> DB UserId guessUser' ExternalExamUserTableCsv{..} = do - let criteria = Set.fromList $ catMaybes + let criteria = Set.fromList $ catMaybes [ GuessUserMatrikelnummer <$> csvEUserMatriculation , GuessUserDisplayName <$> csvEUserName , GuessUserSurname <$> csvEUserSurname diff --git a/src/Handler/Utils/Files.hs b/src/Handler/Utils/Files.hs index e8af2f9ad..9400a9a4b 100644 --- a/src/Handler/Utils/Files.hs +++ b/src/Handler/Utils/Files.hs @@ -13,7 +13,7 @@ import qualified Network.Minio as Minio import qualified Data.ByteString.Base64.URL as Base64 import qualified Data.ByteArray as ByteArray - + data SourceFilesException = SourceFilesMismatchedHashes @@ -34,7 +34,7 @@ sourceFile FileReference{..} = do -> maybeT (throwM SourceFilesContentUnavailable) $ do let uploadName = decodeUtf8 . Base64.encodeUnpadded $ ByteArray.convert fileContentHash uploadBucket <- getsYesod $ views appSettings appUploadCacheBucket - fmap Just . (hoistMaybe =<<) . runAppMinio . runMaybeT $ do + fmap Just . hoistMaybe <=< runAppMinio . runMaybeT $ do objRes <- catchIfMaybeT minioIsDoesNotExist $ Minio.getObject uploadBucket uploadName Minio.defaultGetObjectOptions lift . runConduit $ Minio.gorObjectStream objRes .| C.fold | fmap (fmap fileContentHash) mFileContent /= fmap Just fileReferenceContent @@ -52,6 +52,6 @@ sourceFile FileReference{..} = do sourceFiles' :: forall file. HasFileReference file => ConduitT file File (YesodDB UniWorX) () sourceFiles' = C.mapM sourceFile' - + sourceFile' :: forall file. HasFileReference file => file -> DB File sourceFile' = sourceFile . view (_FileReference . _1) diff --git a/src/Handler/Utils/Form.hs b/src/Handler/Utils/Form.hs index cc5be1768..ae8828d40 100644 --- a/src/Handler/Utils/Form.hs +++ b/src/Handler/Utils/Form.hs @@ -22,7 +22,7 @@ import Handler.Utils.I18n import Handler.Utils.Files import Import -import Data.Char (chr, ord) +import Data.Char ( chr, ord, isDigit ) import qualified Data.Char as Char import qualified Data.Text as Text import qualified Data.CaseInsensitive as CI @@ -55,8 +55,6 @@ import Data.Aeson.Text (encodeToLazyText) import qualified Text.Email.Validate as Email import Data.Text.Lens (unpacked) - -import Data.Char (isDigit) import Text.Blaze (toMarkup) import Handler.Utils.Form.MassInput @@ -64,6 +62,8 @@ import Handler.Utils.Form.MassInput import qualified Data.Binary as Binary import qualified Data.ByteString.Base64.URL as Base64 +{-# ANN module ("HLint: ignore Use const" :: String) #-} + ---------------------------- -- Buttons (new version ) -- @@ -194,13 +194,13 @@ optionalAction' minp justAct fs@FieldSettings{..} defActive csrf = do let actionViews = over (mapped . _fvInput) (\w -> $(widgetFile "widgets/multi-action/optional-action")) actionViews' return (doRes >>= bool (pure Nothing) (Just <$> actionRes), over _fvInput (mappend $ toWidget csrf) doView : actionViews) - + optionalActionA :: AForm Handler a -> FieldSettings UniWorX -> Maybe Bool -> AForm Handler (Maybe a) optionalActionA = optionalActionA' mpopt - + optionalActionA' :: (Field Handler Bool -> FieldSettings UniWorX -> Maybe Bool -> MForm Handler (FormResult Bool, FieldView UniWorX)) -> AForm Handler a -> FieldSettings UniWorX @@ -239,7 +239,7 @@ multiActionOpts :: forall action a. -> Maybe action -> (Html -> MForm Handler (FormResult a, [FieldView UniWorX])) multiActionOpts = multiActionOpts' mpopt - + multiAction' :: forall action a. ( RenderMessage UniWorX action, PathPiece action, Ord action ) => (Field Handler action -> FieldSettings UniWorX -> Maybe action -> MForm Handler (FormResult action, FieldView UniWorX)) @@ -263,7 +263,7 @@ multiActionField minp acts (actField, actExternal, actMessage) fs defAction csrf MsgRenderer mr <- getMsgRenderer let actionResults = view _1 <$> results - + actionViews = Map.foldrWithKey accViews [] results accViews :: forall b. action -> (b, [FieldView UniWorX]) -> [FieldView UniWorX] -> [FieldView UniWorX] @@ -289,11 +289,11 @@ multiActionOpts' minp acts mActsOpts fs defAction csrf = do actsOpts <- liftHandler mActsOpts let actsOpts' = OptionList { olOptions = filter (flip Map.member acts . optionInternalValue) $ olOptions actsOpts - , olReadExternal = assertM (flip Map.member acts) . olReadExternal actsOpts + , olReadExternal = assertM (`Map.member` acts) . olReadExternal actsOpts } acts' = Map.filterWithKey (\a _ -> any ((== a) . optionInternalValue) $ olOptions actsOpts') acts - actOption act = listToMaybe . filter (\Option{..} -> optionInternalValue == act) $ olOptions actsOpts' + actOption act = find (\Option{..} -> optionInternalValue == act) $ olOptions actsOpts' actExternal = fmap optionExternalValue . actOption actMessage = fmap (SomeMessage . optionDisplay) . actOption @@ -305,7 +305,7 @@ multiActionA :: (RenderMessage UniWorX action, PathPiece action, Ord action) -> Maybe action -> AForm Handler a multiActionA acts fSettings defAction = formToAForm $ multiAction acts fSettings defAction mempty - + multiActionAOpts :: Ord action => Map action (AForm Handler a) -> Handler (OptionList action) @@ -320,7 +320,7 @@ multiActionW :: (RenderMessage UniWorX action, PathPiece action, Ord action) -> Maybe action -> WForm Handler (FormResult a) multiActionW acts fSettings defAction = aFormToWForm $ multiActionA acts fSettings defAction - + multiActionWOpts :: Ord action => Map action (AForm Handler a) -> Handler (OptionList action) @@ -335,7 +335,7 @@ multiActionM :: (RenderMessage UniWorX action, PathPiece action, Ord action) -> Maybe action -> (Html -> MForm Handler (FormResult a, Widget)) multiActionM acts fSettings defAction = renderAForm FormStandard $ multiActionA acts fSettings defAction - + multiActionMOpts :: Ord action => Map action (AForm Handler a) -> Handler (OptionList action) @@ -400,13 +400,13 @@ explainedMultiAction' :: forall action a. explainedMultiAction' minp acts mActsOpts fs defAction csrf = do (actsOpts, actsReadExternal) <- liftHandler mActsOpts let actsOpts' = filter (flip Map.member acts . optionInternalValue . view _1) actsOpts - actsReadExternal' = assertM (flip Map.member acts) . actsReadExternal + actsReadExternal' = assertM (`Map.member` acts) . actsReadExternal acts' = Map.filterWithKey (\a _ -> any ((== a) . optionInternalValue . view _1) actsOpts') acts - actOption act = listToMaybe . filter (\Option{..} -> optionInternalValue == act) $ view _1 <$> actsOpts' + actOption act = find (\Option{..} -> optionInternalValue == act) $ view _1 <$> actsOpts' actExternal = fmap optionExternalValue . actOption actMessage = fmap (SomeMessage . optionDisplay) . actOption - + multiActionField minp acts' (explainedSelectionField Nothing $ return (actsOpts', actsReadExternal'), actExternal, actMessage) fs defAction csrf explainedMultiAction :: forall action a. @@ -463,7 +463,7 @@ pointsField :: (Monad m, HandlerSite m ~ UniWorX) => Field m Points pointsField = pointsFieldMinMax (Just 0) Nothing pointsFieldMax :: (Monad m, HandlerSite m ~ UniWorX) => Maybe Points -> Field m Points -pointsFieldMax limit = pointsFieldMinMax (Just 0) limit +pointsFieldMax = pointsFieldMinMax (Just 0) pointsFieldMinMax :: (Monad m, HandlerSite m ~ UniWorX) => Maybe Points -> Maybe Points -> Field m Points pointsFieldMinMax lower upper = checklower $ checkupper $ fixedPrecMinMaxField lower upper -- NOTE: fixedPrecMinMaxField uses HTML5 input attributes min & max for better browser supprt, but may not be supported by all browsers yet @@ -795,7 +795,7 @@ examGradingRuleForm prev = multiActionA actions (fslI MsgExamGradingRule) $ clas let errors | anyOf (folded . _1 . _FormSuccess) (< 0) bounds = [mr MsgPointsMustBeNonNegative] - | FormSuccess bounds' <- sequence $ map (view _1) bounds + | FormSuccess bounds' <- mapM (view _1) bounds , not $ monotone bounds' = [mr MsgPointsMustBeMonotonic] | otherwise @@ -908,7 +908,7 @@ genericFileField mkOpts = Field{..} modifySessionJson SessionFiles $ \(fromMaybe mempty -> MergeHashMap old) -> Just . MergeHashMap $ HashMap.insert ident (Map.insert fileReferenceTitle (sfId, fileReferenceModified) $ HashMap.findWithDefault mempty ident old) old - + _FileTitle :: Prism' Text FilePath _FileTitle = prism' (("f." <>) . pack) $ fmap unpack . Text.stripPrefix "f." @@ -937,7 +937,7 @@ genericFileField mkOpts = Field{..} whenIsJust fieldMaxFileSize $ \maxSize -> forM_ files $ \fInfo -> do fLength <- runConduit $ fileSource fInfo .| C.takeE (fromIntegral $ succ maxSize) .| C.lengthE when (fLength > maxSize) $ do - when (is _Just mIdent) $ + when (is _Just mIdent) $ liftHandler . runDB . runConduit $ mapM_ (transPipe lift . handleFile) files .| handleUpload opts mIdent @@ -946,7 +946,7 @@ genericFileField mkOpts = Field{..} if | invExt : _ <- filter invalidUploadExtension uploadedFilenames -> do - when (is _Just mIdent) $ + when (is _Just mIdent) $ liftHandler . runDB . runConduit $ mapM_ (transPipe lift . handleFile) files .| handleUpload opts mIdent @@ -967,7 +967,7 @@ genericFileField mkOpts = Field{..} .| C.mapMaybe (\fTitle -> fmap (fTitle, ) . assertM (views _3 $ not . fieldOptionForce) $ Map.lookup fTitle permittedFiles) .| C.filter (\(fTitle, _) -> fieldMultiple - || ( (bool (\n h -> h == pure n) elem fieldMultiple) fTitle (mapMaybe (preview _FileTitle) vals) + || ( bool (\n h -> h == pure n) elem fieldMultiple fTitle (mapMaybe (preview _FileTitle) vals) && null files ) ) @@ -985,7 +985,7 @@ genericFileField mkOpts = Field{..} .| sinkNull throwE $ SomeMessage MsgOnlyUploadOneFile | otherwise -> return $ Just fSrc' - + fieldView :: FieldViewFunc m FileUploads fieldView fieldId fieldName _attrs val req = do opts@FileField{..} <- liftHandler mkOpts @@ -1035,9 +1035,9 @@ genericFileField mkOpts = Field{..} $(widgetFile "widgets/genericFileField") unpackZips :: Text unpackZips = "unpack-zip" - - - + + + fileFieldMultiple :: (MonadHandler m, HandlerSite m ~ UniWorX) => Field m FileUploads fileFieldMultiple = genericFileField $ return FileField { fieldIdent = Nothing @@ -1057,8 +1057,8 @@ fileField = genericFileField $ return FileField , fieldAdditionalFiles = Map.empty , fieldMaxFileSize = Nothing } - -specificFileField :: UploadSpecificFile -> Field Handler FileUploads + +specificFileField :: UploadSpecificFile -> Field Handler FileUploads specificFileField UploadSpecificFile{..} = convertField (.| fixupFileTitles) id . genericFileField $ return FileField { fieldIdent = Nothing , fieldUnpackZips = FileFieldUserOption True False @@ -1072,7 +1072,7 @@ specificFileField UploadSpecificFile{..} = convertField (.| fixupFileTitles) id zipFileField :: Bool -- ^ Unpack zips? -> Maybe (NonNull (Set Extension)) -- ^ Restrictions on file extensions - -> Field Handler FileUploads + -> Field Handler FileUploads zipFileField doUnpack permittedExtensions = genericFileField $ return FileField { fieldIdent = Nothing , fieldUnpackZips = FileFieldUserOption True doUnpack @@ -1091,23 +1091,23 @@ fileUploadForm isReq mkFs = \case UploadAny{..} -> bool aopt (\f fs _ -> Just <$> areq f fs Nothing) isReq (zipFileField unpackZips extensionRestriction) (mkFs unpackZips) Nothing UploadSpecific{..} - -> mergeFileSources <$> sequenceA (map specificFileForm . Set.toList $ toNullable specificFiles) + -> mergeFileSources <$> traverse specificFileForm (Set.toList $ toNullable specificFiles) where specificFileForm :: UploadSpecificFile -> AForm Handler (Maybe FileUploads) specificFileForm spec@UploadSpecificFile{..} = bool (\f fs d -> aopt f fs $ fmap Just d) (\f fs d -> Just <$> areq f fs d) specificFileRequired (specificFileField spec) (fsl specificFileLabel) Nothing - mergeFileSources :: [Maybe FileUploads] -> Maybe FileUploads + mergeFileSources :: [Maybe FileUploads] -> Maybe FileUploads mergeFileSources (catMaybes -> sources) = case sources of [] -> Nothing fs -> Just $ sequence_ fs multiFileField' :: FileUploads -- ^ Permitted files in same format as produced by `multiFileField` - -> Field Handler FileUploads + -> Field Handler FileUploads multiFileField' permittedFiles = multiFileField . runConduit $ permittedFiles .| C.foldMap Set.singleton multiFileField :: Handler (Set FileReference) -- ^ Set of files that may be submitted by id-reference - -> Field Handler FileUploads + -> Field Handler FileUploads multiFileField mkPermitted = genericFileField $ mkField <$> mkPermitted where mkField permitted = FileField { fieldIdent = Nothing @@ -1237,7 +1237,7 @@ dayTimeField fs mutc = do fieldTimeFormat :: String -- fieldTimeFormat = "%e.%m.%y %k:%M" fieldTimeFormat = "%Y-%m-%dT%H:%M:%S" - + localTimeField :: (MonadHandler m, HandlerSite m ~ UniWorX) => Field m LocalTime localTimeField = Field { fieldParse = parseHelperGen readTime @@ -1343,7 +1343,7 @@ sectionedFuncForm mkSection mkForm FieldSettings{fsName = _, fsAttrs = _, ..} is -> return () lift $ tell fs aFormToWForm $ Map.union <$> wFormToAForm (pure res) <*> acc - + funcFieldView :: (FormResult (k -> v), Widget) -> MForm m (FormResult (k -> v), [FieldView UniWorX]) funcFieldView (res, formView) = do mr <- getMessageRender @@ -1437,7 +1437,7 @@ optionsCryptoIdF (otoList -> iVals) toExtVal toMsg , optionExternalValue = toPathPiece (cID :: CryptoUUID k) , optionInternalValue } - + examOccurrenceField :: ( MonadHandler m , HandlerSite m ~ UniWorX @@ -1445,7 +1445,7 @@ examOccurrenceField :: ( MonadHandler m => ExamId -> Field m ExamOccurrenceId examOccurrenceField eid - = hoistField liftHandler . selectField . (fmap $ fmap entityKey) + = hoistField liftHandler . selectField . fmap (fmap entityKey) $ optionsPersistCryptoId [ ExamOccurrenceExam ==. eid ] [ Asc ExamOccurrenceName ] examOccurrenceName @@ -1469,7 +1469,7 @@ data MultiUserInvitationMode | MUILookupAnyUser (Maybe (E.SqlQuery (E.SqlExpr (Entity User)))) | MUILookupSuggested (SomeMessage UniWorX) (E.SqlQuery (E.SqlExpr (Entity User))) - + multiUserInvitationField :: forall m. ( MonadHandler m , HandlerSite m ~ UniWorX @@ -1553,7 +1553,7 @@ multiUserField onlySuggested suggestions = Field{..} whenIsJust suggestions $ \suggestions' -> do suggestedEmails <- fmap (Map.assocs . Map.fromListWith min . map (over _2 E.unValue . over _1 E.unValue)) . liftHandler . runDB . E.select $ do user <- suggestions' - return $ ( E.case_ + return ( E.case_ [ E.when_ (unique UserDisplayEmail user) E.then_ (user E.^. UserDisplayEmail) , E.when_ (unique UserEmail user) @@ -1681,7 +1681,7 @@ examResultGradeField = flip examResultField $ do ) } ] - + examResultPassedField :: forall m. ( MonadHandler m , HandlerSite m ~ UniWorX @@ -1699,7 +1699,7 @@ examResultPassedField = flip examResultField $ do ) } ] - + examResultPassedGradeField :: forall m. ( MonadHandler m , HandlerSite m ~ UniWorX @@ -1739,7 +1739,7 @@ examResultModeField :: forall m. examResultModeField optMsg ExamGradingGrades = convertField (fmap Right) (fmap $ either (review passingGrade) id) $ examResultGradeField optMsg examResultModeField optMsg ExamGradingPass = convertField (fmap Left) (fmap $ either id (view passingGrade)) $ examResultPassedField optMsg examResultModeField optMsg ExamGradingMixed = examResultPassedGradeField optMsg - + examGradeField :: forall m. ( MonadHandler m @@ -1768,7 +1768,7 @@ examField :: forall m. , HandlerSite m ~ UniWorX ) => Maybe (SomeMessage UniWorX) -> CourseId -> Field m ExamId -examField optMsg cId = hoistField liftHandler . selectField' optMsg . (fmap $ fmap entityKey) $ +examField optMsg cId = hoistField liftHandler . selectField' optMsg . fmap (fmap entityKey) $ optionsPersistCryptoId [ExamCourse ==. cId] [Asc ExamName] examName @@ -1814,7 +1814,7 @@ csvFormatOptionsForm fs mPrev = hoistAForm liftHandler . multiActionA csvActs fs delimiterOpts = do MsgRenderer mr <- getMsgRenderer let - opts = + opts = [ (MsgCsvDelimiterNull, '\0') , (MsgCsvDelimiterTab, '\t') , (MsgCsvDelimiterComma, ',') @@ -1834,13 +1834,13 @@ csvFormatOptionsForm fs mPrev = hoistAForm liftHandler . multiActionA csvActs fs | (msg, c) <- opts ] return OptionList{..} - + lineEndOpts :: Handler (OptionList Bool) lineEndOpts = optionsPathPiece [ (MsgCsvCrLf, True ) , (MsgCsvLf, False) ] - + quoteOpts :: Handler (OptionList Quoting) quoteOpts = optionsF [ QuoteMinimal @@ -1870,7 +1870,7 @@ csvOptionsForm mPrev = hoistAForm liftHandler $ CsvOptions <$> csvFormatOptionsForm (fslI MsgCsvFormatOptions & setTooltip MsgCsvOptionsTip) (csvFormat <$> mPrev) <*> apopt checkBoxField (fslI MsgCsvTimestamp & setTooltip MsgCsvTimestampTip) (csvTimestamp <$> mPrev) - + courseSelectForm :: forall ident handler. ( PathPiece ident , MonadHandler handler, HandlerSite handler ~ UniWorX @@ -1894,7 +1894,7 @@ courseSelectForm query coursePred miButtonAction' miIdent' fSettings fRequired m , E.asc $ course E.^. CourseName ] return course - + miAdd' nudge btn csrf = do let courseOptions = optionsCryptoIdE query' (\Course{..} -> MsgCourseOption courseTerm courseSchool courseName) >>= fmap (fmap entityKey . mkOptionList) . filterM (coursePred . optionInternalValue) . olOptions @@ -1925,7 +1925,7 @@ embedRenderMessageVariant ''UniWorX ''CourseParticipantStateIsActive $ \case finitePathPiece ''CourseParticipantStateIsActive ["inactive", "active"] makeWrapped ''CourseParticipantStateIsActive - + courseParticipantStateIsActiveField :: (MonadHandler m, HandlerSite m ~ UniWorX) => Maybe (SomeMessage UniWorX) -> Field m Bool courseParticipantStateIsActiveField optMsg = hoistField liftHandler . isoField (_Wrapped @CourseParticipantStateIsActive) $ radioGroupField optMsg optionsFinite diff --git a/src/Handler/Utils/Form/MassInput.hs b/src/Handler/Utils/Form/MassInput.hs index fd1a79895..06e856324 100644 --- a/src/Handler/Utils/Form/MassInput.hs +++ b/src/Handler/Utils/Form/MassInput.hs @@ -37,6 +37,8 @@ import Text.Hamlet (hamletFile) import Algebra.Lattice.Ordered (Ordered(..)) +{-# ANN module ("HLint: ignore Use const" :: String) #-} + $(mapM tupleBoxCoord [2..4]) @@ -149,7 +151,7 @@ instance (Liveliness l1, Liveliness l2) => Liveliness (MapLiveliness l1 l2) wher (\ts -> let ks = Set.mapMonotonic fst ts in fmap MapLiveliness . sequence $ Map.fromSet (\k -> preview liveCoords . Set.mapMonotonic snd $ Set.filter ((== k) . fst) ts) ks) -type MassInputDelete liveliness = forall m a. Applicative m => Map (BoxCoord liveliness) a -> (BoxCoord liveliness) -> m (Map (BoxCoord liveliness) (BoxCoord liveliness)) +type MassInputDelete liveliness = forall m a. Applicative m => Map (BoxCoord liveliness) a -> BoxCoord liveliness -> m (Map (BoxCoord liveliness) (BoxCoord liveliness)) miDeleteList :: MassInputDelete ListLength @@ -330,9 +332,9 @@ massInput MassInput{ miIdent = toPathPiece -> miIdent, ..} FieldSettings{..} fvR guard $ isn't _FormMissing btnRes res miAdd' = traverse ($ mempty) $ miAdd miCoord dimIx nudgeAddWidgetName btnView - addRes'' <- miAdd' & mapped . _Just . _1 %~ wBtnRes + addRes'' <- miAdd' <&> (_Just . _1) %~ wBtnRes addRes' <- fmap join . for addRes'' $ bool (return . Just) (\(res, _view) -> set (_Just . _1) res <$> local (set _1 Nothing) miAdd') (is (_Just . _FormSuccess) (fst <$> addRes'') || is _FormMissing btnRes) - let dimRes' = Map.singleton (dimIx, miCoord) (maybe (Nothing <$ btnRes) (fmap Just) $ fmap fst addRes', fmap snd addRes') + let dimRes' = Map.singleton (dimIx, miCoord) (maybe (Nothing <$ btnRes) (fmap Just . fst) addRes', fmap snd addRes') case remDims of [] -> return dimRes' ((_, BoxDimension dim) : _) -> do @@ -373,7 +375,7 @@ massInput MassInput{ miIdent = toPathPiece -> miIdent, ..} FieldSettings{..} fvR delShapeUpdate | [FormSuccess shapeUpdate'] <- Map.elems . Map.filter (is _FormSuccess) $ fmap fst delResults = Just shapeUpdate' | otherwise = Nothing - delShape = traverse (flip Map.lookup addedShape) =<< delShapeUpdate + delShape = traverse (`Map.lookup` addedShape) =<< delShapeUpdate let shapeChanged = Fold.any (isn't _FormMissing . view _1) addResults || Fold.any (is _FormSuccess . view _1) delResults @@ -490,7 +492,7 @@ massInputList :: forall handler cellResult ident msg. -> (Markup -> MForm handler (FormResult [cellResult], FieldView UniWorX)) massInputList field fieldSettings onMissing miButtonAction miIdent miSettings miRequired miPrevResult = over (mapped . _1 . mapped) (map snd . Map.elems) . massInput MassInput { miAdd = \_ _ _ submitBtn -> Just $ \csrf -> - return (FormSuccess $ \pRes -> FormSuccess $ Map.singleton (maybe 0 succ . fmap fst $ Map.lookupMax pRes) (), toWidget csrf >> fvWidget submitBtn) + return (FormSuccess $ \pRes -> FormSuccess $ Map.singleton (maybe 0 (succ . fst) $ Map.lookupMax pRes) (), toWidget csrf >> fvWidget submitBtn) , miCell = \pos () iRes nudge csrf -> over _2 (\fv -> $(widgetFile "widgets/massinput/list/cell")) <$> mreqMsg field (fieldSettings pos & addName (nudge "field")) onMissing iRes , miDelete = miDeleteList @@ -544,7 +546,7 @@ massInputAccum miAdd' miCell' miButtonAction miLayout miIdent fSettings fRequire miAdd :: ListPosition -> Natural -> (Text -> Text) -> FieldView UniWorX -> Maybe (Markup -> MForm handler (FormResult (Map ListPosition cellData -> FormResult (Map ListPosition cellData)), Widget)) - miAdd _pos _dim nudge submitView = Just $ \csrf' -> over (_1 . mapped) doAdd <$> miAdd' nudge submitView csrf' + miAdd _pos _dim nudge submitView = Just (fmap (over (_1 . mapped) doAdd) . miAdd' nudge submitView) doAdd :: ([cellData] -> FormResult [cellData]) -> (Map ListPosition cellData -> FormResult (Map ListPosition cellData)) doAdd f prevData = Map.fromList . zip [startKey..] <$> f prevElems @@ -599,7 +601,7 @@ massInputAccumW :: forall handler cellData ident. massInputAccumW miAdd' miCell' miButtonAction' miLayout' miIdent' fSettings fRequired mPrev = mFormToWForm $ massInputAccum miAdd' miCell' miButtonAction' miLayout' miIdent' fSettings fRequired mPrev mempty - + -- | Wrapper around `massInput` for the common case, that we just want a list of data with existing data modified the same way as new data is added massInputAccumEdit :: forall handler cellData ident. ( MonadHandler handler, HandlerSite handler ~ UniWorX @@ -622,7 +624,7 @@ massInputAccumEdit miAdd' miCell' miButtonAction miLayout miIdent fSettings fReq miAdd :: ListPosition -> Natural -> (Text -> Text) -> FieldView UniWorX -> Maybe (Markup -> MForm handler (FormResult (Map ListPosition cellData -> FormResult (Map ListPosition cellData)), Widget)) - miAdd _pos _dim nudge submitView = Just $ \csrf' -> over (_1 . mapped) doAdd <$> miAdd' nudge submitView csrf' + miAdd _pos _dim nudge submitView = Just (fmap (over (_1 . mapped) doAdd) . miAdd' nudge submitView) doAdd :: ([cellData] -> FormResult [cellData]) -> (Map ListPosition cellData -> FormResult (Map ListPosition cellData)) doAdd f prevData = Map.fromList . zip [startKey..] <$> f prevElems diff --git a/src/Handler/Utils/Form/MassInput/TH.hs b/src/Handler/Utils/Form/MassInput/TH.hs index dac5203b0..3170f8204 100644 --- a/src/Handler/Utils/Form/MassInput/TH.hs +++ b/src/Handler/Utils/Form/MassInput/TH.hs @@ -30,7 +30,7 @@ tupleBoxCoord tupleDim = do instanceD tCxt ([t|IsBoxCoord|] `appT` tupleType) [ funD 'boxDimensions - [ clause [] (normalB . foldr1 (\ds1 ds2 -> [e|(++)|] `appE` ds1 `appE` ds2) . map (\field -> [e|map (\(BoxDimension dim) -> BoxDimension $ $(field) . dim) boxDimensions|]) $ map (fieldLenses !!) [0..pred tupleDim]) [] + [ clause [] (normalB . foldr1 (\ds1 ds2 -> [e|(++)|] `appE` ds1 `appE` ds2) $ map (\field -> [e|map (\(BoxDimension dim) -> BoxDimension $ $(fieldLenses !! field) . dim) boxDimensions|]) [0..pred tupleDim]) [] ] , funD 'boxOrigin [ clause [] (normalB . tupE $ replicate tupleDim [e|boxOrigin|]) [] diff --git a/src/Handler/Utils/I18n.hs b/src/Handler/Utils/I18n.hs index 0394aa578..aaf7132f4 100644 --- a/src/Handler/Utils/I18n.hs +++ b/src/Handler/Utils/I18n.hs @@ -58,13 +58,13 @@ i18nWidgetFilesAvailable' basename = do let fileKinds' = fmap (pack . dropExtension . takeBaseName &&& toTranslation . pack . takeBaseName) availableFiles fileKinds :: Map Text [Text] fileKinds = sortWith (NTop . flip List.elemIndex (NonEmpty.toList appLanguages)) . Set.toList <$> Map.fromListWith Set.union [ (kind, Set.singleton l) | (kind, Just l) <- fileKinds' ] - toTranslation fName = listToMaybe . sortOn length . mapMaybe (flip Text.stripPrefix fName . (<>".")) $ map fst fileKinds' + toTranslation fName = (listToMaybe . sortOn length) (mapMaybe ((flip Text.stripPrefix fName . (<>".")) . fst) fileKinds') iforM fileKinds $ \kind -> maybe (fail $ "‘" <> i18nDirectory <> "’ has no translations for ‘" <> unpack kind <> "’") return . NonEmpty.nonEmpty i18nWidgetFilesAvailable :: FilePath -> Q Exp i18nWidgetFilesAvailable = TH.lift <=< i18nWidgetFilesAvailable' - + i18nWidgetFiles :: FilePath -> Q Exp i18nWidgetFiles basename = do availableTranslations' <- i18nWidgetFilesAvailable' basename diff --git a/src/Handler/Utils/Invitations.hs b/src/Handler/Utils/Invitations.hs index 7d424420d..2a9f90703 100644 --- a/src/Handler/Utils/Invitations.hs +++ b/src/Handler/Utils/Invitations.hs @@ -274,7 +274,7 @@ sourceInvitations :: forall junction m backend. -> ConduitT () (UserEmail, InvitationDBData junction) (ReaderT backend m) () sourceInvitations forKey = selectSource [InvitationFor ==. invRef @junction forKey] [] .| C.mapM decode where - decode (Entity _ (Invitation{invitationEmail, invitationData})) + decode (Entity _ Invitation{invitationEmail, invitationData}) = case fromJSON invitationData of JSON.Success dbData -> return (invitationEmail, dbData) JSON.Error str -> throwM . PersistMarshalError . pack $ "Could not decode invitationData: " <> str @@ -291,7 +291,7 @@ sourceInvitationsF :: forall junction map m backend. , PersistQueryRead backend ) => Key (InvitationFor junction) - -> ReaderT backend m map + -> ReaderT backend m map sourceInvitationsF forKey = runConduit $ sourceInvitations forKey .| C.foldMap (uncurry singletonMap) @@ -309,7 +309,7 @@ deleteInvitations :: forall junction m backend. => Key (InvitationFor junction) -> ConduitT UserEmail Void (ReaderT backend m) () deleteInvitations k = C.foldMap Set.singleton >>= lift . deleteInvitationsF @junction k - + deleteInvitationsF :: forall junction m mono backend. ( IsInvitableJunction junction , MonadIO m @@ -322,7 +322,7 @@ deleteInvitationsF :: forall junction m mono backend. -> ReaderT backend m () -- | Non-conduit version of `deleteInvitations` deleteInvitationsF invitationFor (otoList -> emailList) - = deleteWhere [InvitationEmail <-. nub emailList, InvitationFor ==. invRef @junction invitationFor] + = deleteWhere [InvitationEmail <-. nub emailList, InvitationFor ==. invRef @junction invitationFor] deleteInvitation :: forall junction m backend. ( IsInvitableJunction junction diff --git a/src/Handler/Utils/Memcached.hs b/src/Handler/Utils/Memcached.hs index 3116d6f18..6160965b4 100644 --- a/src/Handler/Utils/Memcached.hs +++ b/src/Handler/Utils/Memcached.hs @@ -44,7 +44,7 @@ import qualified Control.Concurrent.TokenBucket as Concurrent (TokenBucket, newT import System.IO.Unsafe (unsafePerformIO) import Control.Concurrent.STM.Delay - + import qualified Crypto.Saltine.Class as Saltine import qualified Crypto.Saltine.Internal.ByteSizes as Saltine import qualified Crypto.Saltine.Core.AEAD as AEAD @@ -104,7 +104,7 @@ memcachedByGet :: forall a k m. memcachedByGet k = runMaybeT $ do (aeadKey, conn) <- MaybeT $ getsYesod appMemcached let cKey = memcachedKey aeadKey (Proxy @a) k - + encVal <- fmap toStrict . hoist liftIO . catchMaybeT (Proxy @Memcached.MemcachedException) $ Memcached.get_ cKey conn $logDebugS "memcached" "Cache hit" @@ -115,7 +115,7 @@ memcachedByGet k = runMaybeT $ do decrypted <- hoistMaybe $ AEAD.aeadOpen aeadKey nonce encrypted cKey $logDebugS "memcached" "Decryption valid" - + case Binary.decodeOrFail $ fromStrict decrypted of Right (unconsumed, _, v) | null unconsumed -> do @@ -155,7 +155,7 @@ memcachedByInvalidate k _ = maybeT_ $ do newtype MemcachedUnkeyed a = MemcachedUnkeyed { unMemcachedUnkeyed :: a } deriving (Typeable) deriving newtype (Eq, Ord, Show, Binary) - + memcachedGet :: ( MonadHandler m, HandlerSite m ~ UniWorX , Typeable a, Binary a ) @@ -209,7 +209,7 @@ newtype MemcachedUnkeyedLoc a = MemcachedUnkeyedLoc { unMemcachedUnkeyedLoc :: a memcachedHere :: Q Exp memcachedHere = do loc <- location - [e| \mExp -> fmap unMemcachedUnkeyedLoc . memcachedBy mExp loc . fmap MemcachedUnkeyedLoc |] + [e| \mExp -> fmap unMemcachedUnkeyedLoc . memcachedBy mExp loc . fmap MemcachedUnkeyedLoc |] newtype MemcachedKeyedLoc a = MemcachedKeyedLoc { unMemcachedKeyedLoc :: a } deriving (Typeable) @@ -234,7 +234,7 @@ hashableDynamic :: forall a. ( Typeable a, Hashable a, Eq a ) => a -> HashableDynamic hashableDynamic v = HashableDynamic (typeOf v) v - + memcachedLimit :: TVar (HashMap HashableDynamic Concurrent.TokenBucket) memcachedLimit = unsafePerformIO . newTVarIO $ HashMap.empty {-# NOINLINE memcachedLimit #-} @@ -267,7 +267,7 @@ memcachedLimitedWith (doGet, doSet) liftAct (hashableDynamic -> lK) burst rate t sufficientTokens <- liftIO $ Concurrent.tokenBucketTryAlloc bucket burst rate tokens $logDebugS "memcachedLimitedWith" $ "Sufficient tokens: " <> tshow sufficientTokens guard sufficientTokens - + liftAct $ do res <- act doSet res @@ -285,7 +285,7 @@ memcachedLimited :: forall a m. -> m a -> m (Maybe a) memcachedLimited burst rate tokens mExp = memcachedLimitedWith (memcachedGet, memcachedSet mExp) lift (Proxy @a) burst rate tokens - + memcachedLimitedKey :: forall a k' m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -300,7 +300,7 @@ memcachedLimitedKey :: forall a k' m. -> m a -> m (Maybe a) memcachedLimitedKey lK burst rate tokens mExp = memcachedLimitedWith (memcachedGet, memcachedSet mExp) lift lK burst rate tokens - + memcachedLimitedBy :: forall a k m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -315,7 +315,7 @@ memcachedLimitedBy :: forall a k m. -> m a -> m (Maybe a) memcachedLimitedBy burst rate tokens mExp k = memcachedLimitedWith (memcachedByGet k, memcachedBySet mExp k) lift (Proxy @a) burst rate tokens - + memcachedLimitedKeyBy :: forall a k' k m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -337,7 +337,7 @@ memcachedLimitedHere :: Q Exp memcachedLimitedHere = do loc <- location [e| \burst rate tokens mExp -> fmap (fmap unMemcachedUnkeyedLoc) . memcachedLimitedBy burst rate tokens mExp loc . fmap MemcachedUnkeyedLoc |] - + memcachedLimitedKeyHere :: Q Exp memcachedLimitedKeyHere = do loc <- location @@ -347,7 +347,7 @@ memcachedLimitedByHere :: Q Exp memcachedLimitedByHere = do loc <- location [e| \burst rate tokens mExp k -> fmap (fmap unMemcachedKeyedLoc) . memcachedLimitedBy burst rate tokens mExp (loc, k) . fmap MemcachedKeyedLoc |] - + memcachedLimitedKeyByHere :: Q Exp memcachedLimitedKeyByHere = do loc <- location @@ -357,7 +357,7 @@ memcachedLimitedKeyByHere = do data AsyncTimeoutException = AsyncTimeoutReturnTypeDoesNotMatchComputationKey deriving (Show, Typeable) deriving anyclass (Exception) - + data DynamicAsync = forall a. DynamicAsync !(TypeRep a) !(Async a) instance Eq DynamicAsync where @@ -389,9 +389,9 @@ liftAsyncTimeout dt (hashableDynamic -> cK) act = ifNotM memcachedAvailable (lif Nothing -> do startAct <- liftIO newEmptyTMVarIO act' <- async $ do - $logDebugS "liftAsyncTimeout" $ "Waiting for confirmation..." + $logDebugS "liftAsyncTimeout" "Waiting for confirmation..." atomically $ takeTMVar startAct - $logDebugS "liftAsyncTimeout" $ "Confirmed." + $logDebugS "liftAsyncTimeout" "Confirmed." act act'' <- atomically $ do hm <- readTVar memcachedAsync @@ -406,7 +406,7 @@ liftAsyncTimeout dt (hashableDynamic -> cK) act = ifNotM memcachedAvailable (lif State.put old return $ Just old' Nothing -> return $ Just new - + (hm', act'') <- runStateT (HashMap.alterF go cK hm) act' writeTVar memcachedAsync $! hm' return act'' @@ -460,7 +460,7 @@ memcachedTimeoutBy mExp dt cK k = memcachedTimeoutWith (memcachedByGet k, memcac memcachedTimeoutHere :: Q Exp memcachedTimeoutHere = do loc <- location - [e| \mExp dt cK -> fmap unMemcachedUnkeyedLoc . memcachedTimeoutBy mExp dt cK loc . fmap MemcachedUnkeyedLoc |] + [e| \mExp dt cK -> fmap unMemcachedUnkeyedLoc . memcachedTimeoutBy mExp dt cK loc . fmap MemcachedUnkeyedLoc |] memcachedTimeoutByHere :: Q Exp memcachedTimeoutByHere = do @@ -483,7 +483,7 @@ memcachedLimitedTimeout :: forall a k'' m. -> m a -> m (Maybe a) memcachedLimitedTimeout burst rate tokens mExp dt cK = memcachedLimitedWith (memcachedGet, memcachedSet mExp) (liftAsyncTimeout dt cK) (Proxy @a) burst rate tokens - + memcachedLimitedKeyTimeout :: forall a k' k'' m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -502,7 +502,7 @@ memcachedLimitedKeyTimeout :: forall a k' k'' m. -> m a -> m (Maybe a) memcachedLimitedKeyTimeout lK burst rate tokens mExp dt cK = memcachedLimitedWith (memcachedGet, memcachedSet mExp) (liftAsyncTimeout dt cK) lK burst rate tokens - + memcachedLimitedTimeoutBy :: forall a k'' k m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -521,7 +521,7 @@ memcachedLimitedTimeoutBy :: forall a k'' k m. -> m a -> m (Maybe a) memcachedLimitedTimeoutBy burst rate tokens mExp dt cK k = memcachedLimitedWith (memcachedByGet k, memcachedBySet mExp k) (liftAsyncTimeout dt cK) (Proxy @a) burst rate tokens - + memcachedLimitedKeyTimeoutBy :: forall a k' k'' k m. ( MonadHandler m, HandlerSite m ~ UniWorX , MonadThrow m @@ -547,7 +547,7 @@ memcachedLimitedTimeoutHere :: Q Exp memcachedLimitedTimeoutHere = do loc <- location [e| \burst rate tokens mExp dt cK -> fmap (fmap unMemcachedUnkeyedLoc) . memcachedLimitedTimeoutBy burst rate tokens mExp dt cK loc . fmap MemcachedUnkeyedLoc |] - + memcachedLimitedKeyTimeoutHere :: Q Exp memcachedLimitedKeyTimeoutHere = do loc <- location @@ -557,7 +557,7 @@ memcachedLimitedTimeoutByHere :: Q Exp memcachedLimitedTimeoutByHere = do loc <- location [e| \burst rate tokens mExp dt cK k -> fmap (fmap unMemcachedKeyedLoc) . memcachedLimitedTimeoutBy burst rate tokens mExp dt cK (loc, k) . fmap MemcachedKeyedLoc |] - + memcachedLimitedKeyTimeoutByHere :: Q Exp memcachedLimitedKeyTimeoutByHere = do loc <- location diff --git a/src/Handler/Utils/Pandoc.hs b/src/Handler/Utils/Pandoc.hs index 8ee7e2cab..e4f3d49e1 100644 --- a/src/Handler/Utils/Pandoc.hs +++ b/src/Handler/Utils/Pandoc.hs @@ -33,7 +33,7 @@ htmlField' :: MonadLogger m => HtmlFieldKind -> Field m Html htmlField' fieldKind = Field{..} where fieldEnctype = UrlEncoded - + fieldParse (t : _) _ = return . fmap (assertM' $ not . null . renderHtml) . parseMarkdown $ Text.strip t fieldParse [] _ = return $ Right Nothing diff --git a/src/Handler/Utils/Rating.hs b/src/Handler/Utils/Rating.hs index 90d7d0375..4a2d5615b 100644 --- a/src/Handler/Utils/Rating.hs +++ b/src/Handler/Utils/Rating.hs @@ -147,7 +147,7 @@ isRatingFile (takeFileName -> fName) = liftHandler . runMaybeT $ do cryptoIdChars :: Set (CI Char) cryptoIdChars = Set.fromList . map CI.mk $ "uwa" ++ "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" - + isRatingFileName app cID = is _Just $ do [CI.mk -> dWord, number, CI.mk -> extension] <- pure . filter (not . Text.null) . Text.split (not . Char.isAlphaNum) $ Text.pack fName guard $ Text.all (flip Set.member cryptoIdChars . CI.mk) number diff --git a/src/Handler/Utils/Rating/Format.hs b/src/Handler/Utils/Rating/Format.hs index c0059c2f9..fd8ab2fb5 100644 --- a/src/Handler/Utils/Rating/Format.hs +++ b/src/Handler/Utils/Rating/Format.hs @@ -29,8 +29,6 @@ import qualified Data.YAML.Event as YAML.Event import qualified Data.YAML.Token as YAML (Encoding(..)) import Data.YAML.Aeson () -- ToYAML Value -import Data.List (elemIndex) - import Control.Monad.Trans.State.Lazy (evalState) import qualified System.FilePath.Cryptographic as Explicit @@ -49,7 +47,7 @@ data PrettifyState | PrettifyComment deriving (Eq, Ord, Read, Show, Generic, Typeable) - + formatRating :: MsgRendererS UniWorX -> DateTimeFormatter -> CryptoFileNameSubmission -> Rating -> Lazy.ByteString formatRating (MsgRenderer mr) DateTimeFormatter{..} cID Rating{ ratingValues = Rating'{..}, .. } = mconcat [ prettyYAML @@ -57,7 +55,7 @@ formatRating (MsgRenderer mr) DateTimeFormatter{..} cID Rating{ ratingValues = R ] where ensureNewline t = Text.strip t <> "\n" - + uglyYAML = YAML.Event.writeEvents YAML.UTF8 $ concat [ [ YAML.Event.StreamStart , YAML.Event.DocumentStart $ YAML.Event.DirEndMarkerVersion 2 @@ -142,7 +140,7 @@ formatRating (MsgRenderer mr) DateTimeFormatter{..} cID Rating{ ratingValues = R pos1' = min pos1 mLength pos2' = min pos2 mLength in (before <> ann1 <> fromStrict (encodeUtf8 event'') <> fromStrict (encodeUtf8 $ ann2 ws) <> after, pos1') - + transduce :: PrettifyState -> YAML.Event.Event -> ((Text, Text -> Text), PrettifyState) transduce PrettifyInitial YAML.Event.MappingStart{} = (("# " <> mr MsgRatingYAMLMetaComment <> "\n", id), PrettifyMetadata 0) transduce PrettifyInitial _ = ((mempty, id), PrettifyInitial) @@ -195,8 +193,8 @@ instance ns ~ CryptoIDNamespace (CI FilePath) SubmissionId => YAML.FromYAML (May -> ( Rating'{ ratingComment = fromMaybe ratingComment'' ratingComment', .. } , cID ) - - + + parseRating :: MonadCatch m => File -> m (Rating', Maybe CryptoFileNameSubmission) parseRating f@File{ fileContent = Just (fromStrict -> input), .. } = handle onFailure . handle (throwM . RatingParseException) . handleIf isYAMLUnicodeError (\(ErrorCall msg) -> throwM $ RatingYAMLNotUnicode msg) $ do let evStream = YAML.Event.parseEvents input diff --git a/src/Handler/Utils/Rating/Format/Legacy.hs b/src/Handler/Utils/Rating/Format/Legacy.hs index 0bfa93af1..bd523d06a 100644 --- a/src/Handler/Utils/Rating/Format/Legacy.hs +++ b/src/Handler/Utils/Rating/Format/Legacy.hs @@ -54,7 +54,7 @@ formatRating cID Rating{ ratingValues = Rating'{..}, ..} = let , pure $ pretty ratingComment ] in Lazy.Text.encodeUtf8 . (<> "\n") $ displayT doc - + parseRating :: MonadCatch m => File -> m Rating' parseRating File{ fileContent = Just input, .. } = handle (throwM . RatingParseLegacyException) $ do inputText <- either (throwM . RatingNotUnicode) return $ Text.decodeUtf8' input diff --git a/src/Handler/Utils/SchoolLdap.hs b/src/Handler/Utils/SchoolLdap.hs index 782d533c9..b8e9bcbf8 100644 --- a/src/Handler/Utils/SchoolLdap.hs +++ b/src/Handler/Utils/SchoolLdap.hs @@ -10,7 +10,7 @@ import Text.Parsec.Text import qualified Data.CaseInsensitive as CI import qualified Data.Set as Set - + parseLdapSchools :: Text -> Either ParseError (Set (CI Text)) parseLdapSchools = parse pLdapSchools "" @@ -28,4 +28,4 @@ pSegment = do fragStart pack <$> manyTill anyChar (try (lookAhead $ char ',' >> fragStart) <|> eof) - + diff --git a/src/Handler/Utils/StudyFeatures.hs b/src/Handler/Utils/StudyFeatures.hs index a138fc69c..52d59082f 100644 --- a/src/Handler/Utils/StudyFeatures.hs +++ b/src/Handler/Utils/StudyFeatures.hs @@ -16,7 +16,7 @@ parseStudyFeatures :: UserId -> UTCTime -> Text -> Either ParseError [StudyFeatu parseStudyFeatures uId now = parse (pStudyFeatures uId now <* eof) (unpack key) where Ldap.Attr key = ldapUserStudyFeatures - + parseSubTermsSemester :: Text -> Either ParseError (StudyTermsId, Int) parseSubTermsSemester = parse (pLMUTermsSemester <* eof) (unpack key) where @@ -44,7 +44,7 @@ pStudyFeatures studyFeaturesUser studyFeaturesUpdated = do return StudyFeatures{..} pStudyFeature `sepBy1` char '#' - + pKey :: Parser Int pKey = decimal diff --git a/src/Handler/Utils/Submission.hs b/src/Handler/Utils/Submission.hs index e29f9ce50..a63686f84 100644 --- a/src/Handler/Utils/Submission.hs +++ b/src/Handler/Utils/Submission.hs @@ -169,7 +169,7 @@ planSubmissions sid restriction = do targetSubmissionData = set _1 Nothing <$> Map.restrictKeys submissionData targetSubmissions oldSubmissionData = Map.withoutKeys submissionData targetSubmissions - whenIsJust (fromNullable =<< fmap (`Set.difference` targetSubmissions) restriction) $ \missing -> + whenIsJust (fromNullable . (`Set.difference` targetSubmissions) =<< restriction) $ \missing -> throwM $ SubmissionsNotFound missing let @@ -236,7 +236,7 @@ planSubmissions sid restriction = do | otherwise = Map.keysSet $ Map.filter (views _byProportion (/= 0)) sheetCorrectors - when (not $ null acceptableCorrectors) $ do + unless (null acceptableCorrectors) $ do deficits <- sequence . flip Map.fromSet acceptableCorrectors $ withSubmissionData . calculateDeficit let bestCorrectors :: Set UserId @@ -570,7 +570,7 @@ sinkSubmission userId mExists isUpdate = do sinkSubmission' :: SubmissionId -> ConduitT SubmissionContent Void (YesodJobDB UniWorX) () sinkSubmission' submissionId = lift . finalize <=< execStateLC mempty . Conduit.mapM_ $ \case - Left file@(FileReference{..}) -> do + Left file@FileReference{..} -> do $logDebugS "sinkSubmission" . tshow $ (submissionId, fileReferenceTitle) alreadySeen <- gets (Set.member fileReferenceTitle . sinkFilenames) @@ -587,7 +587,7 @@ sinkSubmission userId mExists isUpdate = do , submissionFileIsUpdate sf == isUpdate ] underlyingFiles = [ t | t@(Entity _ sf) <- otherVersions - , submissionFileIsUpdate sf == False + , not (submissionFileIsUpdate sf) ] anyChanges | not (null collidingFiles) = any (/~ file) [ view (_FileReference . _1) sf | Entity _ sf <- collidingFiles ] @@ -654,7 +654,7 @@ sinkSubmission userId mExists isUpdate = do -- -- 'fileModified' is simply stored and never inspected while -- 'submissionChanged' is always set to @now@. - let anyChanges = any (\f -> f submission submission') $ + let anyChanges = any (\f -> f submission submission') [ (/=) `on` submissionRatingPoints , (/=) `on` submissionRatingComment , (/=) `on` submissionRatingDone @@ -665,13 +665,13 @@ sinkSubmission userId mExists isUpdate = do touchSubmission Sheet{..} <- lift . getJust $ submissionSheet submission' - + mapM_ (throwM . RatingSubmissionException cID . RatingValidityException) $ validateRating sheetType r' when (submissionRatingDone submission' && not (submissionRatingDone submission)) $ tellSt mempty { sinkSubmissionNotifyRating = Any True } lift $ replace submissionId submission' - sheetId <- lift $ getSheetId + sheetId <- lift getSheetId lift $ audit $ TransactionSubmissionEdit submissionId sheetId where a /~ b = not $ a ~~ b @@ -695,16 +695,16 @@ sinkSubmission userId mExists isUpdate = do touchSubmission :: StateT SubmissionSinkState (YesodJobDB UniWorX) () touchSubmission = do alreadyTouched <- gets $ getAny . sinkSubmissionTouched - when (not alreadyTouched) $ do + unless alreadyTouched $ do now <- liftIO getCurrentTime - case isUpdate of - False -> lift . insert_ $ SubmissionEdit userId now submissionId - True -> do - Submission{submissionRatingTime} <- lift $ getJust submissionId - when (is _Just submissionRatingTime) $ - lift $ update submissionId [ SubmissionRatingTime =. Just now ] + if + | isUpdate -> do + Submission{submissionRatingTime} <- lift $ getJust submissionId + when (is _Just submissionRatingTime) $ + lift $ update submissionId [ SubmissionRatingTime =. Just now ] + | otherwise -> lift . insert_ $ SubmissionEdit userId now submissionId tellSt $ mempty{ sinkSubmissionTouched = Any True } - + getSheetId :: MonadIO m => ReaderT SqlBackend m SheetId getSheetId = case mExists of Left shid @@ -716,15 +716,36 @@ sinkSubmission userId mExists isUpdate = do finalize SubmissionSinkState{..} = do missingFiles <- E.select . E.from $ \sf -> E.distinctOnOrderBy [E.asc $ sf E.^. SubmissionFileTitle] $ do E.where_ $ sf E.^. SubmissionFileSubmission E.==. E.val submissionId - when (not isUpdate) $ + unless isUpdate $ E.where_ . E.not_ $ sf E.^. SubmissionFileIsUpdate E.where_ $ sf E.^. SubmissionFileTitle `E.notIn` E.valList (Set.toList sinkFilenames) E.orderBy [E.desc $ sf E.^. SubmissionFileIsUpdate] return sf - case isUpdate of - False -> do + if + | isUpdate -> forM_ missingFiles $ \(Entity sfId SubmissionFile{..}) -> do + shadowing <- existsBy $ UniqueSubmissionFile submissionFileSubmission submissionFileTitle False + + if + | not shadowing -> do + delete sfId + audit $ TransactionSubmissionFileDelete sfId submissionId + | submissionFileIsUpdate -> do + update sfId [ SubmissionFileContent =. Nothing, SubmissionFileIsDeletion =. True ] + audit $ TransactionSubmissionFileEdit sfId submissionId + | otherwise -> do + now <- liftIO getCurrentTime + sfId' <- insert $ SubmissionFile + { submissionFileSubmission = submissionId + , submissionFileTitle + , submissionFileModified = now + , submissionFileContent = Nothing + , submissionFileIsUpdate = True + , submissionFileIsDeletion = True + } + audit $ TransactionSubmissionFileEdit sfId' submissionId + | otherwise -> do shadowed <- selectKeysList [ SubmissionFileSubmission ==. submissionId , SubmissionFileIsUpdate ==. False @@ -733,27 +754,6 @@ sinkSubmission userId mExists isUpdate = do forM_ shadowed $ \sfId' -> do delete sfId' audit $ TransactionSubmissionFileDelete sfId' submissionId - True -> forM_ missingFiles $ \(Entity sfId SubmissionFile{..}) -> do - shadowing <- existsBy $ UniqueSubmissionFile submissionFileSubmission submissionFileTitle False - - if - | not shadowing -> do - delete sfId - audit $ TransactionSubmissionFileDelete sfId submissionId - | submissionFileIsUpdate -> do - update sfId [ SubmissionFileContent =. Nothing, SubmissionFileIsDeletion =. True ] - audit $ TransactionSubmissionFileEdit sfId submissionId - | otherwise -> do - now <- liftIO getCurrentTime - sfId' <- insert $ SubmissionFile - { submissionFileSubmission = submissionId - , submissionFileTitle - , submissionFileModified = now - , submissionFileContent = Nothing - , submissionFileIsUpdate = True - , submissionFileIsDeletion = True - } - audit $ TransactionSubmissionFileEdit sfId' submissionId if | isUpdate @@ -829,7 +829,7 @@ sinkMultiSubmission userId isUpdate = do | otherwise = return Nothing Dual (Alt msId) <- lift . flip foldMapM segments' $ \seg -> Dual . Alt <$> lift (tryDecrypt seg) `catches` [ E.Handler handleCryptoID, E.Handler (handleHCError $ Right fileReferenceTitle) ] return (msId, fp) - (msId, (joinPath -> fileTitle')) <- foldM acc (Nothing, []) $ splitDirectories fileReferenceTitle + (msId, joinPath -> fileTitle') <- foldM acc (Nothing, []) $ splitDirectories fileReferenceTitle case msId of Nothing -> do $logDebugS "sinkMultiSubmission" $ "Dropping " <> tshow (splitDirectories fileReferenceTitle, msId, fileTitle') @@ -838,7 +838,7 @@ sinkMultiSubmission userId isUpdate = do cID <- encrypt sId lift . handle (throwM . SubmissionSinkException cID (Just fileReferenceTitle)) $ feed sId $ Left f{ fileReferenceTitle = fileTitle' } - when (not $ null ignoredFiles) $ do + unless (null ignoredFiles) $ do mr <- (toHtml .) <$> getMessageRender addMessage Warning =<< withUrlRenderer ($(ihamletFile "templates/messages/submissionFilesIgnored.hamlet") mr) lift . fmap Set.fromList . forM (Map.toList sinks) $ \(sId, sink) -> do @@ -899,7 +899,7 @@ submissionDeleteRoute drRecords = DeleteRoute uid <- maybeAuthId subUsers <- selectList [SubmissionUserSubmission ==. subId] [] if - | length subUsers >= 1 + | not $ null subUsers , maybe True (flip any subUsers . (. submissionUserUser . entityVal) . (/=)) uid -> Just <$> messageI Warning (MsgSubmissionDeleteCosubmittorsWarning $ length infos) | otherwise diff --git a/src/Handler/Utils/Table.hs b/src/Handler/Utils/Table.hs index bf4ca6f13..65880ae92 100644 --- a/src/Handler/Utils/Table.hs +++ b/src/Handler/Utils/Table.hs @@ -1,7 +1,7 @@ module Handler.Utils.Table ( module Handler.Utils.Table ) where - + import Handler.Utils.Table.Pagination as Handler.Utils.Table import Handler.Utils.Table.Columns as Handler.Utils.Table import Handler.Utils.Table.Cells as Handler.Utils.Table diff --git a/src/Handler/Utils/Table/Columns.hs b/src/Handler/Utils/Table/Columns.hs index a586fedfd..df7916e2c 100644 --- a/src/Handler/Utils/Table/Columns.hs +++ b/src/Handler/Utils/Table/Columns.hs @@ -120,7 +120,7 @@ colSchoolShort resultSsh = Colonnade.singleton (fromSortable header) body sortSchoolShort :: OpticSortColumn SchoolId sortSchoolShort querySsh = singletonMap "school-short" . SortColumn $ view querySsh - + colSchoolName :: OpticColonnade SchoolName colSchoolName resultSn = Colonnade.singleton (fromSortable header) body where @@ -129,7 +129,7 @@ colSchoolName resultSn = Colonnade.singleton (fromSortable header) body sortSchoolName :: OpticSortColumn SchoolName sortSchoolName querySn = singletonMap "school-name" . SortColumn $ view querySn - + fltrSchool :: OpticFilterColumn t SchoolId fltrSchool querySsh = singletonMap "school" . FilterColumn $ mkExactFilter (view querySsh) @@ -294,7 +294,7 @@ colCourseName resultName = Colonnade.singleton (fromSortable header) body sortCourseName :: OpticSortColumn CourseName sortCourseName queryName = singletonMap "course-name" . SortColumn $ view queryName - + ------------------------- -- Course Applications -- ------------------------- @@ -302,8 +302,8 @@ sortCourseName queryName = singletonMap "course-name" . SortColumn $ view queryN colApplicationId :: OpticColonnade CourseApplicationId colApplicationId resultId = Colonnade.singleton (fromSortable header) body where - header = Sortable Nothing (i18nCell MsgCourseApplicationId) - body = views resultId $ cell . (toWidget . toMarkup =<<) . (encrypt :: CourseApplicationId -> WidgetFor UniWorX CryptoFileNameCourseApplication) + header = Sortable Nothing $ i18nCell MsgCourseApplicationId + body = views resultId $ \aId -> cell $ toWidget . toMarkup =<< (encrypt :: CourseApplicationId -> WidgetFor UniWorX CryptoFileNameCourseApplication) aId colApplicationRatingPoints :: OpticColonnade (Maybe ExamGrade) colApplicationRatingPoints resultPoints = Colonnade.singleton (fromSortable header) body @@ -377,7 +377,7 @@ colApplicationFiles resultInfo = Colonnade.singleton (fromSortable header) body return $ CApplicationR tid ssh csh cID CAFilesR | otherwise -> mempty - + sortApplicationFiles :: OpticSortColumn Bool sortApplicationFiles queryFiles = singletonMap "has-files" . SortColumn $ view queryFiles @@ -567,7 +567,7 @@ fltrUserMatriculation queryMatriculation = singletonMap "user-matriculation" . F fltrUserMatriculationUI :: DBFilterUI fltrUserMatriculationUI mPrev = prismAForm (singletonFilter "user-matriculation") mPrev $ aopt textField (fslI MsgUserMatriculation) - + colUserMatriclenr :: (IsDBTable m c, HasUser a) => Colonnade Sortable a (DBCell m c) colUserMatriclenr = sortable (Just "user-matriclenumber") (i18nCell MsgMatrikelNr) cellHasMatrikelnummer @@ -781,8 +781,8 @@ fltrDegreeUI mPrev = ----------------- -- Allocations -- ----------------- - -colAllocationApplied :: OpticColonnade Int + +colAllocationApplied :: OpticColonnade Int colAllocationApplied resultApplied = Colonnade.singleton (fromSortable header) body where header = Sortable (Just "applied") (i18nCell MsgAllocationUsersApplied) @@ -790,7 +790,7 @@ colAllocationApplied resultApplied = Colonnade.singleton (fromSortable header) b sortAllocationApplied :: forall applied. PersistField applied => OpticSortColumn applied sortAllocationApplied queryApplied = singletonMap "applied" . SortColumn $ view queryApplied - + colAllocationAssigned :: OpticColonnade Int colAllocationAssigned resultAssigned = Colonnade.singleton (fromSortable header) body where @@ -823,7 +823,7 @@ colAllocationPriority resultPriority = Colonnade.singleton (fromSortable header) where header = Sortable (Just "priority") (i18nCell MsgAllocationUsersPriority) body = views resultPriority $ \priority -> cell $(widgetFile "table/cell/allocation-priority") - + sortAllocationPriority :: OpticSortColumn (Maybe AllocationPriority) sortAllocationPriority queryPriority = singletonMap "priority" . SortColumns . views queryPriority . (. IE.veryUnsafeCoerceSqlExprValue) $ \prio -> [ SomeExprValue (prio E.->. "priorities" :: E.JSONBExpr Void) @@ -855,7 +855,7 @@ anchorColonnade :: forall h r' m a url. -> Colonnade h r' (DBCell m a) anchorColonnade = anchorColonnadeM . (return .) - + anchorColonnadeM :: forall h r' m a url. ( HasRoute UniWorX url , IsDBTable m a @@ -879,7 +879,7 @@ maybeAnchorColonnade :: forall h r' m a url. -> Colonnade h r' (DBCell m a) -> Colonnade h r' (DBCell m a) maybeAnchorColonnade = maybeAnchorColonnadeM . (hoistMaybe .) - + maybeAnchorColonnadeM :: forall h r' m a url. ( HasRoute UniWorX url , IsDBTable m a @@ -893,7 +893,7 @@ maybeAnchorColonnadeM mkUrl = imapColonnade anchorColonnade' anchorColonnade' :: r' -> DBCell m a -> DBCell m a anchorColonnade' inp (view dbCell -> (attrs, act)) = review dbCell . (attrs,) $ view (dbCell . _2) . maybeAnchorCellM (mkUrl inp) =<< act - + emptyOpticColonnade :: forall h r' focus c. Monoid c => Getting (Endo [focus]) r' focus -- ^ View on @focus@ within @r'@ that may produce any number of results @@ -914,7 +914,7 @@ emptyOpticColonnade' defC l' c where l :: Fold r' focus l = folding (toListOf l') - + Colonnade oldColonnade = c $ singular l -- This is safe (as long as we don't evaluate the `oneColonnadeEncode`s) -- because `Getter s a` is of kind @k -> *@ and can thus only be inspected @@ -922,7 +922,7 @@ emptyOpticColonnade' defC l' c -- and the definition of `OneColonnade` defaultColumn :: r' -> (r' -> c) -> c - defaultColumn x f + defaultColumn x f | has l x = f x | otherwise = defC diff --git a/src/Handler/Utils/Table/Pagination.hs b/src/Handler/Utils/Table/Pagination.hs index 872223892..06c7666b4 100644 --- a/src/Handler/Utils/Table/Pagination.hs +++ b/src/Handler/Utils/Table/Pagination.hs @@ -92,7 +92,7 @@ import Colonnade.Encode hiding (row) import Text.Hamlet (hamletFile) -import Data.List (elemIndex, inits) +import Data.List (inits) import Data.Maybe (fromJust) diff --git a/src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs b/src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs index cf1c76323..6f2f22496 100644 --- a/src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs +++ b/src/Handler/Utils/Table/Pagination/CsvColumnExplanations.hs @@ -47,7 +47,7 @@ instance (GCsvColumnsExplained a, GCsvColumnsExplained b) => GCsvColumnsExplaine gCsvColumnsExplanations opts _ = Map.unionWithKey (\h f1 f2 -> error $ "Column header ‘" ++ B8.unpack h ++ "’ is produced by both ‘" ++ f1 ++ "’ and ‘" ++ f2 ++ "’") (gCsvColumnsExplanations opts (error "proxy" :: a p)) (gCsvColumnsExplanations opts (error "proxy" :: b p)) - + instance GCsvColumnsExplained a => GCsvColumnsExplained (M1 D c a) where gCsvColumnsExplanations opts _ = gCsvColumnsExplanations opts (error "proxy" :: a p) diff --git a/src/Handler/Utils/Table/Pagination/Types.hs b/src/Handler/Utils/Table/Pagination/Types.hs index 7e8141003..b2df222ac 100644 --- a/src/Handler/Utils/Table/Pagination/Types.hs +++ b/src/Handler/Utils/Table/Pagination/Types.hs @@ -43,7 +43,7 @@ instance Headedness Sortable where instance Functor Sortable where fmap f Sortable{..} = Sortable { sortableContent = f sortableContent, .. } - + newtype SortableP s = SortableP { toSortable :: forall a. s a -> Sortable a} class Headedness s => ToSortable s where diff --git a/src/Handler/Utils/TermCandidates.hs b/src/Handler/Utils/TermCandidates.hs index 7d49f451f..5ddb8f77b 100644 --- a/src/Handler/Utils/TermCandidates.hs +++ b/src/Handler/Utils/TermCandidates.hs @@ -259,7 +259,7 @@ acceptSingletonParents = do { studySubTermsChild = StudyTermsKey' key , studySubTermsParent = StudyTermsKey' parent } - + mapM getJustEntity $ catMaybes inserted diff --git a/src/Handler/Utils/Users.hs b/src/Handler/Utils/Users.hs index be010ee94..b0aa61ce1 100644 --- a/src/Handler/Utils/Users.hs +++ b/src/Handler/Utils/Users.hs @@ -74,7 +74,7 @@ guessUser (Set.toList -> criteria) = $cachedHereBinary criteria $ go False asWords = filter (not . Text.null) . Text.words . Text.strip containsAsSet x y = E.and . map (\y' -> x `E.hasInfix` E.val y') $ asWords y - + toSql user = \case GuessUserMatrikelnummer userMatriculation' -> user E.^. UserMatrikelnummer E.==. E.val (Just userMatriculation') GuessUserDisplayName userDisplayName' -> user E.^. UserDisplayName `containsAsSet` userDisplayName' @@ -83,7 +83,7 @@ guessUser (Set.toList -> criteria) = $cachedHereBinary criteria $ go False go didLdap = do let retrieveUsers = E.select . E.from $ \user -> do - E.where_ . E.and $ map (toSql user) criteria + E.where_ . E.and $ map (toSql user) criteria return user users <- retrieveUsers let users' = sortBy (flip closeness) users @@ -106,11 +106,11 @@ guessUser (Set.toList -> criteria) = $cachedHereBinary criteria $ go False for ldapData $ upsertCampusUser UpsertCampusUser if - | x@(Entity pid _) : [] <- users' - , fromMaybe False (matchesMatriculation x) || didLdap + | [x@(Entity pid _)] <- users' + , Just True == matchesMatriculation x || didLdap -> return $ Just pid | x@(Entity pid _) : x' : _ <- users' - , fromMaybe False (matchesMatriculation x) || didLdap + , Just True == matchesMatriculation x || didLdap , GT <- x `closeness` x' -> return $ Just pid | not didLdap diff --git a/src/Handler/Utils/Widgets.hs b/src/Handler/Utils/Widgets.hs index 1e1f1ea76..bc8f527b6 100644 --- a/src/Handler/Utils/Widgets.hs +++ b/src/Handler/Utils/Widgets.hs @@ -100,7 +100,7 @@ heat :: ( Real a, Real b ) -- ^ Distinguishes @full@, zero is mapped to 1, @full@ is mapped to 0 heat (realToFrac -> full) (realToFrac -> achieved) = fromRational $ cutOffCoPercent 0.3 (full^2) (achieved^2) - + invHeat :: ( Real a, Real b ) => a -> b -> Milli -- ^ Distinguishes @full@, zero is mapped to 0, @full@ is mapped to 1 @@ -110,7 +110,7 @@ coHeat :: ( Real a, Real b) => a -> b -> Milli -- ^ Distinguishes zero, zero is mapped to 1, @full@ is mapped to 0 coHeat full achieved = 1 - invCoHeat full achieved - + invCoHeat :: ( Real a, Real b) => a -> b -> Milli -- ^ Distinguishes zero, zero is mapped to 0, @full@ is mapped to 1 @@ -142,7 +142,7 @@ invDualHeat :: ( Real a, Real b, Real c ) => a -> b -> c -> Milli -- ^ Distinguishes zero, zero is mapped to 2, @optimal@ is mapped to 1, @full@ is mapped to 0 invDualHeat optimal full achieved = 2 - dualHeat optimal full achieved - + invDualCoHeat :: ( Real a, Real b, Real c ) => a -> b -> c -> Milli -- ^ Distinguishes @full@, zero is mapped to 2, @optimal@ is mapped to 1, @full@ is mapped to 0 diff --git a/src/Handler/Utils/Zip.hs b/src/Handler/Utils/Zip.hs index 0d30778c8..255d8f93b 100644 --- a/src/Handler/Utils/Zip.hs +++ b/src/Handler/Utils/Zip.hs @@ -113,7 +113,7 @@ produceZip info = C.map toZipData .| transPipe liftBase (void $ zipStream zipOpt toZipEntry File{..} = ZipEntry{..} where isDir = isNothing fileContent - + zipEntryName = encodeZipEntryName . bool (dropWhileEnd isPathSeparator) addTrailingPathSeparator isDir . normalise $ makeValid fileTitle zipEntryTime = utcToLocalTime utc fileModified zipEntrySize = Nothing @@ -141,7 +141,7 @@ acceptFile fInfo = do fileContent <- fmap Just . runConduit $ fileSource fInfo .| foldC return File{..} - + decodeZipEntryName :: MonadThrow m => Either Text ByteString -> m FilePath -- ^ Extract the filename from a 'ZipEntry' doing decoding along the way. -- @@ -149,7 +149,7 @@ decodeZipEntryName :: MonadThrow m => Either Text ByteString -> m FilePath decodeZipEntryName = \case Left t -> return $ unpack t Right cp437 -> either throwM return $ decodeStrictByteStringExplicit CP437 cp437 - + encodeZipEntryName :: FilePath -> Either Text ByteString -- ^ Encode a filename for use in a 'ZipEntry', encodes as -- 'Data.Encoding.UTF8.UTF8' iff the given path contains non-ascii characters. diff --git a/src/Import/NoFoundation.hs b/src/Import/NoFoundation.hs index 1e3925395..0fdedc192 100644 --- a/src/Import/NoFoundation.hs +++ b/src/Import/NoFoundation.hs @@ -20,6 +20,6 @@ import Settings.WellKnownFiles as Import import CryptoID as Import import Audit as Import - + import Web.ServerSession.Backend.Persistent.Memcached as Import import Web.ServerSession.Backend.Acid as Import (AcidStorage(..)) diff --git a/src/Import/NoModel.hs b/src/Import/NoModel.hs index d7a71dce2..846bb5c00 100644 --- a/src/Import/NoModel.hs +++ b/src/Import/NoModel.hs @@ -60,6 +60,7 @@ import GHC.Exts as Import (IsList) import Data.Ix as Import (Ix) import Data.Hashable as Import +import Data.List as Import (elemIndex) import Data.List.NonEmpty as Import (NonEmpty(..), nonEmpty) import Data.Text.Encoding.Error as Import(UnicodeException(..)) import Data.Semigroup as Import (Min(..), Max(..)) @@ -78,6 +79,8 @@ import Database.Persist.Sql as Import (SqlReadBackend, SqlReadT, SqlWriteT, IsSq import Ldap.Client.Pool as Import +import Control.Monad as Import (zipWithM) + import System.Random as Import (Random(..)) import Control.Monad.Random.Class as Import (MonadRandom(..)) diff --git a/src/Jobs.hs b/src/Jobs.hs index bdf6b847f..314e68679 100644 --- a/src/Jobs.hs +++ b/src/Jobs.hs @@ -492,7 +492,7 @@ jLocked jId act = do liftIO . atomically $ writeTVar hasLock True return val - unlock = whenM (liftIO . atomically $ readTVar hasLock) $ + unlock = whenM (readTVarIO hasLock) $ runDB . setSerializable $ update jId [ QueuedJobLockInstance =. Nothing , QueuedJobLockTime =. Nothing diff --git a/src/Jobs/Crontab.hs b/src/Jobs/Crontab.hs index 2a801ff79..4a9b269a4 100644 --- a/src/Jobs/Crontab.hs +++ b/src/Jobs/Crontab.hs @@ -4,7 +4,7 @@ module Jobs.Crontab ( determineCrontab ) where -import Import +import Import import qualified Data.HashMap.Strict as HashMap import Jobs.Types @@ -48,7 +48,7 @@ determineCrontab = execWriterT $ do , cronRateLimit = appJobCronInterval , cronNotAfter = Right CronNotScheduled } - whenIsJust appPruneUnreferencedFiles $ \pInterval -> + whenIsJust appPruneUnreferencedFiles $ \pInterval -> tell $ HashMap.singleton (JobCtlQueue JobPruneUnreferencedFiles) Cron @@ -57,7 +57,7 @@ determineCrontab = execWriterT $ do , cronRateLimit = pInterval , cronNotAfter = Right CronNotScheduled } - + oldestInvitationMUTC <- lift $ preview (_head . _entityVal . _invitationExpiresAt . _Just) <$> selectList [InvitationExpiresAt !=. Nothing] [Asc InvitationExpiresAt, LimitTo 1] whenIsJust oldestInvitationMUTC $ \oldestInvUTC -> tell $ HashMap.singleton (JobCtlQueue JobPruneInvitations) @@ -88,7 +88,7 @@ determineCrontab = execWriterT $ do , cronNotAfter = Right CronNotScheduled } - tell . flip foldMap universeF $ \kind -> + tell . flip foldMap universeF $ \kind -> case appHealthCheckInterval kind of Just int -> HashMap.singleton (JobCtlGenerateHealthReport kind) @@ -137,7 +137,7 @@ determineCrontab = execWriterT $ do let epochInterval = syncWithin / 2 interval = appSynchroniseLdapUsersInterval - + (ldapEpoch, epochNow) = now `divMod'` epochInterval ldapInterval = epochNow `div'` interval numIntervals = floor $ epochInterval / interval @@ -168,11 +168,11 @@ determineCrontab = execWriterT $ do } | otherwise -> return () - + let sheetJobs (Entity nSheet Sheet{..}) = do - for_ (max <$> sheetVisibleFrom <*> sheetActiveFrom) $ \aFrom -> + for_ (max <$> sheetVisibleFrom <*> sheetActiveFrom) $ \aFrom -> tell $ HashMap.singleton (JobCtlQueue $ JobQueueNotification NotificationSheetActive{..}) Cron @@ -222,7 +222,7 @@ determineCrontab = execWriterT $ do , cronRepeat = CronRepeatOnChange , cronRateLimit = appNotificationRateLimit , cronNotAfter = Left appNotificationExpiration - } + } when sheetAutoDistribute $ tell $ HashMap.singleton (JobCtlQueue $ JobDistributeCorrections nSheet) @@ -239,13 +239,13 @@ determineCrontab = execWriterT $ do correctorNotifications :: Map (UserId, SheetId) (Max UTCTime) -> WriterT (Crontab JobCtl) DB () correctorNotifications = (tell .) . Map.foldMapWithKey $ \(nUser, nSheet) (Max time) -> HashMap.singleton (JobCtlQueue $ JobQueueNotification NotificationCorrectionsAssigned { nUser, nSheet } ) - Cron + Cron { cronInitial = CronTimestamp . utcToLocalTimeTZ appTZ $ addUTCTime appNotificationCollateDelay time , cronRepeat = CronRepeatNever , cronRateLimit = appNotificationRateLimit , cronNotAfter = Left appNotificationExpiration } - + submissionsByCorrector :: Entity Submission -> Map (UserId, SheetId) (Max UTCTime) submissionsByCorrector (Entity _ sub) | Just ratingBy <- submissionRatingBy sub @@ -261,7 +261,7 @@ determineCrontab = execWriterT $ do ) .| C.fold collateSubmissionsByCorrector Map.empty - + let examJobs (Entity nExam Exam{..}) = do newestResult <- lift . E.select . E.from $ \examResult -> do @@ -270,7 +270,7 @@ determineCrontab = execWriterT $ do whenIsJust examVisibleFrom $ \visibleFrom -> do case over (mapped . _Value) ((max `on` NTop) examFinished) newestResult of - [E.Value (NTop (Just ts))] -> + [E.Value (NTop (Just ts))] -> tell $ HashMap.singleton (JobCtlQueue $ JobQueueNotification NotificationExamResult{..}) Cron @@ -338,10 +338,10 @@ determineCrontab = execWriterT $ do , cronNotAfter = Left appNotificationExpiration } Nothing -> return () - + runConduit $ transPipe lift (selectSource [] []) .| C.mapM_ examJobs - + let externalExamJobs nExternalExam = do newestResult <- lift . E.select . E.from $ \externalExamResult -> do diff --git a/src/Jobs/Handler/Files.hs b/src/Jobs/Handler/Files.hs index de85244c0..77e6337e2 100644 --- a/src/Jobs/Handler/Files.hs +++ b/src/Jobs/Handler/Files.hs @@ -14,7 +14,7 @@ import qualified Database.Esqueleto.Internal.Sql as E (unsafeSqlCastAs) import qualified Data.Conduit.Combinators as C import qualified Data.Conduit.List as C (mapMaybe) - + import Handler.Utils.Minio import qualified Network.Minio as Minio @@ -32,7 +32,7 @@ dispatchJobPruneSessionFiles = JobHandlerAtomic . hoist lift $ do $logInfoS "PruneSessionFiles" [st|Deleted #{n} expired session files|] - + fileReferences :: E.SqlExpr (E.Value FileContentReference) -> [E.SqlQuery ()] fileReferences (E.just -> fHash) = [ E.from $ \appFile -> E.where_ $ appFile E.^. CourseApplicationFileContent E.==. fHash @@ -47,7 +47,7 @@ fileReferences (E.just -> fHash) ] - + dispatchJobPruneUnreferencedFiles :: JobHandler UniWorX dispatchJobPruneUnreferencedFiles = JobHandlerAtomic . hoist lift $ do now <- liftIO getCurrentTime @@ -57,16 +57,16 @@ dispatchJobPruneUnreferencedFiles = JobHandlerAtomic . hoist lift $ do E.update $ \fileContent -> do let isReferenced = E.any E.exists . fileReferences $ fileContent E.^. FileContentHash now' = E.unsafeSqlCastAs "TIMESTAMP WITH TIME ZONE" $ E.val now - shouldBe = E.bool (E.just . E.maybe now' (E.min now') $ fileContent E.^. FileContentUnreferencedSince) E.nothing isReferenced + shouldBe = E.bool (E.just . E.maybe now' (E.min now') $ fileContent E.^. FileContentUnreferencedSince) E.nothing isReferenced E.set fileContent [ FileContentUnreferencedSince E.=. shouldBe ] let getCandidates = E.selectSource . E.from $ \fileContent -> do - E.where_ . E.maybe E.false (E.<. E.val (addUTCTime (-keep) now)) $ fileContent E.^. FileContentUnreferencedSince + E.where_ . E.maybe E.false (E.<. E.val (addUTCTime (-keep) now)) $ fileContent E.^. FileContentUnreferencedSince return ( fileContent E.^. FileContentHash , E.length_ $ fileContent E.^. FileContentContent ) - + Sum deleted <- runConduit $ getCandidates .| maybe (C.map id) (takeWhileTime . (/ 2)) interval @@ -90,7 +90,7 @@ dispatchJobInjectFiles = JobHandlerException . maybeT (return ()) $ do , Just fRef <- Crypto.digestFromByteString bs = Just (oi, fRef) extractReference _ = Nothing - + injectOrDelete :: (Minio.Object, FileContentReference) -> Handler (Sum Int64, Sum Int64) -- ^ Injected, Already existed injectOrDelete (obj, fRef) = maybeT (return mempty) $ do @@ -106,7 +106,7 @@ dispatchJobInjectFiles = JobHandlerException . maybeT (return ()) $ do let isReferenced = E.any E.exists $ fileReferences (E.val fRef) now' = E.unsafeSqlCastAs "TIMESTAMP WITH TIME ZONE" $ E.val now in return $ FileContent E.<# E.val fRef E.<&> E.val content E.<&> E.bool (E.just now') E.nothing isReferenced - runAppMinio . maybeT (return ()) . catchIfMaybeT minioIsDoesNotExist $ Minio.removeObject uploadBucket obj + runAppMinio . maybeT (return ()) . catchIfMaybeT minioIsDoesNotExist $ Minio.removeObject uploadBucket obj return res (Sum inj, Sum exc) <- diff --git a/src/Jobs/Handler/HelpRequest.hs b/src/Jobs/Handler/HelpRequest.hs index ca07dee2b..42ad88d0f 100644 --- a/src/Jobs/Handler/HelpRequest.hs +++ b/src/Jobs/Handler/HelpRequest.hs @@ -10,7 +10,7 @@ import qualified Data.CaseInsensitive as CI import Handler.Utils import Data.Bitraversable - + dispatchJobHelpRequest :: Either (Maybe Address) UserId -> UTCTime @@ -38,10 +38,10 @@ dispatchJobHelpRequest jSender jRequestTime jHelpSubject jHelpRequest jReferer j objId <- setMailObjectIdRandom mr <- getMailMessageRender return . mr $ MsgHelpErrorYamlFilename objId - + addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/support.hamlet") :: HtmlUrlI18n UniWorXMessage (Route UniWorX)) whenIsJust ((,) <$> jError <*> errPartName) $ \(err, partName) -> addPart' $ do toMailPart $ toYAML err _partDisposition .= InlineDisposition partName - + diff --git a/src/Jobs/Handler/QueueNotification.hs b/src/Jobs/Handler/QueueNotification.hs index 29b078816..18d7d3f46 100644 --- a/src/Jobs/Handler/QueueNotification.hs +++ b/src/Jobs/Handler/QueueNotification.hs @@ -133,7 +133,7 @@ determineNotificationCandidates NotificationAllocationStaffRegister{..} = do E.where_ $ userSchool E.^. UserSchoolUser E.==. user E.^. UserId E.&&. userSchool E.^. UserSchoolSchool E.==. E.val allocationSchool E.&&. E.not_ (userSchool E.^. UserSchoolIsOptOut) - + E.where_ . E.not_ . E.exists . E.from $ \(course `E.InnerJoin` lecturer) -> do E.on $ lecturer E.^. LecturerCourse E.==. course E.^. CourseId E.&&. lecturer E.^. LecturerUser E.==. user E.^. UserId @@ -155,7 +155,7 @@ determineNotificationCandidates NotificationAllocationAllocation{..} = E.&&. application E.^. CourseApplicationUser E.!=. user E.^. UserId E.&&. E.not_ (E.isNothing $ application E.^. CourseApplicationRatingTime) - E.where_ . E.exists . E.from $ \application -> + E.where_ . E.exists . E.from $ \application -> E.where_ $ application E.^. CourseApplicationAllocation E.==. E.val (Just nAllocation) E.&&. application E.^. CourseApplicationCourse E.==. course E.^. CourseId E.&&. application E.^. CourseApplicationUser E.!=. user E.^. UserId @@ -167,7 +167,7 @@ determineNotificationCandidates NotificationAllocationUnratedApplications{..} = E.&&. allocationCourse E.^. AllocationCourseAllocation E.==. E.val nAllocation E.on $ course E.^. CourseId E.==. lecturer E.^. LecturerCourse E.on $ lecturer E.^. LecturerUser E.==. user E.^. UserId - + E.where_ . E.exists . E.from $ \application -> E.where_ $ application E.^. CourseApplicationAllocation E.==. E.val (Just nAllocation) E.&&. application E.^. CourseApplicationCourse E.==. course E.^. CourseId @@ -194,7 +194,7 @@ determineNotificationCandidates NotificationAllocationOutdatedRatings{..} = E.&&. allocationCourse E.^. AllocationCourseAllocation E.==. E.val nAllocation E.on $ course E.^. CourseId E.==. lecturer E.^. LecturerCourse E.on $ lecturer E.^. LecturerUser E.==. user E.^. UserId - + E.where_ . E.exists . E.from $ \application -> E.where_ $ application E.^. CourseApplicationAllocation E.==. E.val (Just nAllocation) E.&&. application E.^. CourseApplicationCourse E.==. course E.^. CourseId diff --git a/src/Jobs/Handler/SendNotification/Allocation.hs b/src/Jobs/Handler/SendNotification/Allocation.hs index 9932fef7c..79b40b79e 100644 --- a/src/Jobs/Handler/SendNotification/Allocation.hs +++ b/src/Jobs/Handler/SendNotification/Allocation.hs @@ -18,7 +18,7 @@ import Text.Hamlet import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils as E - + dispatchNotificationAllocationStaffRegister :: AllocationId -> UserId -> Handler () dispatchNotificationAllocationStaffRegister nAllocation jRecipient = userMailT jRecipient $ do @@ -87,7 +87,7 @@ dispatchNotificationAllocationUnratedApplications nAllocation jRecipient = do E.where_ $ application E.^. CourseApplicationCourse E.==. course E.^. CourseId E.&&. application E.^. CourseApplicationAllocation E.==. E.val (Just nAllocation) E.&&. E.isNothing (application E.^. CourseApplicationRatingTime) - + return ( course E.^. CourseTerm , course E.^. CourseSchool , course E.^. CourseShorthand @@ -127,7 +127,7 @@ dispatchNotificationAllocationOutdatedRatings nAllocation jRecipient = do E.where_ $ application E.^. CourseApplicationCourse E.==. course E.^. CourseId E.&&. application E.^. CourseApplicationAllocation E.==. E.val (Just nAllocation) E.&&. E.maybe E.false (E.<. application E.^. CourseApplicationTime) (application E.^. CourseApplicationRatingTime) - + return ( course E.^. CourseTerm , course E.^. CourseSchool , course E.^. CourseShorthand @@ -191,11 +191,11 @@ dispatchNotificationAllocationResults nAllocation jRecipient = userMailT jRecipi [] | doParticipantResults -> Just [] | otherwise -> Nothing cs -> Just $ map (courseShorthand . entityVal) cs - + return (allocation, lecturerResults, participantResults) replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ MsgMailSubjectAllocationResults allocationName editNotifications <- mkEditNotifications jRecipient - + addHtmlMarkdownAlternatives $(ihamletFile "templates/mail/allocationResults.hamlet") diff --git a/src/Jobs/Handler/SendNotification/CorrectionsAssigned.hs b/src/Jobs/Handler/SendNotification/CorrectionsAssigned.hs index 720d5850c..13f66127e 100644 --- a/src/Jobs/Handler/SendNotification/CorrectionsAssigned.hs +++ b/src/Jobs/Handler/SendNotification/CorrectionsAssigned.hs @@ -22,7 +22,7 @@ dispatchNotificationCorrectionsAssigned nUser nSheet jRecipient = do , SubmissionRatingTime ==. Nothing ] return (course, sheet, nbrSubs) - when (nbrSubs > 0) . userMailT jRecipient $ do + when (nbrSubs > 0) . userMailT jRecipient $ do replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ MsgMailSubjectCorrectionsAssigned courseShorthand sheetName diff --git a/src/Jobs/Handler/SendNotification/CorrectionsNotDistributed.hs b/src/Jobs/Handler/SendNotification/CorrectionsNotDistributed.hs index 53282040e..50ba2ad51 100644 --- a/src/Jobs/Handler/SendNotification/CorrectionsNotDistributed.hs +++ b/src/Jobs/Handler/SendNotification/CorrectionsNotDistributed.hs @@ -18,7 +18,7 @@ dispatchNotificationCorrectionsNotDistributed nSheet jRecipient = do , SubmissionRatingBy ==. Nothing ] return (course, sheet, nbrSubs) - when (nbrSubs > 0) . userMailT jRecipient $ do + when (nbrSubs > 0) . userMailT jRecipient $ do replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ MsgMailSubjectSubmissionsUnassigned courseShorthand sheetName MsgRenderer mr <- getMailMsgRenderer diff --git a/src/Jobs/Handler/SendNotification/CourseRegistered.hs b/src/Jobs/Handler/SendNotification/CourseRegistered.hs index 946fa5752..9bfb22ff3 100644 --- a/src/Jobs/Handler/SendNotification/CourseRegistered.hs +++ b/src/Jobs/Handler/SendNotification/CourseRegistered.hs @@ -16,8 +16,8 @@ dispatchNotificationCourseRegistered :: UserId -> CourseId -> UserId -> Handler dispatchNotificationCourseRegistered nUser nCourse jRecipient = userMailT jRecipient $ do (User{..}, Course{..}) <- liftHandler . runDB $ (,) <$> getJust nUser <*> getJust nCourse - let isSelf = nUser == jRecipient - + let isSelf = nUser == jRecipient + replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ if | isSelf -> MsgMailSubjectCourseRegistered courseShorthand diff --git a/src/Jobs/Handler/SendNotification/ExamOffice.hs b/src/Jobs/Handler/SendNotification/ExamOffice.hs index fe3d8df8b..c7a6d1c37 100644 --- a/src/Jobs/Handler/SendNotification/ExamOffice.hs +++ b/src/Jobs/Handler/SendNotification/ExamOffice.hs @@ -16,7 +16,7 @@ import qualified Data.CaseInsensitive as CI import qualified Data.Set as Set - + dispatchNotificationExamOfficeExamResults :: ExamId -> UserId -> Handler () dispatchNotificationExamOfficeExamResults nExam jRecipient = userMailT jRecipient $ do (Course{..}, Exam{..}) <- liftHandler . runDB $ do diff --git a/src/Jobs/Handler/SendNotification/SubmissionEdited.hs b/src/Jobs/Handler/SendNotification/SubmissionEdited.hs index 9a3ccc316..e244c02ab 100644 --- a/src/Jobs/Handler/SendNotification/SubmissionEdited.hs +++ b/src/Jobs/Handler/SendNotification/SubmissionEdited.hs @@ -70,7 +70,7 @@ dispatchNotificationSubmissionUserCreated nUser nSubmission jRecipient = userMai return (user, course, sheet, submission, coSubmittors) - let isSelf = nUser == jRecipient + let isSelf = nUser == jRecipient let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors addMailHeader "Reply-To" allCoSubmittors @@ -91,13 +91,13 @@ dispatchNotificationSubmissionUserCreated nUser nSubmission jRecipient = userMai editNotifications <- mkEditNotifications jRecipient addHtmlMarkdownAlternatives $(ihamletFile "templates/mail/submissionUserCreated.hamlet") - + dispatchNotificationSubmissionUserDeleted :: UserId -> SheetId -> SubmissionId -> UserId -> Handler () dispatchNotificationSubmissionUserDeleted nUser nSheet nSubmission jRecipient = userMailT jRecipient $ do (User{..}, Course{..}, Sheet{..}, mSubmission, coSubmittors) <- liftHandler . runDB $ do submission <- get nSubmission - + sheet <- maybe (getJust nSheet) (belongsToJust submissionSheet) submission course <- belongsToJust sheetCourse sheet @@ -108,10 +108,10 @@ dispatchNotificationSubmissionUserDeleted nUser nSheet nSubmission jRecipient = return user user <- getJust nUser - + return (user, course, sheet, submission, coSubmittors) - let isSelf = nUser == jRecipient + let isSelf = nUser == jRecipient unless (null coSubmittors) $ do let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors diff --git a/src/Jobs/Handler/SendNotification/SubmissionRated.hs b/src/Jobs/Handler/SendNotification/SubmissionRated.hs index 7770c33ad..5d4a78ec8 100644 --- a/src/Jobs/Handler/SendNotification/SubmissionRated.hs +++ b/src/Jobs/Handler/SendNotification/SubmissionRated.hs @@ -21,7 +21,7 @@ dispatchNotificationSubmissionRated nSubmission jRecipient = userMailT jRecipien corrector <- traverse getJust submissionRatingBy return (course, sheet, submission, corrector) - whenIsJust corrector $ \corrector' -> + whenIsJust corrector $ \corrector' -> addMailHeader "Reply-To" . renderAddress $ userAddressFrom corrector' replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI $ MsgMailSubjectSubmissionRated courseShorthand diff --git a/src/Jobs/Handler/SendNotification/Utils.hs b/src/Jobs/Handler/SendNotification/Utils.hs index e60d20cfd..a6eee899b 100644 --- a/src/Jobs/Handler/SendNotification/Utils.hs +++ b/src/Jobs/Handler/SendNotification/Utils.hs @@ -12,7 +12,7 @@ import qualified Data.HashSet as HashSet ihamletSomeMessage :: HtmlUrlI18n UniWorXMessage (Route UniWorX) -> HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX) ihamletSomeMessage f trans = f $ trans . SomeMessage - + mkEditNotifications :: (MonadHandler m, HandlerSite m ~ UniWorX) => UserId -> m (HtmlUrlI18n UniWorXMessage (Route UniWorX)) mkEditNotifications uid = liftHandler $ do cID <- encrypt uid diff --git a/src/Jobs/Handler/SendPasswordReset.hs b/src/Jobs/Handler/SendPasswordReset.hs index ce2aadd93..d5b4c75aa 100644 --- a/src/Jobs/Handler/SendPasswordReset.hs +++ b/src/Jobs/Handler/SendPasswordReset.hs @@ -18,7 +18,7 @@ dispatchJobSendPasswordReset :: UserId dispatchJobSendPasswordReset jRecipient = JobHandlerException . userMailT jRecipient $ do cID <- encrypt jRecipient User{..} <- liftHandler . runDB $ getJust jRecipient - + replaceMailHeader "Auto-Submitted" $ Just "auto-generated" setSubjectI MsgMailSubjectPasswordReset diff --git a/src/Jobs/Handler/SendTestEmail.hs b/src/Jobs/Handler/SendTestEmail.hs index d396cc7c1..711322647 100644 --- a/src/Jobs/Handler/SendTestEmail.hs +++ b/src/Jobs/Handler/SendTestEmail.hs @@ -2,7 +2,7 @@ module Jobs.Handler.SendTestEmail ( dispatchJobSendTestEmail ) where -import Import +import Import import Handler.Utils.Mail import Handler.Utils.DateTime diff --git a/src/Jobs/Handler/SynchroniseLdap.hs b/src/Jobs/Handler/SynchroniseLdap.hs index 14d5e6668..f4bdcf021 100644 --- a/src/Jobs/Handler/SynchroniseLdap.hs +++ b/src/Jobs/Handler/SynchroniseLdap.hs @@ -10,7 +10,7 @@ import qualified Data.Conduit.List as C import Auth.LDAP import Jobs.Queue - + data SynchroniseLdapException = SynchroniseLdapNoLdap @@ -40,7 +40,7 @@ dispatchJobSynchroniseLdapUser :: UserId -> JobHandler UniWorX dispatchJobSynchroniseLdapUser jUser = JobHandlerException $ do UniWorX{..} <- getYesod case appLdapPool of - Just ldapPool -> + Just ldapPool -> runDB . void . runMaybeT . handleExc $ do user@User{userIdent} <- MaybeT $ get jUser diff --git a/src/Jobs/HealthReport.hs b/src/Jobs/HealthReport.hs index 2a96f5096..67ee78717 100644 --- a/src/Jobs/HealthReport.hs +++ b/src/Jobs/HealthReport.hs @@ -33,7 +33,7 @@ import UnliftIO.Concurrent (myThreadId) generateHealthReport :: HealthCheck -> Handler HealthReport generateHealthReport = withHealthReportMetrics . $(dispatchTH ''HealthCheck) - + dispatchHealthCheckMatchingClusterConfig :: Handler HealthReport -- ^ Can the cluster configuration be read from the database and does it match our configuration? dispatchHealthCheckMatchingClusterConfig @@ -63,7 +63,7 @@ dispatchHealthCheckMatchingClusterConfig ourSetting <- getsYesod $ fmap fst . appMemcached dbSetting <- clusterSetting @'ClusterMemcachedKey return $ maybe True ((== dbSetting) . Just) ourSetting - + clusterSetting :: forall key. ( ClusterSetting key @@ -118,7 +118,7 @@ dispatchHealthCheckSMTPConnect = fmap HealthSMTPConnect . yesodTimeout (^. _appH response@(rCode, _) <- liftIO $ SMTP.sendCommand smtpConn SMTP.NOOP case rCode of 250 -> return True - _ -> do + _ -> do $logErrorS "Mail" $ "NOOP failed: " <> tshow response return False @@ -143,7 +143,7 @@ dispatchHealthCheckWidgetMemcached = fmap HealthWidgetMemcached . yesodTimeout ( & HTTP.setRequestManager httpManager' (== content) . responseBody <$> httpLBS httpRequest _other -> return False - + dispatchHealthCheckActiveJobExecutors :: Handler HealthReport dispatchHealthCheckActiveJobExecutors = HealthActiveJobExecutors <$> do diff --git a/src/Jobs/Queue.hs b/src/Jobs/Queue.hs index 18c85be59..b5483a8c6 100644 --- a/src/Jobs/Queue.hs +++ b/src/Jobs/Queue.hs @@ -29,7 +29,7 @@ import Data.Semigroup ((<>)) import UnliftIO.Concurrent (myThreadId) import Control.Monad.Trans.Resource (register) - + data JobQueueException = JobQueuePoolEmpty | JobQueueWorkerNotFound @@ -83,9 +83,9 @@ writeJobCtlBlock = writeJobCtlBlock' writeJobCtl queueJobUnsafe :: Bool -> Job -> YesodDB UniWorX (Maybe QueuedJobId) queueJobUnsafe queuedJobWriteLastExec job = do $logInfoS "queueJob" $ tshow job - + doQueue <- fmap not . and2M (return $ jobNoQueueSame job) $ exists [ QueuedJobContent ==. toJSON job ] - + if | doQueue -> Just <$> do queuedJobCreationTime <- liftIO getCurrentTime @@ -146,5 +146,5 @@ runDBJobs' act = do forM_ jIds $ \jId -> whenM (existsKey jId) $ runReaderT (writeJobCtl $ JobCtlPerform jId) =<< getYesod - + return ret diff --git a/src/Jobs/Types.hs b/src/Jobs/Types.hs index 11fe8b12e..c587bf9b8 100644 --- a/src/Jobs/Types.hs +++ b/src/Jobs/Types.hs @@ -174,7 +174,7 @@ data JobHandler site deriving (Generic, Typeable) makePrisms ''JobHandler - + data JobWorkerState = JobWorkerBusy @@ -215,7 +215,7 @@ showWorkerId = tshow . hashUnique . jobWorkerUnique newWorkerId :: MonadIO m => m JobWorkerId newWorkerId = JobWorkerId <$> liftIO newUnique - + data JobContext = JobContext { jobCrontab :: TVar (Crontab JobCtl) , jobConfirm :: TVar (HashMap JobCtl (NonEmpty (TMVar (Maybe SomeException)))) diff --git a/src/Ldap/Client/Pool.hs b/src/Ldap/Client/Pool.hs index d14289125..c79b7d9de 100644 --- a/src/Ldap/Client/Pool.hs +++ b/src/Ldap/Client/Pool.hs @@ -138,7 +138,7 @@ createLdapPool host port stripes timeoutConn (round . (* 1e6) -> timeoutAct) lim delExecutor LdapExecutor{..} = do atomically . void $ tryPutTMVar ldapDestroy () wait ldapAsync - withRunInIO $ \runInIO -> + withRunInIO $ \runInIO -> createPool (runInIO mkExecutor) delExecutor stripes timeoutConn limit where withTimeout :: forall m' a. (MonadUnliftIO m', MonadThrow m') => m' a -> m' a diff --git a/src/Mail.hs b/src/Mail.hs index 36ae4146d..a446040ff 100644 --- a/src/Mail.hs +++ b/src/Mail.hs @@ -111,7 +111,7 @@ import Control.Monad.Trans.Maybe (MaybeT(..)) import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI - + import Control.Monad.Random (MonadRandom(..)) import qualified Crypto.Saltine.Class as Saltine (IsEncoding(..)) import qualified Data.ByteArray as ByteArray (convert) @@ -227,11 +227,11 @@ data MailException = MailNotAvailable deriving (Eq, Ord, Read, Show, Generic, Typeable) instance Exception MailException - + class Yesod site => YesodMail site where defaultFromAddress :: (MonadHandler m, HandlerSite m ~ site) => m Address - defaultFromAddress = (Address Nothing . ("yesod@" <>) . pack) <$> liftIO getHostName + defaultFromAddress = Address Nothing . ("yesod@" <>) . pack <$> liftIO getHostName mailObjectIdDomain :: (MonadHandler m, HandlerSite m ~ site) => m Text mailObjectIdDomain = pack <$> liftIO getHostName @@ -464,7 +464,7 @@ replaceMailHeaderI :: ( RenderMessage site msg , MonadHeader m ) => MailHeader -> msg -> m () replaceMailHeaderI header msg = removeMailHeader header >> addMailHeaderI header msg - + addMailHeaderI :: ( RenderMessage site msg , MonadMail m , HandlerSite m ~ site @@ -523,7 +523,7 @@ setDate time = do rfc822zone tz' | tz' `elem` rfc822zones = tz' | otherwise = tz' { timeZoneName = "" } - rfc822zones = + rfc822zones = [ TimeZone 0 False "UT" , TimeZone 0 False "GMT" , TimeZone (-5 * 60) False "EST" diff --git a/src/Model.hs b/src/Model.hs index fcd41546b..301846972 100644 --- a/src/Model.hs +++ b/src/Model.hs @@ -140,7 +140,7 @@ instance HasFileReference SheetFile where fileReferenceTitleField = SheetFileTitle fileReferenceContentField = SheetFileContent fileReferenceModifiedField = SheetFileModified - + instance HasFileReference SubmissionFile where data FileReferenceResidual SubmissionFile = SubmissionFileResidual { submissionFileResidualSubmission :: SubmissionId @@ -233,4 +233,4 @@ instance HasFileReference MaterialFile where fileReferenceTitleField = MaterialFileTitle fileReferenceContentField = MaterialFileContent fileReferenceModifiedField = MaterialFileModified - + diff --git a/src/Model/Migration.hs b/src/Model/Migration.hs index 6b4c67ee8..1bc6a8e62 100644 --- a/src/Model/Migration.hs +++ b/src/Model/Migration.hs @@ -55,7 +55,7 @@ import Web.ServerSession.Backend.Persistent.Memcached (migrateMemcachedSqlStorag -- -- Doing so creates sort of parallel commit history tracking changes to the database schema - + share [mkPersist sqlSettings, mkMigrate "migrateDBVersioning"] [persistLowerCase| AppliedMigration json @@ -90,11 +90,11 @@ migrateAll = do $logInfoS "Migration" [st|#{tshow appliedMigrationFrom} -> #{tshow appliedMigrationTo}|] appliedMigrationTime <- liftIO getCurrentTime _ <- migration - insert AppliedMigration{..} + insert AppliedMigration{..} -- Map.foldlWithKey traverses migrations in ascending order of AppliedMigrationKey $logDebugS "Migration" "Apply missing migrations" - Map.foldlWithKey doCustomMigration (return ()) missingMigrations - + Map.foldlWithKey doCustomMigration (return ()) missingMigrations + $logDebugS "Migration" "Persistent automatic migration" mapM_ ($logInfoS "Migration") =<< runMigrationSilent migrateAll' @@ -105,20 +105,20 @@ requiresMigration :: forall m. => ReaderT SqlBackend m Bool requiresMigration = mapReaderT (exceptT return return) $ do initial <- either id (map snd) <$> parseMigration initialMigration - when (not $ null initial) $ do + unless (null initial) $ do $logInfoS "Migration" $ intercalate "; " initial throwError True customs <- mapReaderT lift $ getMissingMigrations @_ @m - when (not $ Map.null customs) $ do + unless (Map.null customs) $ do $logInfoS "Migration" . intercalate ", " . map tshow $ Map.keys customs throwError True - + automatic <- either id (map snd) <$> parseMigration migrateAll' - when (not $ null automatic) $ do + unless (null automatic) $ do $logInfoS "Migration" $ intercalate "; " automatic throwError True - + return False initialMigration :: Migration @@ -188,7 +188,7 @@ customMigrations = Map.fromListWith (>>) other -> error $ "Could not parse theme: " <> show other ) , ( AppliedMigrationKey [migrationVersion|0.0.0|] [version|1.0.0|] - , whenM (tableExists "sheet") $ -- Better JSON encoding + , whenM (tableExists "sheet") -- Better JSON encoding [executeQQ| ALTER TABLE "sheet" ALTER COLUMN "type" TYPE jsonb USING "type"::jsonb; ALTER TABLE "sheet" ALTER COLUMN "grouping" TYPE jsonb USING "grouping"::jsonb; @@ -265,13 +265,13 @@ customMigrations = Map.fromListWith (>>) _other -> error "Empty userDisplayName found" ) , ( AppliedMigrationKey [migrationVersion|3.1.0|] [version|3.2.0|] - , whenM (tableExists "sheet") $ + , whenM (tableExists "sheet") [executeQQ| ALTER TABLE "sheet" ADD COLUMN IF NOT EXISTS "upload_mode" jsonb DEFAULT '{ "tag": "Upload", "unpackZips": true }'; |] ) , ( AppliedMigrationKey [migrationVersion|3.2.0|] [version|4.0.0|] - , whenM (columnExists "user" "plugin") $ + , whenM (columnExists "user" "plugin") -- <> is standard sql for /= [executeQQ| DELETE FROM "user" WHERE "plugin" <> 'LDAP'; @@ -280,7 +280,7 @@ customMigrations = Map.fromListWith (>>) |] ) , ( AppliedMigrationKey [migrationVersion|4.0.0|] [version|5.0.0|] - , whenM (tableExists "user") $ + , whenM (tableExists "user") [executeQQ| ALTER TABLE "user" ADD COLUMN IF NOT EXISTS "notification_settings" jsonb NOT NULL DEFAULT '[]'; |] @@ -288,16 +288,16 @@ customMigrations = Map.fromListWith (>>) , ( AppliedMigrationKey [migrationVersion|5.0.0|] [version|6.0.0|] , whenM (tableExists "sheet") $ do sheets <- [sqlQQ| SELECT "id", "type" FROM "sheet"; |] - forM_ sheets $ \(sid, Single lsty) -> update sid [SheetType =. Legacy.sheetType lsty] + forM_ sheets $ \(sid, Single lsty) -> update sid [SheetType =. Legacy.sheetType lsty] ) , ( AppliedMigrationKey [migrationVersion|6.0.0|] [version|7.0.0|] - , whenM (tableExists "cluster_config") $ + , whenM (tableExists "cluster_config") [executeQQ| UPDATE "cluster_config" SET "setting" = 'secret-box-key' WHERE "setting" = 'error-message-key'; |] ) , ( AppliedMigrationKey [migrationVersion|7.0.0|] [version|8.0.0|] - , whenM (tableExists "sheet") $ + , whenM (tableExists "sheet") [executeQQ| UPDATE "sheet" SET "type" = json_build_object('type', "type"->'type', 'grading', "type"->'') WHERE jsonb_exists("type", ''); UPDATE "sheet" SET "type" = json_build_object('type', "type"->'type', 'grading', json_build_object('type', "type"->'grading'->'type', 'max', "type"->'grading'->'points')) WHERE ("type"->'grading'->'type') = '"points"' AND jsonb_exists("type"->'grading', 'points'); @@ -315,10 +315,10 @@ customMigrations = Map.fromListWith (>>) ) , ( AppliedMigrationKey [migrationVersion|9.0.0|] [version|10.0.0|] , do - whenM (columnExists "study_degree" "shorthand") $ [executeQQ| UPDATE "study_degree" SET "shorthand" = NULL WHERE "shorthand" = '' |] - whenM (columnExists "study_degree" "name") $ [executeQQ| UPDATE "study_degree" SET "name" = NULL WHERE "shorthand" = '' |] - whenM (columnExists "study_terms" "shorthand") $ [executeQQ| UPDATE "study_terms" SET "shorthand" = NULL WHERE "shorthand" = '' |] - whenM (columnExists "study_terms" "name") $ [executeQQ| UPDATE "study_terms" SET "name" = NULL WHERE "shorthand" = '' |] + whenM (columnExists "study_degree" "shorthand") [executeQQ| UPDATE "study_degree" SET "shorthand" = NULL WHERE "shorthand" = '' |] + whenM (columnExists "study_degree" "name") [executeQQ| UPDATE "study_degree" SET "name" = NULL WHERE "shorthand" = '' |] + whenM (columnExists "study_terms" "shorthand") [executeQQ| UPDATE "study_terms" SET "shorthand" = NULL WHERE "shorthand" = '' |] + whenM (columnExists "study_terms" "name") [executeQQ| UPDATE "study_terms" SET "name" = NULL WHERE "shorthand" = '' |] ) , ( AppliedMigrationKey [migrationVersion|10.0.0|] [version|11.0.0|] , whenM ((&&) <$> columnExists "sheet" "upload_mode" <*> columnExists "sheet" "submission_mode") $ do @@ -388,7 +388,7 @@ customMigrations = Map.fromListWith (>>) ALTER TABLE transaction_log ADD COLUMN "initiator_id" bigint DEFAULT null; |] - whenM (tableExists "user") $ + whenM (tableExists "user") [executeQQ| UPDATE transaction_log SET initiator_id = "user".id FROM "user" WHERE transaction_log.initiator = "user".ident; |] @@ -420,7 +420,7 @@ customMigrations = Map.fromListWith (>>) eid <- MaybeT . getKeyBy $ UniqueExam cid examn uid <- MaybeT . getKeyBy $ UniqueAuthentication uident return $ TransactionExamRegister eid uid - whenIsJust newT $ \newT' -> + whenIsJust newT $ \newT' -> update lid [ TransactionLogInfo =. toJSON newT' ] updateTransactionInfo _ = return () runConduit $ getLogEntries .| C.mapM_ updateTransactionInfo @@ -441,7 +441,7 @@ customMigrations = Map.fromListWith (>>) [executeQQ| UPDATE "course" SET ("applications_required", "applications_instructions", "applications_text", "applications_files", "applications_ratings_visible") = (#{appRequired}, #{applicationsInstructions}, #{applicationsText}, #{applicationsFiles}, #{applicationsRatingsVisible}) WHERE "id" = #{cid}; |] - + [executeQQ| ALTER TABLE "allocation_course" DROP COLUMN "instructions", DROP COLUMN "application_text", DROP COLUMN "application_files", DROP COLUMN "ratings_visible"; |] @@ -537,7 +537,7 @@ customMigrations = Map.fromListWith (>>) . snd ) & map fst - forM_ (zip [_ExamPartNumber' # 1..] partsSorted) $ \(num :: ExamPartNumber, pId) -> + forM_ (zip [_ExamPartNumber' # 1..] partsSorted) $ \(num :: ExamPartNumber, pId) -> [executeQQ| UPDATE "exam_part" SET "number" = #{num} WHERE "id" = #{pId}; |] @@ -572,13 +572,13 @@ customMigrations = Map.fromListWith (>>) |] ) , ( AppliedMigrationKey [migrationVersion|22.0.0|] [version|23.0.0|] - , whenM (tableExists "exam") $ + , whenM (tableExists "exam") [executeQQ| UPDATE "exam" SET "bonus_rule" = jsonb_insert("bonus_rule", '{round}' :: text[], '0.01' :: jsonb) WHERE "bonus_rule"->>'rule' = 'bonus-points'; |] ) , ( AppliedMigrationKey [migrationVersion|23.0.0|] [version|24.0.0|] - , whenM (tableExists "course_favourite") $ + , whenM (tableExists "course_favourite") [executeQQ| ALTER TABLE "course_favourite" RENAME COLUMN "time" TO "last_visit"; ALTER TABLE "course_favourite" ADD COLUMN "reason" jsonb DEFAULT '"visited"'::jsonb; @@ -596,7 +596,7 @@ customMigrations = Map.fromListWith (>>) _other -> error "Cannot reconstruct course_participant.allocated" ) , ( AppliedMigrationKey [migrationVersion|25.0.0|] [version|26.0.0|] - , whenM (tableExists "allocation") $ + , whenM (tableExists "allocation") [executeQQ| CREATE TABLE "allocation_matching" ("id" SERIAL8 PRIMARY KEY UNIQUE, "allocation" INT8 NOT NULL, "fingerprint" BYTEA NOT NULL, "log" INT8 NOT NULL); INSERT INTO "allocation_matching" ("allocation", "fingerprint", "log") (select "id" as "allocation", "fingerprint", "matching_log" as "log" from "allocation" where not ("matching_log" is null) and not ("fingerprint" is null)); @@ -605,7 +605,7 @@ customMigrations = Map.fromListWith (>>) |] ) , ( AppliedMigrationKey [migrationVersion|26.0.0|] [version|27.0.0|] - , whenM (tableExists "user") $ + , whenM (tableExists "user") [executeQQ| ALTER TABLE "user" ADD COLUMN "languages" jsonb; UPDATE "user" SET "languages" = "mail_languages" where "mail_languages" <> '[]'; @@ -617,7 +617,7 @@ customMigrations = Map.fromListWith (>>) tableDropEmpty "exam_part_corrector" ) , ( AppliedMigrationKey [migrationVersion|28.0.0|] [version|29.0.0|] - , whenM (tableExists "study_features") $ + , whenM (tableExists "study_features") [executeQQ| ALTER TABLE "study_features" ADD COLUMN "super_field" bigint; UPDATE "study_features" SET "super_field" = "field", "field" = "sub_field" WHERE NOT ("sub_field" IS NULL); @@ -625,7 +625,7 @@ customMigrations = Map.fromListWith (>>) |] ) , ( AppliedMigrationKey [migrationVersion|29.0.0|] [version|30.0.0|] - , whenM (tableExists "exam") $ + , whenM (tableExists "exam") [executeQQ| UPDATE "exam" SET "occurrence_rule" = #{ExamRoomManual} WHERE "occurrence_rule" IS NULL; ALTER TABLE "exam" ALTER COLUMN "occurrence_rule" SET NOT NULL; @@ -640,7 +640,7 @@ customMigrations = Map.fromListWith (>>) in [executeQQ|UPDATE exam_result SET result = #{res'} WHERE id = #{resId};|] ) , ( AppliedMigrationKey [migrationVersion|31.0.0|] [version|32.0.0|] - , whenM (tableExists "exam") $ + , whenM (tableExists "exam") [executeQQ| ALTER TABLE "exam" ADD COLUMN "grading_mode" character varying; UPDATE "exam" SET "grading_mode" = 'grades' WHERE "show_grades"; @@ -650,7 +650,7 @@ customMigrations = Map.fromListWith (>>) |] ) , ( AppliedMigrationKey [migrationVersion|32.0.0|] [version|33.0.0|] - , whenM (tableExists "external_exam") $ + , whenM (tableExists "external_exam") [executeQQ| ALTER TABLE "external_exam" ADD COLUMN "grading_mode" character varying; UPDATE "external_exam" SET "grading_mode" = 'grades' WHERE "show_grades"; @@ -716,7 +716,7 @@ customMigrations = Map.fromListWith (>>) (fromPersistValue . unSingle -> Right (fileReferenceTitle' :: FilePath), fromPersistValue . unSingle -> Right fileReferenceModified, fromPersistValue . unSingle -> Right fileReferenceContent) -> do let fileRef fileReferenceTitle = _FileReference # (FileReference{..}, residual) candidateTitles = fileReferenceTitle' : [ fName <.> ("old-" <> show n) <.> ext | n <- [1..1000] ] - where (fName, ext) = splitExtension fileReferenceTitle' + where (fName, ext) = splitExtension fileReferenceTitle' validTitles <- dropWhileM (fmap (is _Just) . checkUnique . fileRef) candidateTitles case validTitles of fTitle : _ -> doUpdate . Entity fRefKey $ fileRef fTitle @@ -849,7 +849,7 @@ customMigrations = Map.fromListWith (>>) ALTER TABLE "allocation_matching" RENAME COLUMN "log_ref" TO "log"; |] - whenM (tableExists "session_file") $ + whenM (tableExists "session_file") [executeQQ| ALTER TABLE "session_file" ADD COLUMN "content" BYTEA; UPDATE "session_file" SET "content" = (SELECT "hash" FROM "file" WHERE "file".id = "session_file"."file"); @@ -920,4 +920,4 @@ columnExists table column = do case haveColumn :: [Single PersistValue] of [_] -> return True _other -> return False - + diff --git a/src/Model/Migration/Types.hs b/src/Model/Migration/Types.hs index 23f4e6a17..019701659 100644 --- a/src/Model/Migration/Types.hs +++ b/src/Model/Migration/Types.hs @@ -55,7 +55,7 @@ deriveJSON defaultOptions ''SheetType Current.derivePersistFieldJSON ''SheetType - + data Transaction = TransactionTermEdit { transactionTerm :: Current.TermIdentifier @@ -75,7 +75,7 @@ data Transaction , transactionUser :: Current.UserIdent } deriving (Eq, Ord, Read, Show, Generic, Typeable) - + deriveJSON defaultOptions { constructorTagModifier = camelToPathPiece' 1 , fieldLabelModifier = camelToPathPiece' 1 diff --git a/src/Model/Migration/Version.hs b/src/Model/Migration/Version.hs index 35c799a10..c5239e4bb 100644 --- a/src/Model/Migration/Version.hs +++ b/src/Model/Migration/Version.hs @@ -24,7 +24,7 @@ import Data.Data (Data) deriving instance Lift Version - + data MigrationVersion = InitialVersion | MigrationVersion Version deriving (Eq, Ord, Show, Read, Generic, Typeable, Data, Lift) diff --git a/src/Model/Tokens/Bearer.hs b/src/Model/Tokens/Bearer.hs index c2231f0f9..d8e3cd901 100644 --- a/src/Model/Tokens/Bearer.hs +++ b/src/Model/Tokens/Bearer.hs @@ -10,7 +10,7 @@ module Model.Tokens.Bearer import ClassyPrelude.Yesod import Yesod.Core.Instances () - + import Model import Model.Tokens.Lens import Utils (assertM', foldMapM) diff --git a/src/Model/Tokens/Lens.hs b/src/Model/Tokens/Lens.hs index 2f2a95571..cb813f769 100644 --- a/src/Model/Tokens/Lens.hs +++ b/src/Model/Tokens/Lens.hs @@ -10,7 +10,7 @@ class HasTokenIdentifier s a | s -> a where class HasTokenIssuedBy s a | s -> a where _tokenIssuedBy :: Lens' s a - + class HasTokenIssuedFor s a | s -> a where _tokenIssuedFor :: Lens' s a diff --git a/src/Model/Tokens/Session.hs b/src/Model/Tokens/Session.hs index 4f0180491..2a5990eaf 100644 --- a/src/Model/Tokens/Session.hs +++ b/src/Model/Tokens/Session.hs @@ -8,9 +8,9 @@ import ClassyPrelude.Yesod import Model.Tokens.Lens import Model import Utils.Lens - + import Web.ServerSession.Core - + import Jose.Jwt (IntDate(..)) import qualified Jose.Jwt as Jose @@ -70,7 +70,7 @@ instance FromJSON (SessionToken sess) where fromPathPiece aud let sessionExpiresAt = unIntDate <$> jwtExp sessionStartsAt = unIntDate <$> jwtNbf - + return SessionToken{..} where parseMaybe errId = maybe (fail $ "Could not parse " <> errId) return diff --git a/src/Model/Types/Allocation.hs b/src/Model/Types/Allocation.hs index f03b5ce69..afa9461d4 100644 --- a/src/Model/Types/Allocation.hs +++ b/src/Model/Types/Allocation.hs @@ -16,7 +16,7 @@ import qualified Data.Csv as Csv import qualified Data.Vector as Vector import qualified Data.Map.Strict as Map - + import Crypto.Hash (SHAKE128) import qualified Database.Esqueleto as E diff --git a/src/Model/Types/Common.hs b/src/Model/Types/Common.hs index 8577a86fa..ceb97f2a2 100644 --- a/src/Model/Types/Common.hs +++ b/src/Model/Types/Common.hs @@ -11,7 +11,7 @@ module Model.Types.Common import Import.NoModel import qualified Yesod.Auth.Util.PasswordStore as PWStore - + type Count = Sum Integer type Points = Centi diff --git a/src/Model/Types/Exam.hs b/src/Model/Types/Exam.hs index 25cb813a5..6dbc7122e 100644 --- a/src/Model/Types/Exam.hs +++ b/src/Model/Types/Exam.hs @@ -59,6 +59,8 @@ import qualified Data.Foldable import Data.Aeson (genericToJSON, genericParseJSON) +{-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-} + data ExamResult' res = ExamAttended { examResult :: res } | ExamNoShow @@ -97,7 +99,7 @@ instance Applicative ExamResult' where instance Foldable ExamResult' where foldMap = foldMapOf _examResult - + instance Traversable ExamResult' where traverse = _examResult @@ -170,7 +172,7 @@ derivePersistFieldJSON ''ExamOccurrenceRule makePrisms ''ExamOccurrenceRule examOccurrenceRuleAutomatic :: ExamOccurrenceRule -> Bool -examOccurrenceRuleAutomatic x = or $ map ($ x) +examOccurrenceRuleAutomatic x = any ($ x) [ is _ExamRoomSurname , is _ExamRoomMatriculation , is _ExamRoomRandom @@ -388,7 +390,7 @@ _ExamPartNumber' = prism (ExamPartNumber . fromNum) (first ExamPartNumber . toNu fromNum (toInteger -> n) | n < 0 = [Left "-", Right . fromInteger $ abs n] | otherwise = [Right $ fromInteger n] - + toNum fs | Just ns <- mapM (preview _Right) fs = case ns of @@ -401,7 +403,7 @@ _ExamPartNumber' = prism (ExamPartNumber . fromNum) (first ExamPartNumber . toNu instance Show ExamPartNumber where showsPrec p = showsPrec p . CI.original . view _ExamPartNumber instance Read ExamPartNumber where - readPrec = review _ExamPartNumber . CI.mk <$> readPrec + readPrec = review _ExamPartNumber . CI.mk <$> readPrec instance PersistField ExamPartNumber where toPersistValue = toPersistValue . view _ExamPartNumber diff --git a/src/Model/Types/Health.hs b/src/Model/Types/Health.hs index af2a14147..0dc4af620 100644 --- a/src/Model/Types/Health.hs +++ b/src/Model/Types/Health.hs @@ -27,7 +27,7 @@ deriveJSON defaultOptions } ''HealthCheck nullaryPathPiece ''HealthCheck $ camelToPathPiece' 2 pathPieceJSONKey ''HealthCheck - + data HealthReport = HealthMatchingClusterConfig { healthMatchingClusterConfig :: Bool } -- ^ Is the database-stored configuration we're running under still up to date? @@ -87,7 +87,7 @@ healthReportStatus = \case HealthHTTPReachable (Just False) -> HealthFailure HealthLDAPAdmins (Just prop ) | prop <= 0 -> HealthFailure - HealthSMTPConnect (Just False) -> HealthFailure + HealthSMTPConnect (Just False) -> HealthFailure HealthWidgetMemcached (Just False) -> HealthFailure -- TODO: investigate this failure mode; do we just handle it gracefully? HealthActiveJobExecutors (Just prop ) | prop <= 0 -> HealthFailure diff --git a/src/Model/Types/Languages.hs b/src/Model/Types/Languages.hs index 8ed789fb6..0f5568720 100644 --- a/src/Model/Types/Languages.hs +++ b/src/Model/Types/Languages.hs @@ -10,7 +10,7 @@ import GHC.Exts (IsList) import Model.Types.TH.JSON import Control.Lens.TH (makeWrapped) - + newtype Languages = Languages [Lang] deriving (Eq, Ord, Show, Read, Generic, Typeable) diff --git a/src/Model/Types/Misc.hs b/src/Model/Types/Misc.hs index 6e33c53dc..bc8e1c23d 100644 --- a/src/Model/Types/Misc.hs +++ b/src/Model/Types/Misc.hs @@ -73,7 +73,7 @@ deriveFinite ''Quoting nullaryPathPiece ''Quoting $ \q -> if | q == "QuoteNone" -> "never" | otherwise -> camelToPathPiece' 1 q - + data CsvOptions = CsvOptions { csvFormat :: CsvFormatOptions @@ -156,7 +156,7 @@ instance FromJSON CsvOptions where csvFormat <- o JSON..:? "format" JSON..!= csvFormat def csvTimestamp <- o JSON..:? "timestamp" JSON..!= csvTimestamp def return CsvOptions{..} - + instance ToJSON CsvFormatOptions where toJSON CsvFormatOptions{..} = JSON.object [ "delimiter" JSON..= fromEnum csvDelimiter @@ -171,7 +171,7 @@ instance FromJSON CsvFormatOptions where csvQuoting <- o JSON..:? "quoting" JSON..!= csvQuoting def csvEncoding <- o JSON..:? "encoding" JSON..!= csvEncoding def return CsvFormatOptions{..} - + derivePersistFieldJSON ''CsvOptions nullaryPathPiece ''CsvPreset $ camelToPathPiece' 2 diff --git a/src/Model/Types/Security.hs b/src/Model/Types/Security.hs index 0cd47cc69..8507da7d0 100644 --- a/src/Model/Types/Security.hs +++ b/src/Model/Types/Security.hs @@ -152,7 +152,7 @@ instance (Ord a, FromJSON a) => FromJSON (PredDNF a) where parseJSON = $(mkParseJSON predNFAesonOptions ''PredDNF) instance (Ord a, PathPiece a) => PathPiece (PredDNF a) where - toPathPiece = Text.unwords . map (Text.intercalate "AND") . map (map toPathPiece . otoList) . otoList . dnfTerms + toPathPiece = Text.unwords . map (Text.intercalate "AND" . map toPathPiece . otoList) . otoList . dnfTerms fromPathPiece = fmap (PredDNF . Set.fromList) . mapM (fromNullable <=< foldMapM (fmap Set.singleton . fromPathPiece) . Text.splitOn "AND") . concatMap (Text.splitOn "OR") . Text.words type AuthLiteral = PredLiteral AuthTag diff --git a/src/Model/Types/Sheet.hs b/src/Model/Types/Sheet.hs index e596d64c6..49bf2d76c 100644 --- a/src/Model/Types/Sheet.hs +++ b/src/Model/Types/Sheet.hs @@ -19,7 +19,7 @@ import qualified Data.Map as Map import Text.Blaze (Markup) import Data.Maybe (fromJust) - + import qualified Data.Csv as Csv diff --git a/src/Model/Types/Submission.hs b/src/Model/Types/Submission.hs index b8ace9549..162952d2e 100644 --- a/src/Model/Types/Submission.hs +++ b/src/Model/Types/Submission.hs @@ -23,10 +23,10 @@ import qualified Data.Text as Text import qualified Data.Set as Set -import Data.List (elemIndex, genericIndex) +import Data.List (genericIndex) import Data.Bits import Data.Text.Metrics (damerauLevenshtein) - + ------------------------- -- Submission Download -- ------------------------- @@ -50,7 +50,7 @@ isUpdateSubmissionFileType True = SubmissionCorrected --------------------------- -- Submission Pseudonyms -- --------------------------- - + type PseudonymWord = CI Text newtype Pseudonym = Pseudonym Word24 @@ -137,7 +137,7 @@ _PseudonymText = prism' tToWords tFromWords . _PseudonymWords pseudonymWords :: Fold Text PseudonymWord pseudonymWords = folding - $ \(CI.mk -> input) -> map (view _2) . fromMaybe [] . listToMaybe . groupBy ((==) `on` view _1) . sortBy (comparing $ view _1) . filter ((<= distanceCutoff) . view _1) $ map (distance input &&& id) pseudonymWordlist + $ \(CI.mk -> input) -> maybe [] (map (view _2)) . listToMaybe . groupBy ((==) `on` view _1) . sortOn (view _1) . filter ((<= distanceCutoff) . view _1) $ map (distance input &&& id) pseudonymWordlist where distance = damerauLevenshtein `on` CI.foldedCase -- | Arbitrary cutoff point, for reference: ispell cuts off at 1 diff --git a/src/Model/Types/TH/JSON.hs b/src/Model/Types/TH/JSON.hs index 34a752350..c1ca6a88a 100644 --- a/src/Model/Types/TH/JSON.hs +++ b/src/Model/Types/TH/JSON.hs @@ -64,4 +64,4 @@ predNFAesonOptions = defaultOptions , sumEncoding = ObjectWithSingleField , tagSingleConstructors = True } - + diff --git a/src/Network/Mail/Mime/Instances.hs b/src/Network/Mail/Mime/Instances.hs index 201442aee..ca2e73f91 100644 --- a/src/Network/Mail/Mime/Instances.hs +++ b/src/Network/Mail/Mime/Instances.hs @@ -15,7 +15,7 @@ import Utils.PathPiece import Utils (assertM) import qualified Data.Csv as Csv - + deriving instance Read Address deriving instance Ord Address diff --git a/src/Network/Mime/TH.hs b/src/Network/Mime/TH.hs index e90033904..da941bfc9 100644 --- a/src/Network/Mime/TH.hs +++ b/src/Network/Mime/TH.hs @@ -21,7 +21,7 @@ import Instances.TH.Lift () mimeMapFile, mimeSetFile :: FilePath -> ExpQ mimeMapFile file = do qAddDependentFile file - + mappings <- runIO $ filter (not . isComment) . Text.lines <$> Text.readFile file let coMappings :: [(Extension, MimeType)] @@ -38,7 +38,7 @@ mimeMapFile file = do lift mimeMap mimeSetFile file = do qAddDependentFile file - + ls <- runIO $ filter (not . isComment) . Text.lines <$> Text.readFile file let mimeSet :: Set MimeType diff --git a/src/Settings/Cluster.hs b/src/Settings/Cluster.hs index bc72857ea..ae619dd73 100644 --- a/src/Settings/Cluster.hs +++ b/src/Settings/Cluster.hs @@ -57,7 +57,7 @@ instance ToHttpApiData ClusterSettingsKey where instance FromHttpApiData ClusterSettingsKey where parseUrlPiece = maybe (Left "Could not parse url piece") Right . fromPathPiece - + class (ToJSON (ClusterSettingValue key), FromJSON (ClusterSettingValue key)) => ClusterSetting (key :: ClusterSettingsKey) where type ClusterSettingValue key :: * initClusterSetting :: forall m p. MonadIO m => p key -> m (ClusterSettingValue key) @@ -86,7 +86,7 @@ instance ClusterSetting 'ClusterServerSessionKey where type ClusterSettingValue 'ClusterServerSessionKey = AEAD.Key initClusterSetting _ = liftIO AEAD.newKey knownClusterSetting _ = ClusterServerSessionKey - + instance ToJSON AEAD.Key where toJSON = Aeson.String . decodeUtf8 . Base64.encode . Saltine.encode diff --git a/src/Settings/Log.hs b/src/Settings/Log.hs index 112519e41..57742ad0b 100644 --- a/src/Settings/Log.hs +++ b/src/Settings/Log.hs @@ -31,12 +31,12 @@ instance Hashable LogSettings instance NFData LogSettings instance Hashable LogDestination instance NFData LogDestination - + deriveJSON defaultOptions { constructorTagModifier = camelToPathPiece' 1 , sumEncoding = UntaggedValue } ''LogLevel - + deriveJSON defaultOptions { constructorTagModifier = camelToPathPiece' 2 , fieldLabelModifier = camelToPathPiece' 2 diff --git a/src/Settings/StaticFiles/Generator.hs b/src/Settings/StaticFiles/Generator.hs index 47c04090c..f7fb5daf1 100644 --- a/src/Settings/StaticFiles/Generator.hs +++ b/src/Settings/StaticFiles/Generator.hs @@ -36,7 +36,7 @@ staticGenerator staticDir = do where toEntries :: FilePath -- ^ Absolute path -> IO [Entry] - toEntries loc = compile (mimeLookup $ pack loc) (makeRelative staticDir loc) loc + toEntries loc = compile (mimeLookup $ pack loc) (makeRelative staticDir loc) loc compile :: MimeType -> Location -- ^ Relative location diff --git a/src/Settings/StaticFiles/Webpack.hs b/src/Settings/StaticFiles/Webpack.hs index 3fcd6c224..999f959ab 100644 --- a/src/Settings/StaticFiles/Webpack.hs +++ b/src/Settings/StaticFiles/Webpack.hs @@ -54,11 +54,11 @@ mkWebpackEntrypoints manifest mkGen stDir = do , "” has no haskellName" ] Just n -> tell $ pure (n, ebMimeType entry) - + let entryName = mkName $ "webpackEntrypoint_" <> entrypoint widgetName = mkName $ "webpackLinks_" <> entrypoint - staticR <- newName "staticR" + staticR <- newName "staticR" sequence [ sigD entryName [t|[(Route EmbeddedStatic, MimeType)]|] , funD entryName @@ -89,4 +89,4 @@ mkWebpackEntrypoints manifest mkGen stDir = do Left exc -> throwM exc Right (ws, res') -> res' <$ mapM_ (\w -> reportWarning $ "Warning while parsing webpack manifest: " <> show w) ws - + diff --git a/src/Settings/WellKnownFiles.hs b/src/Settings/WellKnownFiles.hs index 91b4dfd9a..fcb207c7b 100644 --- a/src/Settings/WellKnownFiles.hs +++ b/src/Settings/WellKnownFiles.hs @@ -5,7 +5,7 @@ module Settings.WellKnownFiles ) where import Settings.WellKnownFiles.TH - + import Settings (appWellKnownDir, appWellKnownLinkFile, compileTimeAppSettings) mkWellKnown "de-de-formal" (appWellKnownDir compileTimeAppSettings) (appWellKnownLinkFile compileTimeAppSettings) diff --git a/src/Settings/WellKnownFiles/TH.hs b/src/Settings/WellKnownFiles/TH.hs index e88a25755..a8eacb92c 100644 --- a/src/Settings/WellKnownFiles/TH.hs +++ b/src/Settings/WellKnownFiles/TH.hs @@ -4,7 +4,7 @@ module Settings.WellKnownFiles.TH import ClassyPrelude.Yesod import Utils - + import Language.Haskell.TH import Language.Haskell.TH.Syntax hiding (Lift(..)) import qualified Language.Haskell.TH.Syntax as TH (Lift(..)) @@ -107,7 +107,7 @@ mkWellKnown defLang wellKnownBase wellKnownLinks = do -> return $ defLang :| Set.toList languages' | otherwise -> fail "default language is missing in wellKnownBase" - + fVar <- newName "f" hVar <- newName "h" @@ -121,7 +121,7 @@ mkWellKnown defLang wellKnownBase wellKnownLinks = do wellKnownFileName = dataD (cxt []) - nWellKnownFileName + nWellKnownFileName [] Nothing [ normalC (mkName $ fNameManip fName) [] @@ -142,7 +142,7 @@ mkWellKnown defLang wellKnownBase wellKnownLinks = do [ clause [conP (mkName $ fNameManip fName) []] (normalB . TH.lift . map Text.pack $ splitDirectories fName) [] | fName <- Set.toList fileNames ] - , funD 'fromPathMultiPiece $ + , funD 'fromPathMultiPiece [ clause [] (normalB [e|flip HashMap.lookup $(varE nwellKnownFileNames)|]) [] ] ] @@ -157,7 +157,7 @@ mkWellKnown defLang wellKnownBase wellKnownLinks = do getWellKnownR = funD ngetWellKnownR [ clause [varP fVar] (normalB [e|$(varE hVar) =<< selectLanguage fLanguages|]) - [ funD hVar $ + [ funD hVar $ [ clause [varP lVar] (guardedB [ (,) <$> normalG [e|HashSet.member ($(varE lVar), $(varE fVar)) $ HashSet.fromList $(listE [ tupE [TH.lift l, conE . mkName $ fNameManip fName] | (l, fName) <- Set.toList xs ])|] <*> [e|TypedContent mime (toContent fContent) <$ setEtag $(TH.lift $ hashToText (mime, fContent))|] @@ -174,7 +174,7 @@ mkWellKnown defLang wellKnownBase wellKnownLinks = do nwellKnownHtmlLinks [ clause [] (normalB [e|toWidgetHead . preEscapedToHtml . $(varE hVar) =<< selectLanguage lLanguages|]) [ sigD hVar [t|Text -> Text|] - , funD hVar $ + , funD hVar $ [ clause [varP lVar] (guardedB [ (,) <$> normalG [|$(varE lVar) == lang|] <*> TH.lift (Text.filter (`notElem` ['\r', '\n']) $ Text.decodeUtf8 c) diff --git a/src/UnliftIO/Async/Utils.hs b/src/UnliftIO/Async/Utils.hs index 4b775e807..3e0184997 100644 --- a/src/UnliftIO/Async/Utils.hs +++ b/src/UnliftIO/Async/Utils.hs @@ -21,7 +21,7 @@ allocateAsync act = withRunInIO $ \run -> run . fmap (view _2) . flip allocate A allocateLinkedAsync :: forall m a. (MonadUnliftIO m, MonadResource m) => m a -> m (Async a) allocateLinkedAsync = uncurry (<$) . (id &&& UnliftIO.link) <=< allocateAsync - + allocateAsyncWithUnmask :: forall m a. ( MonadUnliftIO m, MonadResource m ) => ((forall b. m b -> m b) -> m a) -> m (Async a) @@ -30,7 +30,7 @@ allocateAsyncWithUnmask act = withRunInIO $ \run -> run . fmap (view _2) . flip allocateLinkedAsyncWithUnmask :: forall m a. (MonadUnliftIO m, MonadResource m) => ((forall b. m b -> m b) -> m a) -> m (Async a) allocateLinkedAsyncWithUnmask act = uncurry (<$) . (id &&& UnliftIO.link) =<< allocateAsyncWithUnmask act - + allocateAsyncMasked :: forall m a. ( MonadUnliftIO m, MonadResource m ) => m a -> m (Async a) diff --git a/src/Utils.hs b/src/Utils.hs index 0b5670ad7..4a6d66df4 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -51,6 +51,7 @@ import Control.Lens as Utils (none) import Control.Lens.Extras (is) import Data.Set.Lens +import Control.Monad (zipWithM) import Control.Arrow as Utils ((>>>)) import Control.Monad.Trans.Except (ExceptT(..), throwE, runExceptT) import Control.Monad.Except (MonadError(..)) @@ -149,7 +150,7 @@ maybeAttribute :: Text -> (a -> Text) -> Maybe a -> [(Text,Text)] maybeAttribute _ _ Nothing = [] maybeAttribute a c (Just v) = [(a,c v)] - + newtype PrettyValue = PrettyValue { unPrettyValue :: Value } deriving (Eq, Read, Show, Generic, Typeable, Data, TH.Lift) deriving newtype (Hashable, IsString, FromJSON, ToJSON, NFData) @@ -343,7 +344,7 @@ cutOffCoPercent (abs -> offset) (abs -> full) (abs -> achieved) | otherwise = 1 where percent = achieved / full - + -- | @cutOffPercent offset full achieved@ returns a value between 0 and 1, measuring how close @achieved@ is to @full@@; 1 meaning very and 0 meaning not at all -- -- @offset@ specifies minimum result value, unless @achieved@ is zero @@ -580,7 +581,7 @@ catchMaybeT _ act = catch (lift act) (const mzero :: e -> MaybeT m a) catchMPlus :: forall p m e a. (MonadPlus m, MonadCatch m, Exception e) => p e -> m a -> m a catchMPlus _ = handle (const mzero :: e -> m a) - + catchIfMPlus :: forall m e a. (MonadPlus m, MonadCatch m, Exception e) => (e -> Bool) -> m a -> m a catchIfMPlus p act = catchIf p act (const mzero) @@ -703,7 +704,7 @@ shortCircuitM sc binOp mx my = do x <- mx if | sc x -> return x - | otherwise -> binOp <$> pure x <*> my + | otherwise -> binOp x <$> my guardM :: MonadPlus m => m Bool -> m () @@ -800,7 +801,7 @@ mconcatForM = flip mconcatMapM findM :: (Monad m, Foldable f) => (a -> MaybeT m b) -> f a -> m (Maybe b) findM f = runMaybeT . Fold.foldr (\x as -> f x <|> as) mzero - + yesodTimeout :: ( MonadHandler m , MonadUnliftIO m ) @@ -832,7 +833,7 @@ peekN n = do peeked <- catMaybes <$> replicateM (fromIntegral n) await mapM_ leftover peeked return peeked - + anyMC, allMC :: forall a o m. Monad m => (a -> m Bool) -> ConduitT a o m Bool anyMC f = C.mapM f .| orC allMC f = C.mapM f .| andC @@ -874,7 +875,7 @@ choice = foldr (<|>) empty ------------- -- Cookies -- ------------- - + -- Moved to Utils.Cookies.Registered -------------------- @@ -1170,8 +1171,7 @@ instance (Eq k, Hashable k, FromJSON v, FromJSONKey k, Semigroup v) => FromJSON Aeson.FromJSONKeyTextParser f -> Aeson.withObject "HashMap" $ fmap MergeHashMap . HashMap.foldrWithKey (\k v m -> HashMap.insertWith (<>) <$> f k Aeson. Aeson.Key k <*> parseJSON v Aeson. Aeson.Key k <*> m) (pure mempty) Aeson.FromJSONKeyValue f -> Aeson.withArray "Map" $ \arr -> - fmap (MergeHashMap . HashMap.fromListWith (<>)) . sequence . - zipWith (parseIndexedJSONPair f parseJSON) [0..] $ otoList arr + fmap (MergeHashMap . HashMap.fromListWith (<>)) . zipWithM (parseIndexedJSONPair f parseJSON) [0..] $ otoList arr where uc :: Aeson.Parser (HashMap Text v) -> Aeson.Parser (MergeHashMap k v) uc = unsafeCoerce diff --git a/src/Utils/Allocation.hs b/src/Utils/Allocation.hs index 323985f6a..08ce49bd4 100644 --- a/src/Utils/Allocation.hs +++ b/src/Utils/Allocation.hs @@ -20,7 +20,7 @@ import Control.Monad.Writer (tell) import Control.Monad.ST -import Data.List ((!!), elemIndex) +import Data.List ((!!)) type CourseIndex = Int @@ -85,7 +85,7 @@ computeMatchingLog g cloneCounts capacities preferences centralNudge = writer $ courses' <- lift . lift . MArr.newListArray courseBounds . map initCourse $ Set.toAscList courses :: RandT randomGen (WriterT _ (ST s)) (STArray s CourseIndex (Either (Set (student, CloneIndex)) (Seq (student, CloneIndex)))) stPrefs <- lift . lift $ MArr.newArray studentBounds [] :: RandT randomGen (WriterT _ (ST s)) (STArray s (StudentIndex, CloneIndex) [course]) - forM_ clonedStudents $ \(st, cn) -> + forM_ clonedStudents $ \(st, cn) -> lift . lift . MArr.writeArray stPrefs (st ^. contStudents, cn) $ studentPrefs cstb (st, cn) let @@ -127,11 +127,11 @@ computeMatchingLog g cloneCounts capacities preferences centralNudge = writer $ (newSpots, lostSpots) = force . Seq.splitAt capacity $ betterSpots <> Seq.singleton (st, cn) <> worseSpots isUnstableWith :: CloneIndex -> (student, CloneIndex) -> Bool - isUnstableWith cn' (stO, cnO) = fromMaybe False $ do + isUnstableWith cn' (stO, cnO) = Just True == (do c' <- matchingCourse st cn' rMe <- courseRating c' (st, cn') rOther <- courseRating c' (stO, cnO) - return $ LT == compare (rMe, stb (st, cn')) (rOther, stb (stO, cnO)) + return $ LT == compare (rMe, stb (st, cn')) (rOther, stb (stO, cnO))) if | any (uncurry isUnstableWith) $ (,) <$> [0,1..pred cn] <*> toList lostSpots -> lift . tell . pure $ MatchingNoApplyCloneInstability st (fromIntegral cn) c @@ -181,10 +181,10 @@ computeMatchingLog g cloneCounts capacities preferences centralNudge = writer $ -- caRb <- hoistMaybe $ rank (b, cnb) ca -- cbRa <- hoistMaybe $ rank (a, cna) cb -- cbRb <- hoistMaybe $ rank (b, cnb) cb - + -- let currentRanks cop = caRa `cop` cbRb -- newRanks cop = cbRa `cop` caRb - + -- swapImproves = or -- [ currentRanks (+) > newRanks (+) -- , currentRanks (+) == newRanks (+) @@ -239,7 +239,7 @@ computeMatchingLog g cloneCounts capacities preferences centralNudge = writer $ cloneIndices :: cloneIndex -> cloneCount -> Set CloneIndex cloneIndices firstClone clones = Set.fromList $ map fromIntegral [firstClone, pred $ firstClone + fromIntegral clones] - + clonedStudents :: Set (student, CloneIndex) clonedStudents = Set.fromDistinctAscList $ do (student, (firstClone, clones)) <- Map.toAscList cloneCounts @@ -266,7 +266,7 @@ computeMatchingLog g cloneCounts capacities preferences centralNudge = writer $ contCourses = iso toInt fromInt where courses' = Set.toAscList courses - + toInt = fromMaybe (error "trying to resolve unknown course") . flip elemIndex courses' fromInt = (!!) courses' diff --git a/src/Utils/Cookies/Registered.hs b/src/Utils/Cookies/Registered.hs index e94afb763..14a91c9fe 100644 --- a/src/Utils/Cookies/Registered.hs +++ b/src/Utils/Cookies/Registered.hs @@ -44,7 +44,7 @@ _CookieEncoded :: Prism' Text Text _CookieEncoded = prism' cEncode cDecode where b64Prefix = "base64url:" - + cDecode t | Just encoded <- Text.stripPrefix b64Prefix t = either (const Nothing) Just . Text.decodeUtf8' <=< either (const Nothing) Just . Base64.decode $ Text.encodeUtf8 encoded @@ -60,14 +60,14 @@ _CookieEncoded = prism' cEncode cDecode newtype RegisteredCookieCurrentValue = RegisteredCookieCurrentValue { getRegisteredCookieCurrentValue :: Maybe Text } deriving (Eq, Ord, Read, Show, Generic, Typeable) - + -- Primitive setRegisteredCookie' :: (Textual t, MonadHandler m, Yesod (HandlerSite m), HasCookieSettings RegisteredCookie (HandlerSite m)) => (SetCookie -> SetCookie) -> RegisteredCookie -> t -> m () setRegisteredCookie' modSet ident@(toPathPiece -> name) (review _CookieEncoded . repack -> content) = do path <- getCookiePath defSetCookie <- cookieSettingsToSetCookie . ($ ident) =<< getsYesod getCookieSettings - + setCookie $ modSet defSetCookie { setCookieName = Text.encodeUtf8 name , setCookieValue = Text.encodeUtf8 content @@ -114,7 +114,7 @@ deleteRegisteredCookie :: (MonadHandler m, Yesod (HandlerSite m)) => RegisteredC deleteRegisteredCookie name = deleteRegisteredCookie' name . Text.decodeUtf8 =<< getCookiePath -- Primitive -lookupRegisteredCookies :: (Textual t, Monoid m, MonadHandler f) => (t -> m) -> RegisteredCookie -> f m +lookupRegisteredCookies :: (Textual t, Monoid m, MonadHandler f) => (t -> m) -> RegisteredCookie -> f m lookupRegisteredCookies toM (toPathPiece -> name) = do cachedVal <- cacheByGet (Text.encodeUtf8 name) case cachedVal of diff --git a/src/Utils/Csv.hs b/src/Utils/Csv.hs index 0c071f864..c291ba7ee 100644 --- a/src/Utils/Csv.hs +++ b/src/Utils/Csv.hs @@ -11,10 +11,10 @@ module Utils.Csv import ClassyPrelude hiding (lookup) import Settings.Mime - + import Data.Csv hiding (Name) import Data.Csv.Conduit (CsvParseError) - + import Language.Haskell.TH (Name) import Language.Haskell.TH.Lib @@ -63,7 +63,7 @@ toCsvRendered :: forall mono. toCsvRendered csvRenderedHeader (otoList -> csvs) = CsvRendered{..} where csvRenderedData = map toNamedRecord csvs - + toDefaultOrderedCsvRendered :: forall mono. ( ToNamedRecord (Element mono) , DefaultOrdered (Element mono) diff --git a/src/Utils/DB.hs b/src/Utils/DB.hs index d33c5703f..8e0337492 100644 --- a/src/Utils/DB.hs +++ b/src/Utils/DB.hs @@ -33,7 +33,7 @@ getJustBy u = getBy u >>= maybe getKeyBy :: (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, PersistUniqueRead backend, MonadIO m) => Unique record -> ReaderT backend m (Maybe (Key record)) getKeyBy u = fmap entityKey <$> getBy u -- TODO optimize this, so that DB does not deliver entire record! - + getKeyJustBy :: (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, PersistUniqueRead backend, MonadIO m, MonadThrow m, Show (Unique record)) => Unique record -> ReaderT backend m (Key record) getKeyJustBy u = getKeyBy u >>= maybe @@ -46,7 +46,7 @@ getKeyBy404 u = getKeyBy u >>= maybe notFound return getEntity404 :: (PersistStoreRead backend, PersistRecordBackend val backend, MonadHandler m) => Key val -> ReaderT backend m (Entity val) -getEntity404 k = Entity <$> pure k <*> get404 k +getEntity404 k = Entity k <$> get404 k existsBy :: (PersistEntityBackend record ~ BaseBackend backend, PersistEntity record, PersistUniqueRead backend, MonadIO m) => Unique record -> ReaderT backend m Bool diff --git a/src/Utils/DateTime.hs b/src/Utils/DateTime.hs index 01b009acf..27b30c9bf 100644 --- a/src/Utils/DateTime.hs +++ b/src/Utils/DateTime.hs @@ -44,7 +44,7 @@ import Algebra.Lattice import Algebra.Lattice.Ordered import Control.Monad.Fail - + -- $(timeLocaleMap _) :: [Lang] -> TimeLocale timeLocaleMap :: [(Lang, String)] -- ^ Languages and matching locales, first is taken as default @@ -55,7 +55,7 @@ timeLocaleMap extra@((_, defLocale):_) = do let langs = NonEmpty.fromList $ map fst extra - + localeMap' = funD localeMap $ map matchLang extra ++ [defaultLang] defaultLang :: ClauseQ @@ -69,7 +69,7 @@ timeLocaleMap extra@((_, defLocale):_) = do localeExp :: String -> ExpQ localeExp = lift <=< runIO . getLocale . Just - + letE [localeMap'] (varE localeMap) currentYear :: ExpQ @@ -83,7 +83,7 @@ class FormatTime t => HasLocalTime t where instance HasLocalTime LocalTime where toLocalTime = id - + instance HasLocalTime Day where toLocalTime d = LocalTime d midnight @@ -118,7 +118,7 @@ instance Lattice SelDateTimeFormat where instance BoundedJoinSemiLattice SelDateTimeFormat where bottom = SelFormatTime - + instance BoundedMeetSemiLattice SelDateTimeFormat where top = SelFormatDateTime diff --git a/src/Utils/Failover.hs b/src/Utils/Failover.hs index e8c51dae7..ea3dec8d5 100644 --- a/src/Utils/Failover.hs +++ b/src/Utils/Failover.hs @@ -75,7 +75,7 @@ mkFailover :: MonadIO m => PointedList a -> m (Failover a) mkFailover opts = fmap Failover . liftIO $ newTVarIO opts' - where opts' = flip (iover $ indexing traverse) opts $ \i failoverValue -> FailoverItem{ failoverLabel = tshow i, failoverLastTest = Nothing, failoverReferences = Set.empty, .. } + where opts' = flip (iover $ indexing traverse) opts $ \i failoverValue -> FailoverItem{ failoverLabel = tshow i, failoverLastTest = Nothing, failoverReferences = Set.empty, .. } mkFailoverLabeled :: MonadIO m => PointedList (Text, a) @@ -98,7 +98,7 @@ withFailoverReference :: (MonadIO m, MonadMask m) -> m b withFailoverReference Failover{..} cont = do ref <- liftIO newUnique - finally (cont ref) $ + finally (cont ref) $ atomically . modifyTVar failover $ traverse . _failoverReferences %~ Set.delete ref diff --git a/src/Utils/Files.hs b/src/Utils/Files.hs index 8ccf64b13..284a4a890 100644 --- a/src/Utils/Files.hs +++ b/src/Utils/Files.hs @@ -29,7 +29,7 @@ import Control.Monad.Trans.Resource (allocate) sinkFiles :: (MonadThrow m, MonadHandler m, HandlerSite m ~ UniWorX, MonadUnliftIO m, BackendCompatible SqlBackend (YesodPersistBackend UniWorX), YesodPersist UniWorX) => ConduitT File FileReference (SqlPersistT m) () sinkFiles = C.mapM sinkFile - + sinkFile :: (MonadThrow m, MonadHandler m, HandlerSite m ~ UniWorX, MonadUnliftIO m, BackendCompatible SqlBackend (YesodPersistBackend UniWorX), YesodPersist UniWorX) => File -> SqlPersistT m FileReference sinkFile File{ fileContent = Nothing, .. } = return FileReference { fileReferenceContent = Nothing @@ -44,9 +44,9 @@ sinkFile File{ fileContent = Just fileContentContent, .. } = do insert FileLock{ fileLockContent = fileContentHash, .. } releaseLock lId = liftHandler . runDB $ (withReaderT projectBackend $ setSerializable (delete lId :: SqlPersistT (HandlerFor UniWorX) ()) :: YesodDB UniWorX ()) in unliftIO $ allocate (unliftIO takeLock) (unliftIO . releaseLock) - + inDB <- exists [ FileContentHash ==. fileContentHash ] - + let sinkFileDB = unless inDB $ repsert (FileContentKey fileContentHash) FileContent{ fileContentUnreferencedSince = Nothing, .. } maybeT sinkFileDB $ do let uploadName = decodeUtf8 . Base64.encodeUnpadded $ ByteArray.convert fileContentHash @@ -68,7 +68,7 @@ sinkFile File{ fileContent = Just fileContentContent, .. } = do } where fileContentHash = Crypto.hash fileContentContent - + sinkFiles' :: (MonadThrow m, MonadHandler m, HandlerSite m ~ UniWorX, MonadUnliftIO m, BackendCompatible SqlBackend (YesodPersistBackend UniWorX), YesodPersist UniWorX, HasFileReference record) => ConduitT (File, FileReferenceResidual record) record (SqlPersistT m) () sinkFiles' = C.mapM $ uncurry sinkFile' diff --git a/src/Utils/Form.hs b/src/Utils/Form.hs index e24753d90..f3e8461b1 100644 --- a/src/Utils/Form.hs +++ b/src/Utils/Form.hs @@ -165,7 +165,7 @@ addDatalist mkOptions field = field noValidate :: FieldSettings site -> FieldSettings site noValidate = addAttr "formnovalidate" "" - + noAutocomplete :: FieldSettings site -> FieldSettings site noAutocomplete = addAttr "autocomplete" "off" @@ -718,9 +718,9 @@ selectField' optMsg mkOpts = Field{..} let rendered = case val of Left _ -> "" - Right a -> maybe "" optionExternalValue . listToMaybe $ filter ((== a) . optionInternalValue) olOptions + Right a -> maybe "" optionExternalValue $ find ((== a) . optionInternalValue) olOptions - isSel Nothing = not $ rendered `elem` map optionExternalValue olOptions + isSel Nothing = rendered `notElem` map optionExternalValue olOptions isSel (Just opt) = rendered == optionExternalValue opt [whamlet| $newline never @@ -757,9 +757,9 @@ radioField' optMsg mkOpts = Field{..} let rendered = case val of Left _ -> "" - Right a -> maybe "" optionExternalValue . listToMaybe $ filter ((== a) . optionInternalValue) olOptions + Right a -> maybe "" optionExternalValue $ find ((== a) . optionInternalValue) olOptions - isSel Nothing = not $ rendered `elem` map optionExternalValue olOptions + isSel Nothing = rendered `notElem` map optionExternalValue olOptions isSel (Just opt) = rendered == optionExternalValue opt [whamlet| $newline never @@ -800,9 +800,9 @@ radioGroupField optMsg mkOpts = Field{..} let rendered = case val of Left _ -> "" - Right a -> maybe "" optionExternalValue . listToMaybe $ filter ((== a) . optionInternalValue) olOptions + Right a -> maybe "" optionExternalValue $ find ((== a) . optionInternalValue) olOptions - isSel Nothing = not $ rendered `elem` map optionExternalValue olOptions + isSel Nothing = rendered `notElem` map optionExternalValue olOptions isSel (Just opt) = rendered == optionExternalValue opt [whamlet| $newline never @@ -820,7 +820,7 @@ radioGroupField optMsg mkOpts = Field{..} #{optionDisplay opt} |] - + ----------- -- Forms -- ----------- @@ -885,9 +885,7 @@ renderFieldViews :: ( RenderMessage site AFormMessage ) => FormLayout -> [FieldView site] -> WidgetT site IO () renderFieldViews layout - = join - . fmap (view _1) - . generateFormPost + = view _1 <=< generateFormPost . lmap (const mempty) . renderWForm layout . (FormSuccess () <$) @@ -1160,7 +1158,7 @@ wFormFields = mapRWST (fmap (\((a, s, w'), w) -> ((a, w), s, w')) . censor (cons -- Special variants of @mopt@, @mreq@, ... -- --------------------------------------------- - + data ValueRequired site = forall msg. RenderMessage site msg => ValueRequired msg mreq :: forall m a. @@ -1168,21 +1166,21 @@ mreq :: forall m a. , RenderMessage (HandlerSite m) (ValueRequired (HandlerSite m)) ) => Field m a -> FieldSettings (HandlerSite m) -> Maybe a -> MForm m (FormResult a, FieldView (HandlerSite m)) -mreq f fs@FieldSettings{..} mdef = mreqMsg f fs (ValueRequired fsLabel) mdef +mreq f fs@FieldSettings{..} = mreqMsg f fs $ ValueRequired fsLabel wreq :: forall m a. ( MonadHandler m , RenderMessage (HandlerSite m) (ValueRequired (HandlerSite m)) ) => Field m a -> FieldSettings (HandlerSite m) -> Maybe a -> WForm m (FormResult a) -wreq f fs@FieldSettings{..} mdef = wreqMsg f fs (ValueRequired fsLabel) mdef +wreq f fs@FieldSettings{..} = wreqMsg f fs $ ValueRequired fsLabel areq :: forall m a. ( MonadHandler m , RenderMessage (HandlerSite m) (ValueRequired (HandlerSite m)) ) => Field m a -> FieldSettings (HandlerSite m) -> Maybe a -> AForm m a -areq f fs@FieldSettings{..} mdef = areqMsg f fs (ValueRequired fsLabel) mdef +areq f fs@FieldSettings{..} = areqMsg f fs $ ValueRequired fsLabel mforced :: (site ~ HandlerSite m, MonadHandler m) diff --git a/src/Utils/Lens.hs b/src/Utils/Lens.hs index a08246da3..4dae872f8 100644 --- a/src/Utils/Lens.hs +++ b/src/Utils/Lens.hs @@ -8,7 +8,7 @@ import Import.NoModel import Model import Model.Rating import qualified ClassyPrelude.Yesod as Yesod (HasHttpManager(..)) - + import Control.Lens as Utils.Lens hiding ( (<.>) , universe @@ -106,14 +106,14 @@ _entityVal = ilens ((,) <$> entityKey <*> entityVal) (\e v -> e { entityVal = v _Entity :: Iso (Entity record) (Entity record') (Key record, record) (Key record', record') _Entity = iso ((,) <$> entityKey <*> entityVal) (uncurry Entity) - + instance HasStudyFeatures a => HasStudyFeatures (Entity a) where hasStudyFeatures = _entityVal . hasStudyFeatures instance HasStudyTerms a => HasStudyTerms (Entity a) where hasStudyTerms = _entityVal . hasStudyTerms - + instance HasStudyDegree a => HasStudyDegree (Entity a) where hasStudyDegree = _entityVal . hasStudyDegree @@ -203,7 +203,7 @@ makeLenses_ ''CourseUserNote makeLenses_ ''CourseParticipant makeLenses_ ''CourseApplication - + makeLenses_ ''Allocation makeLenses_ ''Submission @@ -224,7 +224,7 @@ makeLenses_ ''AllocationUser makeLenses_ ''Tutorial makeLenses_ ''SessionFile - + makeLenses_ ''ExternalExam makeLenses_ ''ExternalExamOfficeSchool makeLenses_ ''ExternalExamStaff diff --git a/src/Utils/Lens/TH.hs b/src/Utils/Lens/TH.hs index e52157a18..34af447b7 100644 --- a/src/Utils/Lens/TH.hs +++ b/src/Utils/Lens/TH.hs @@ -69,7 +69,7 @@ makeClassyFor_ recName = makeFieldOptics (classyRulesFor_ clNamer) recName where clsName = "Has" <> nameBase recName funName = "has" <> nameBase recName - + clNamer :: ClassyNamer -- clNamer _ = Just (clsName, funName) -- for newer versions >= 4.17 clNamer _ = Just (mkName clsName, mkName funName) diff --git a/src/Utils/Metrics.hs b/src/Utils/Metrics.hs index f4d942b1d..514b6d1ca 100644 --- a/src/Utils/Metrics.hs +++ b/src/Utils/Metrics.hs @@ -24,6 +24,8 @@ import qualified Network.HTTP.Types as HTTP import Yesod.Core.Types (HandlerData(..), GHState(..)) +{-# ANN module ("HLint: ignore Use even" :: String) #-} + histogramBuckets :: Rational -- ^ min -> Rational -- ^ max @@ -40,7 +42,7 @@ histogramBuckets bMin bMax = map fromRational . takeWhile (<= bMax) . go bMin $ where bMin' :: Integer bMin' = floor . List.head . dropWhile (< 1) $ List.iterate (* 10) bMin - + {-# NOINLINE healthReportTime #-} healthReportTime :: Vector Label2 Gauge @@ -152,7 +154,7 @@ registerReadyMetric = liftIO $ void . register . readyMetric =<< getPOSIXTime withJobWorkerStateLbls :: (MonadIO m, MonadMask m) => Label4 -> m a -> m a withJobWorkerStateLbls newLbls act = do liftIO $ withLabel jobWorkerStateTransitions newLbls incCounter - + start <- liftIO $ getTime Monotonic res <- handleAll (return . Left) $ Right <$> act end <- liftIO $ getTime Monotonic @@ -160,7 +162,7 @@ withJobWorkerStateLbls newLbls act = do liftIO . withLabel jobWorkerStateDuration newLbls . flip observe . realToFrac $ end - start either throwM return res - + observeYesodCacheSize :: MonadHandler m => m () observeYesodCacheSize = do HandlerData{handlerState} <- liftHandler ask diff --git a/src/Utils/Occurrences.hs b/src/Utils/Occurrences.hs index 6b4051d89..ecd495dc4 100644 --- a/src/Utils/Occurrences.hs +++ b/src/Utils/Occurrences.hs @@ -50,7 +50,7 @@ normalizeOccurrences initial | otherwise = Nothing merge _ = Nothing - merges <- views _occurrencesScheduled $ mapMaybe (\b -> (,) <$> pure b <*> merge b) . Set.toList . Set.delete a + merges <- views _occurrencesScheduled $ mapMaybe (\b -> (b, ) <$> merge b) . Set.toList . Set.delete a case merges of [] -> return () ((b, merged) : _) -> throwE =<< asks (over _occurrencesScheduled $ Set.insert merged . Set.delete b . Set.delete a) diff --git a/src/Utils/Parameters.hs b/src/Utils/Parameters.hs index 2ca4e2573..f056be9c6 100644 --- a/src/Utils/Parameters.hs +++ b/src/Utils/Parameters.hs @@ -73,11 +73,11 @@ lookupGlobalPostParam ident = (>>= fromPathPiece) <$> lookupPostParam (toPathPie hasGlobalPostParam :: MonadHandler m => GlobalPostParam -> m Bool hasGlobalPostParam ident = isJust <$> lookupPostParam (toPathPiece ident) - + lookupGlobalPostParams :: (MonadHandler m, PathPiece result) => GlobalPostParam -> m [result] lookupGlobalPostParams ident = mapMaybe fromPathPiece <$> lookupPostParams (toPathPiece ident) - + lookupGlobalPostParamForm :: (Monad m, PathPiece result) => GlobalPostParam -> MForm m (Maybe result) lookupGlobalPostParamForm ident = runMaybeT $ do ps <- MaybeT askParams diff --git a/src/Utils/PathPiece.hs b/src/Utils/PathPiece.hs index 8c429964f..11be9154b 100644 --- a/src/Utils/PathPiece.hs +++ b/src/Utils/PathPiece.hs @@ -36,7 +36,7 @@ import Control.Monad.Fail import Data.Binary (Binary) import qualified Data.Binary as Binary - + mkFiniteFromPathPiece :: Name -> Q ([Dec], Exp) mkFiniteFromPathPiece finiteType = do @@ -132,8 +132,8 @@ derivePathPiece adt mangle joinPP = do , clause [wildP] (normalB [e|Nothing|]) [] ] ] - - + + splitCamel :: Textual t => t -> [t] splitCamel = map fromList . reverse . helper (error "hasChange undefined at start of string") [] "" . otoList where @@ -169,7 +169,7 @@ tuplePathPiece tupleDim = do let tupleSeparator :: Text tupleSeparator = "," - + xs <- replicateM tupleDim $ newName "x" :: Q [Name] xs' <- replicateM tupleDim $ newName "x'" :: Q [Name] diff --git a/src/Utils/PersistentTokenBucket.hs b/src/Utils/PersistentTokenBucket.hs index 667898003..ca9f05f22 100644 --- a/src/Utils/PersistentTokenBucket.hs +++ b/src/Utils/PersistentTokenBucket.hs @@ -5,7 +5,7 @@ module Utils.PersistentTokenBucket ) where import Import.NoFoundation - + import qualified Data.Conduit.Combinators as C @@ -23,7 +23,7 @@ persistentTokenBucketTryAlloc' :: (MonadHandler m, HasAppSettings (HandlerSite m -> SqlPersistT m Bool persistentTokenBucketTryAlloc' tbsIdent tokens = do TokenBucketConf{..} <- getsYesod $ views _appPersistentTokenBuckets ($ tbsIdent) - persistentTokenBucketTryAlloc TokenBucketSettings + persistentTokenBucketTryAlloc TokenBucketSettings { tbsIdent , tbsDepth = tokenBucketDepth , tbsInvRate = tokenBucketInvRate @@ -65,7 +65,7 @@ persistentTokenBucketTakeC' :: forall i m a. -> ConduitT i i (ReaderT SqlBackend m) () persistentTokenBucketTakeC' tbsIdent cTokens = do TokenBucketConf{..} <- getsYesod $ views _appPersistentTokenBuckets ($ tbsIdent) - persistentTokenBucketTakeC TokenBucketSettings + persistentTokenBucketTakeC TokenBucketSettings { tbsIdent , tbsDepth = tokenBucketDepth , tbsInvRate = tokenBucketInvRate @@ -78,7 +78,7 @@ persistentTokenBucketTakeC :: forall i m a. -> (i -> a) -> ConduitT i i (ReaderT SqlBackend m) () persistentTokenBucketTakeC tbs cTokens = C.mapAccumWhileM tbAccum () - where tbAccum :: i + where tbAccum :: i -> () -> SqlPersistT m (Either () ((), i)) tbAccum x () diff --git a/src/Utils/Sql.hs b/src/Utils/Sql.hs index b3ad49706..2a03a76da 100644 --- a/src/Utils/Sql.hs +++ b/src/Utils/Sql.hs @@ -20,7 +20,7 @@ import Control.Lens ((&)) setSerializable :: forall m a. (MonadLogger m, MonadMask m, MonadIO m, ReadLogSettings (SqlPersistT m)) => SqlPersistT m a -> SqlPersistT m a setSerializable = setSerializable' $ fullJitterBackoff 1e3 & limitRetriesByCumulativeDelay 10e6 - + setSerializable' :: forall m a. (MonadLogger m, MonadMask m, MonadIO m, ReadLogSettings (SqlPersistT m)) => RetryPolicyM (SqlPersistT m) -> SqlPersistT m a -> ReaderT SqlBackend m a setSerializable' policy act = do LogSettings{logSerializableTransactionRetryLimit} <- readLogSettings @@ -29,7 +29,7 @@ setSerializable' policy act = do where suggestRetry :: SqlError -> ReaderT SqlBackend m Bool suggestRetry = return . isSerializationError - + logRetry :: Maybe Natural -> Bool -- ^ Will retry -> SqlError @@ -55,4 +55,4 @@ setSerializable' policy act = do return res - + diff --git a/src/Utils/Tokens.hs b/src/Utils/Tokens.hs index 2a23db3b9..f29aa5da9 100644 --- a/src/Utils/Tokens.hs +++ b/src/Utils/Tokens.hs @@ -67,7 +67,7 @@ bearerToken bearerAuthority bearerRoutes bearerAddAuth mBearerExpiresAt bearerSt bearerIssuedFor <- getsYesod $ view clusterID defaultExpiration <- getsYesod $ view _appBearerExpiration - + let bearerExpiresAt | Just t <- mBearerExpiresAt = t diff --git a/src/Web/ServerSession/Backend/Persistent/Memcached.hs b/src/Web/ServerSession/Backend/Persistent/Memcached.hs index bdf4df53b..b2a56a396 100644 --- a/src/Web/ServerSession/Backend/Persistent/Memcached.hs +++ b/src/Web/ServerSession/Backend/Persistent/Memcached.hs @@ -17,7 +17,7 @@ import Web.ServerSession.Core import Database.Persist.Sql (ConnectionPool, runSqlPool) import qualified Data.Binary as Binary - + import qualified Database.Memcached.Binary.IO as Memcached import qualified Crypto.Saltine.Class as Saltine @@ -111,7 +111,7 @@ instance (IsSessionData sess, Binary (Decomposed sess)) => Storage (MemcachedSql runTransactionM MemcachedSqlStorage{..} = flip runSqlPool mcdSqlConnPool getSession MemcachedSqlStorage{..} sessId = exceptT (maybe (return Nothing) throwM) (return . Just) $ do - encSession <- catchIfExceptT (\_ -> Nothing) Memcached.isKeyNotFound . liftIO . fmap LBS.toStrict $ Memcached.getAndTouch_ expiry (memcachedSqlSessionId # sessId) mcdSqlMemcached + encSession <- catchIfExceptT (const Nothing) Memcached.isKeyNotFound . liftIO . fmap LBS.toStrict $ Memcached.getAndTouch_ expiry (memcachedSqlSessionId # sessId) mcdSqlMemcached guardExceptT (BS.length encSession >= Saltine.secretBoxNonce + Saltine.secretBoxMac) $ Just MemcachedSqlStorageAEADCiphertextTooShort @@ -129,10 +129,10 @@ instance (IsSessionData sess, Binary (Decomposed sess)) => Storage (MemcachedSql expiration <- runMaybeT $ fmap (memcachedSessionExpirationTime . entityVal) . MaybeT . lift . getBy . UniqueMemcachedSessionExpiration =<< hoistMaybe mcdSqlSessionAuthId guardExceptT (maybe True (mcdSqlSessionCreatedAt >) expiration) Nothing - + return $ (sessId, decoded) ^. memcachedSqlSession - where expiry = maybe 0 ceiling mcdSqlMemcachedExpiration + where expiry = maybe 0 ceiling mcdSqlMemcachedExpiration deleteSession MemcachedSqlStorage{..} sessId = liftIO . handleIf Memcached.isKeyNotFound (const $ return ()) $ Memcached.delete (memcachedSqlSessionId # sessId) mcdSqlMemcached @@ -161,7 +161,7 @@ replaceSession' isReplace s@MemcachedSqlStorage{..} seNewSession@(review memcach whenIsJust mOld $ \seExistingSession -> throwM @_ @(StorageException (MemcachedSqlStorage sess)) $ SessionAlreadyExists{..} - nonce <- liftIO $ AEAD.newNonce + nonce <- liftIO AEAD.newNonce let encSession = Saltine.encode nonce <> AEAD.aead mcdSqlMemcachedKey nonce encoded encSessId encSessId = LBS.toStrict $ Binary.encode sessId handleFailure @@ -172,4 +172,4 @@ replaceSession' isReplace s@MemcachedSqlStorage{..} seNewSession@(review memcach where encoded = LBS.toStrict $ Binary.encode decoded - expiry = maybe 0 ceiling mcdSqlMemcachedExpiration + expiry = maybe 0 ceiling mcdSqlMemcachedExpiration diff --git a/src/Web/ServerSession/Frontend/Yesod/Jwt.hs b/src/Web/ServerSession/Frontend/Yesod/Jwt.hs index e4297a510..341fb2291 100644 --- a/src/Web/ServerSession/Frontend/Yesod/Jwt.hs +++ b/src/Web/ServerSession/Frontend/Yesod/Jwt.hs @@ -35,7 +35,7 @@ import qualified Data.Aeson as JSON instance Universe ForceInvalidate instance Finite ForceInvalidate -finitePathPiece ''ForceInvalidate +finitePathPiece ''ForceInvalidate [ "current", "all", "none" ] @@ -86,7 +86,7 @@ backend jwtCfg getApprootText' state = pure $ Just SessionBackend{..} approot' = getApprootText' req return (sessionData, save) - + findSession :: State sto -> Wai.Request -> Maybe Jwt @@ -130,7 +130,7 @@ createCookie state approot' session (Jwt payload) = AddCookie def , setCookieSecure = getSecureCookies state } - + decodeSession :: ( MonadThrow m , MonadIO m ) @@ -157,7 +157,7 @@ encodeSession :: MonadIO m => ServerSessionJwtConfig -> SessionToken sess -> m Jwt -encodeSession ServerSessionJwtConfig{..} token = liftIO $ +encodeSession ServerSessionJwtConfig{..} token = liftIO $ either throwM return =<< Jose.encode (Jose.keys sJwtJwkSet) sJwtEncoding payload where payload = Jose.Claims . toStrict $ JSON.encode token diff --git a/src/Yesod/Core/Instances.hs b/src/Yesod/Core/Instances.hs index 17838c4b8..76e480a8f 100644 --- a/src/Yesod/Core/Instances.hs +++ b/src/Yesod/Core/Instances.hs @@ -54,7 +54,7 @@ routeToPathPiece instance (RenderRoute site, ParseRoute site) => PathPiece (Route site) where fromPathPiece = routeFromPathPiece toPathPiece = routeToPathPiece - + instance ParseRoute site => FromJSON (Route site) where parseJSON = withText "Route" $ maybe (fail "Could not parse route") return . routeFromPathPiece diff --git a/src/Yesod/Core/Types/Instances.hs b/src/Yesod/Core/Types/Instances.hs index e05f92f0d..924c27673 100644 --- a/src/Yesod/Core/Types/Instances.hs +++ b/src/Yesod/Core/Types/Instances.hs @@ -33,7 +33,7 @@ import Control.Monad.Morph (MFunctor, MMonad) deriving via (ReaderT (HandlerData site site) IO) instance MonadFix (HandlerFor site) deriving via (ReaderT (HandlerData sub site) IO) instance MonadFix (SubHandlerFor sub site) deriving via (ReaderT (WidgetData site) IO) instance MonadFix (WidgetFor site) - + deriving via (ReaderT (HandlerData site site) IO) instance MonadCatch (HandlerFor site) deriving via (ReaderT (HandlerData sub site) IO) instance MonadCatch (SubHandlerFor sub site) deriving via (ReaderT (WidgetData site) IO) instance MonadCatch (WidgetFor site) diff --git a/src/Yesod/Form/Fields/Instances.hs b/src/Yesod/Form/Fields/Instances.hs index a35ed24ce..c77b1e4ea 100644 --- a/src/Yesod/Form/Fields/Instances.hs +++ b/src/Yesod/Form/Fields/Instances.hs @@ -13,7 +13,7 @@ deriving instance Foldable Option deriving instance Traversable Option instance Foldable OptionList where - foldMap f OptionList{..} = foldMap (foldMap f) olOptions + foldMap f OptionList{..} = foldMap (foldMap f) olOptions instance Semigroup (OptionList a) where diff --git a/stack.yaml b/stack.yaml index ebd6b03a3..b0eae426c 100644 --- a/stack.yaml +++ b/stack.yaml @@ -151,6 +151,7 @@ extra-deps: - unidecode-0.1.0.4@sha256:99581ee1ea334a4596a09ae3642e007808457c66893b587e965b31f15cbf8c4d,1144 - uuid-crypto-1.4.0.0@sha256:9e2f271e61467d9ea03e78cddad75a97075d8f5108c36a28d59c65abb3efd290,1325 - wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314 + - hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814 resolver: nightly-2020-08-08 allow-newer: true diff --git a/stack.yaml.lock b/stack.yaml.lock index 398eecca6..fd5569286 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -150,6 +150,20 @@ packages: subdir: colonnade git: git@gitlab2.rz.ifi.lmu.de:uni2work/colonnade.git commit: f8170266ab25b533576e96715bedffc5aa4f19fa +- completed: + cabal-file: + size: 9845 + sha256: 674630347209bc5f7984e8e9d93293510489921f2d2d6092ad1c9b8c61b6560a + name: minio-hs + version: 1.5.2 + git: git@gitlab2.rz.ifi.lmu.de:uni2work/minio-hs.git + pantry-tree: + size: 4560 + sha256: c5faff15fa22a7a63f45cd903c9bd11ae03f422c26f24750f5c44cb4d0db70fc + commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1 + original: + git: git@gitlab2.rz.ifi.lmu.de:uni2work/minio-hs.git + commit: 42103ab247057c04c8ce7a83d9d4c160713a3df1 - completed: hackage: acid-state-0.16.0.1@sha256:d43f6ee0b23338758156c500290c4405d769abefeb98e9bc112780dae09ece6f,6207 pantry-tree: @@ -367,6 +381,13 @@ packages: sha256: 6d64803c639ed4c7204ea6fab0536b97d3ee16cdecb9b4a883cd8e56d3c61402 original: hackage: wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314 +- completed: + hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814 + pantry-tree: + size: 442 + sha256: 347eac6c8a3c02fc0101444d6526b57b3c27785809149b12f90d8db57c721fea + original: + hackage: hlint-test-0.1.0.0@sha256:e427c0593433205fc629fb05b74c6b1deb1de72d1571f26142de008f0d5ee7a9,1814 snapshots: - completed: size: 524392