module Handler.Utils ( module Handler.Utils ) where import Import hiding (link) import Data.Map ((!)) import qualified Data.Map as Map import qualified Data.Set as Set import Handler.Utils.DateTime as Handler.Utils import Handler.Utils.Form as Handler.Utils import Handler.Utils.Table as Handler.Utils import Handler.Utils.Zip as Handler.Utils import Handler.Utils.Rating as Handler.Utils hiding (extractRatings) -- import Handler.Utils.Submission as Handler.Utils import Handler.Utils.Sheet as Handler.Utils import Handler.Utils.Mail as Handler.Utils import Handler.Utils.ContentDisposition as Handler.Utils import Handler.Utils.I18n as Handler.Utils import Handler.Utils.Widgets as Handler.Utils import Handler.Utils.Database as Handler.Utils import Handler.Utils.Occurrences as Handler.Utils import Handler.Utils.Memcached as Handler.Utils hiding (manageMemcachedLocalInvalidations) import Handler.Utils.Files as Handler.Utils import Handler.Utils.Download as Handler.Utils import Handler.Utils.AuthorshipStatement as Handler.Utils import Handler.Utils.Term as Handler.Utils import Control.Monad.Logger -- | Prefix a message with a short course id, -- eg. for window title bars, etc. -- This function should help to make this consistent everywhere prependCourseTitle :: (RenderMessage UniWorX msg) => TermId -> SchoolId -> CourseShorthand -> msg -> UniWorXMessages prependCourseTitle tid ssh csh msg = UniWorXMessages [ SomeMessage $ toPathPiece tid , SomeMessage dashText , SomeMessage $ toPathPiece ssh , SomeMessage dashText , SomeMessage csh , SomeMessage colonText , SomeMessage msg ] where dashText :: Text dashText = "-" colonText :: Text colonText = ":" warnTermDays :: (RenderMessage UniWorX msg) => TermId -> Map UTCTime msg -> DB () warnTermDays tid timeNames = do Term{..} <- get404 tid MsgRenderer mr <- getMsgRenderer let alldays = Map.keysSet timeNames warnholidays = let hdays = Set.fromList termHolidays in Set.filter (\(utctDay -> d) -> Set.member d hdays) alldays outoftermdays = Set.filter (\(utctDay -> d) -> d < termStart || d > termEnd ) alldays outoflecture = Set.filter (\(utctDay -> d) -> d < termLectureStart || d > termLectureEnd) alldays `Set.difference` outoftermdays -- out of term implies out of lecture-time warnI msg d = formatTime SelFormatDate d >>= \dt -> addMessageI Warning $ msg tid (mr (timeNames ! d)) dt forM_ warnholidays $ warnI MsgDayIsAHoliday forM_ outoflecture $ warnI MsgDayIsOutOfLecture forM_ outoftermdays $ warnI MsgDayIsOutOfTerm -- | return a value only if the current user ist authorized for a given route guardAuthorizedFor :: ( MonadThrow m , MonadTrans t, MonadPlus (t (ReaderT SqlBackend m)) , MonadAP (ReaderT SqlBackend m) ) => Route UniWorX -> a -> t (ReaderT SqlBackend m) a guardAuthorizedFor link = guardMOn . lift $ hasReadAccessTo link runAppLoggingT :: UniWorX -> LoggingT m a -> m a runAppLoggingT app@(appLogger -> (_, loggerTVar)) = flip runLoggingT logFunc where logFunc loc src lvl str = do f <- messageLoggerSource app <$> readTVarIO loggerTVar f loc src lvl str studyFeaturesWidget :: StudyFeaturesId -> Widget studyFeaturesWidget featId = do (StudyFeatures{studyFeaturesSemester}, (degree, terms)) <- liftHandler . runDB . ($ featId) . runKleisli $ Kleisli getJust >>> Kleisli return &&& Kleisli (getJust . studyFeaturesDegree) &&& Kleisli (getJust . studyFeaturesField) [whamlet| $newline never _{StudyDegreeTerm degree terms}, _{MsgTableStudyFeatureAge} #{studyFeaturesSemester} |] getShowSex :: (MonadHandler m, HandlerSite m ~ UniWorX) => m Bool getShowSex = maybe False (userShowSex . entityVal) <$> maybeAuth -- | Conditional redirect that hides the URL if the user is not authorized for the route redirectAccess :: (MonadHandler m, HandlerSite m ~ UniWorX) => Route (HandlerSite m) -> m a redirectAccess url = liftHandler $ do -- must hide URL if not authorized access <- isAuthorized url False case access of Authorized -> redirect url _ -> permissionDeniedI MsgUnauthorizedRedirect redirectAccessWith :: (MonadHandler m, HandlerSite m ~ UniWorX) => Status -> Route (HandlerSite m) -> m a redirectAccessWith status url = liftHandler $ do -- must hide URL if not authorized access <- isAuthorized url False case access of Authorized -> redirectWith status url _ -> permissionDeniedI MsgUnauthorizedRedirect redirectAlternatives :: (MonadHandler m, HandlerSite m ~ UniWorX) => NonEmpty (Route (HandlerSite m)) -> m a redirectAlternatives = go where go (nunsnoc -> ([], r)) = redirectAccess r go (nunsnoc -> (r' : rs, r)) = liftHandler $ do access <- isAuthorized r' False case access of Authorized -> redirect r' _ -> redirectAlternatives (nsnoc rs r) nunsnoc (x :| xs) = case nonEmpty xs of Nothing -> ([], x) Just xs' -> over _1 (x :) $ nunsnoc xs' nsnoc [] x = x :| [] nsnoc (x' : xs) x = x' :| (xs ++ [x])