chore: bump to lts-15.0

BREAKING CHANGE: major version bumps
This commit is contained in:
Gregor Kleen 2020-02-23 11:12:45 +01:00
parent 06f3ac6563
commit cfaea9c08b
137 changed files with 371 additions and 772 deletions

View File

@ -1,6 +1,6 @@
default: default:
image: image:
name: fpco/stack-build:lts-13.21 name: fpco/stack-build:lts-15.0
cache: cache:
paths: paths:
- node_modules - node_modules

View File

@ -5,6 +5,7 @@
- ignore: { name: "Parse error" } - ignore: { name: "Parse error" }
- ignore: { name: "Reduce duplication" } - ignore: { name: "Reduce duplication" }
- ignore: { name: "Redundant lambda" } - ignore: { name: "Redundant lambda" }
- ignore: { name: "Redundant multi-way if" }
- ignore: { name: "Use ||" } - ignore: { name: "Use ||" }
- ignore: { name: "Use &&" } - ignore: { name: "Use &&" }
- ignore: { name: "Use ++" } - ignore: { name: "Use ++" }

View File

@ -20,4 +20,4 @@ if [[ -d .stack-work-ghci ]]; then
trap move-back EXIT trap move-back EXIT
fi fi
stack ghci --flag uniworx:dev --flag uniworx:library-only --ghci-options -fobject-code ${@:-uniworx:lib} stack ghci --flag uniworx:dev --flag uniworx:library-only --ghci-options ${@:-uniworx:lib}

View File

@ -120,7 +120,6 @@ dependencies:
- lens-aeson - lens-aeson
- systemd - systemd
- streaming-commons - streaming-commons
- hourglass
- unix - unix
- stm-delay - stm-delay
- cassava - cassava
@ -201,6 +200,8 @@ ghc-options:
- -Wall - -Wall
- -Wmissing-home-modules - -Wmissing-home-modules
- -Wredundant-constraints - -Wredundant-constraints
- -Widentities
- -Wincomplete-uni-patterns
- -fno-warn-type-defaults - -fno-warn-type-defaults
- -fno-warn-unrecognised-pragmas - -fno-warn-unrecognised-pragmas
- -fno-warn-partial-type-signatures - -fno-warn-partial-type-signatures

View File

@ -86,8 +86,6 @@ import Control.Monad.Trans.Cont (runContT, callCC)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Semigroup (Min(..))
import Handler.Utils.Routes (classifyHandler) import Handler.Utils.Routes (classifyHandler)
-- Import all relevant handler modules here. -- Import all relevant handler modules here.
@ -511,6 +509,8 @@ shutdownApp app = do
destroyAllResources $ appConnPool app destroyAllResources $ appConnPool app
release . fst $ appLogger app release . fst $ appLogger app
liftIO $ threadDelay 2e4
--------------------------------------------- ---------------------------------------------
-- Functions for use in development with GHCi -- Functions for use in development with GHCi

View File

@ -8,7 +8,6 @@ import Database.Persist.Sql (SqlBackendCanRead)
import Utils.Form import Utils.Form
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
@ -22,7 +21,6 @@ dummyForm :: ( RenderMessage (HandlerSite m) FormMessage
, RenderMessage (HandlerSite m) DummyMessage , RenderMessage (HandlerSite m) DummyMessage
, YesodPersist (HandlerSite m) , YesodPersist (HandlerSite m)
, SqlBackendCanRead (YesodPersistBackend (HandlerSite m)) , SqlBackendCanRead (YesodPersistBackend (HandlerSite m))
, Button (HandlerSite m) ButtonSubmit
, MonadHandler m , MonadHandler m
) => AForm m (CI Text) ) => AForm m (CI Text)
dummyForm = wFormToAForm $ do dummyForm = wFormToAForm $ do

View File

@ -14,14 +14,12 @@ module Auth.LDAP
import Import.NoFoundation import Import.NoFoundation
import Network.Connection import Network.Connection
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import qualified Control.Monad.Catch as Exc import qualified Control.Monad.Catch as Exc
import Utils.Form import Utils.Form
import Ldap.Client (Ldap)
import qualified Ldap.Client as Ldap import qualified Ldap.Client as Ldap
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text

View File

@ -8,7 +8,6 @@ import Database.Persist.Sql (SqlBackendCanRead)
import Utils.Form import Utils.Form
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Yesod.Auth.Util.PasswordStore (verifyPasswordWith) import Yesod.Auth.Util.PasswordStore (verifyPasswordWith)

View File

@ -296,20 +296,21 @@ nextCronMatch tz mPrev prec now c@Cron{..} = onlyOnceWithinPrec $ case notAfter
<*> genMatch 60 True True cdMinute cronMinute <*> genMatch 60 True True cdMinute cronMinute
<*> genMatch 60 True True cdSecond cronSecond <*> genMatch 60 True True cdSecond cronSecond
let toGregorian' = over _1 fromIntegral . over _2 fromIntegral . over _3 fromIntegral . toGregorian let toGregorian' :: Day -> (Natural, Natural, Natural)
toGregorian' = over _1 fromIntegral . over _2 fromIntegral . over _3 fromIntegral . toGregorian
(mCronYear, mCronMonth, mCronDayOfMonth) <- if (mCronYear, mCronMonth, mCronDayOfMonth) <- if
| Just (year, month, dayOfMonth) <- mCronGregorianDate | Just (year, month, dayOfMonth) <- mCronGregorianDate
-> return (year, month, dayOfMonth) -> return (year, month, dayOfMonth)
| Just (weekYear, week, dayOfWeek) <- mCronWeekDate | Just (weekYear, week, dow) <- mCronWeekDate
-> return . toGregorian' $ fromWeekDate (fromIntegral weekYear) (fromIntegral week) (fromIntegral dayOfWeek) -> return . toGregorian' $ fromWeekDate (fromIntegral weekYear) (fromIntegral week) (fromIntegral dow)
| Just (year, dayOfYear) <- mCronOrdinalDate | Just (year, dayOfYear) <- mCronOrdinalDate
-> maybeToList . fmap toGregorian' $ fromOrdinalDateValid (fromIntegral year) (fromIntegral dayOfYear) -> maybeToList . fmap toGregorian' $ fromOrdinalDateValid (fromIntegral year) (fromIntegral dayOfYear)
| Just (weekYear, month, weekOfMonth, dayOfWeek) <- mCronWeekOfMonthDate | Just (weekYear, month, weekOfMonth, dow) <- mCronWeekOfMonthDate
-> do -> do
year <- genMatch 400 False True cdYear cronYear year <- genMatch 400 False True cdYear cronYear
day <- genMatch 31 True False cdDayOfMonth cronDayOfMonth day <- genMatch 31 True False cdDayOfMonth cronDayOfMonth
jDay <- maybeToList $ fromGregorianValid (fromIntegral year) (fromIntegral month) (fromIntegral day) jDay <- maybeToList $ fromGregorianValid (fromIntegral year) (fromIntegral month) (fromIntegral day)
guard $ consistentCronDate (toCronDate localRef{ localDay = jDay }) { cdWeekYear = weekYear, cdMonth = month, cdWeekOfMonth = weekOfMonth, cdDayOfWeek = dayOfWeek } guard $ consistentCronDate (toCronDate localRef{ localDay = jDay }) { cdWeekYear = weekYear, cdMonth = month, cdWeekOfMonth = weekOfMonth, cdDayOfWeek = dow }
return (year, month, day) return (year, month, day)
| otherwise | otherwise
-> fmap toGregorian' [localDay localRef, succ $ localDay localRef] -> fmap toGregorian' [localDay localRef, succ $ localDay localRef]
@ -329,8 +330,8 @@ nextCronMatch tz mPrev prec now c@Cron{..} = onlyOnceWithinPrec $ case notAfter
-> return . over _1 fromIntegral . over _2 fromIntegral . over _3 fromIntegral $ toWeekDate julDay -> return . over _1 fromIntegral . over _2 fromIntegral . over _3 fromIntegral $ toWeekDate julDay
mCronWeekOfMonth <- if mCronWeekOfMonth <- if
| Just (weekYear, month, weekOfMonth, dayOfWeek) <- mCronWeekOfMonthDate | Just (weekYear, month, weekOfMonth, dow) <- mCronWeekOfMonthDate
-> weekOfMonth <$ guard (weekYear == mCronWeekYear && month == mCronMonth && dayOfWeek == mCronDayOfWeek) -> weekOfMonth <$ guard (weekYear == mCronWeekYear && month == mCronMonth && dow == mCronDayOfWeek)
| otherwise | otherwise
-> genMatch 5 True False cdWeekOfMonth cronWeekOfMonth -> genMatch 5 True False cdWeekOfMonth cronWeekOfMonth

View File

@ -15,7 +15,6 @@ import Data.Time
import Numeric.Natural import Numeric.Natural
import Data.HashMap.Strict (HashMap)
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -11,15 +11,12 @@ import Database.Persist
import Database.Persist.Sql import Database.Persist.Sql
import Data.ByteArray (convert) import Data.ByteArray (convert)
import Data.ByteArray.Encoding
import qualified Data.ByteString.Char8 as CBS
import Web.PathPieces import Web.PathPieces
import Web.HttpApiData import Web.HttpApiData
import Data.Aeson as Aeson import Data.Aeson as Aeson
import Text.Read as Read import Control.Monad.Fail
instance HashAlgorithm hash => PersistField (Digest hash) where instance HashAlgorithm hash => PersistField (Digest hash) where
@ -31,12 +28,6 @@ instance HashAlgorithm hash => PersistField (Digest hash) where
instance HashAlgorithm hash => PersistFieldSql (Digest hash) where instance HashAlgorithm hash => PersistFieldSql (Digest hash) where
sqlType _ = SqlBlob sqlType _ = SqlBlob
instance HashAlgorithm hash => Read (Digest hash) where
readPrec = do
str <- replicateM (2 * hashDigestSize (error "Value of type hash forced" :: hash)) Read.get
bs <- either fail return . convertFromBase Base16 $ CBS.pack str
maybe (fail "Could not convert digestFromByteString") return $ digestFromByteString (bs :: ByteString)
instance HashAlgorithm hash => PathPiece (Digest hash) where instance HashAlgorithm hash => PathPiece (Digest hash) where
toPathPiece = showToPathPiece toPathPiece = showToPathPiece
fromPathPiece = readFromPathPiece fromPathPiece = readFromPathPiece

View File

@ -21,10 +21,9 @@ import System.FilePath.Cryptographic.ImplicitNamespace
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.Aeson (ToJSON(..), ToJSONKey(..), ToJSONKeyFunction(..), FromJSON(..), FromJSONKey(..), FromJSONKeyFunction(..), Value(..), withText) import Data.Aeson (withText)
import Data.Aeson.Encoding (text) import Data.Aeson.Encoding (text)
import Text.Blaze (ToMarkup(..)) import Text.Blaze (ToMarkup(..))

View File

@ -9,7 +9,6 @@ import Data.UUID.Types (UUID)
import Data.Binary.SerializationLength import Data.Binary.SerializationLength
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI)
import System.FilePath (FilePath)
import Data.Binary (Binary) import Data.Binary (Binary)
import qualified Data.Binary as Binary import qualified Data.Binary as Binary

View File

@ -16,6 +16,8 @@ import Data.Vector.Instances ()
import Model.Types.TH.JSON (derivePersistFieldJSON) import Model.Types.TH.JSON (derivePersistFieldJSON)
import Control.Monad.Fail
instance MonadThrow Parser where instance MonadThrow Parser where
throwM = fail . show throwM = fail . show

View File

@ -12,6 +12,8 @@ import Data.CaseInsensitive.Instances ()
import qualified Data.Text as Text import qualified Data.Text as Text
import Control.Monad.Fail
instance Csv.ToField Bool where instance Csv.ToField Bool where
toField True = "t" toField True = "t"

View File

@ -16,12 +16,11 @@ import Database.Persist.Sql
import Text.Blaze (ToMarkup(..)) import Text.Blaze (ToMarkup(..))
import Text.Shakespeare.Text (ToText(..)) import Text.Shakespeare.Text (ToText(..))
import Data.Text (Text)
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text
import Language.Haskell.TH.Syntax (Lift(..)) import Language.Haskell.TH.Syntax (Lift(..))
import Data.Aeson (ToJSON(..), FromJSON(..), ToJSONKey(..), FromJSONKey(..), ToJSONKeyFunction(..)) import Data.Aeson (ToJSONKey(..), FromJSONKey(..), ToJSONKeyFunction(..))
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E

View File

@ -6,13 +6,14 @@ module Data.Encoding.Instances
import ClassyPrelude import ClassyPrelude
import Utils.PathPiece import Utils.PathPiece
import Data.String (IsString(..))
import Text.Read import Text.Read
import Web.PathPieces import Web.PathPieces
import Data.Encoding import Data.Encoding
import Control.Monad.Fail
instance PathPiece DynEncoding where instance PathPiece DynEncoding where
toPathPiece = showToPathPiece toPathPiece = showToPathPiece

View File

@ -7,7 +7,6 @@ module Data.HashMap.Strict.Instances
import ClassyPrelude import ClassyPrelude
import Data.Binary (Binary(..)) import Data.Binary (Binary(..))
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap

View File

@ -6,7 +6,6 @@ module Data.HashSet.Instances
import ClassyPrelude import ClassyPrelude
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet import qualified Data.HashSet as HashSet
import Data.Binary (Binary(..)) import Data.Binary (Binary(..))

View File

@ -11,6 +11,8 @@ import Data.Aeson
import Data.Binary (Binary) import Data.Binary (Binary)
import qualified Data.Binary as Binary import qualified Data.Binary as Binary
import Control.Monad.Fail
instance ToJSON a => ToJSON (NonNull a) where instance ToJSON a => ToJSON (NonNull a) where
toJSON = toJSON . toNullable toJSON = toJSON . toNullable

View File

@ -6,7 +6,6 @@ module Data.Set.Instances
import ClassyPrelude import ClassyPrelude
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -7,12 +7,16 @@ module Data.Time.Calendar.Instances
import ClassyPrelude import ClassyPrelude
import Data.Binary (Binary) import Data.Binary (Binary)
import qualified Data.Binary as Binary
import Data.Time.Calendar
import Data.Universe
deriving newtype instance Hashable Day deriving newtype instance Hashable Day
deriving newtype instance Binary Day
instance Binary Day where deriving instance Ord DayOfWeek
get = ModifiedJulianDay <$> Binary.get instance Universe DayOfWeek where
put = Binary.put . toModifiedJulianDay universe = [Monday .. Sunday]
instance Finite DayOfWeek

View File

@ -15,6 +15,8 @@ import Data.HashMap.Strict ((!))
import Data.Universe import Data.Universe
import Control.Monad.Fail
instance (Eq a, Hashable a, Finite a, ToJSON b, ToJSONKey a) => ToJSON (a -> b) where instance (Eq a, Hashable a, Finite a, ToJSON b, ToJSONKey a) => ToJSON (a -> b) where
toJSON f = toJSON $ HashMap.fromList [(k, f k) | k <- universeF] toJSON f = toJSON $ HashMap.fromList [(k, f k) | k <- universeF]

View File

@ -17,12 +17,21 @@ import Control.Monad (unless)
import Data.List (elemIndex) import Data.List (elemIndex)
-- | Get type var bind name
--
-- Stolen from https://hackage.haskell.org/package/template-haskell-util-0.1.1.0
getTVBName :: TyVarBndr -> Name
getTVBName (PlainTV name ) = name
getTVBName (KindedTV name _) = name
finiteEnum :: Name -> DecsQ finiteEnum :: Name -> DecsQ
-- ^ Declare generic `Enum`- and `Bounded`-Instances given `Finite`- and `Eq`-Instances -- ^ Declare generic `Enum`- and `Bounded`-Instances given `Finite`- and `Eq`-Instances
finiteEnum tName = do finiteEnum tName = do
DatatypeInfo{..} <- reifyDatatype tName DatatypeInfo{..} <- reifyDatatype tName
let datatype = foldl appT (conT datatypeName) $ map pure datatypeVars let datatype = foldl appT (conT datatypeName) $ map (varT . getTVBName) datatypeVars
tUniverse = [e|universeF :: [$(datatype)]|] tUniverse = [e|universeF :: [$(datatype)]|]
[d| [d|
@ -48,14 +57,14 @@ deriveFinite tName = fmap concat . sequence $
[ deriveUniverse' [e|concat|] [e|universeF|] tName [ deriveUniverse' [e|concat|] [e|universeF|] tName
, do , do
DatatypeInfo{..} <- reifyDatatype tName DatatypeInfo{..} <- reifyDatatype tName
[d|instance Finite $(foldl appT (conT datatypeName) $ map pure datatypeVars)|] [d|instance Finite $(foldl appT (conT datatypeName) $ map (varT . getTVBName) datatypeVars)|]
] ]
deriveUniverse' :: ExpQ -> ExpQ -> Name -> DecsQ deriveUniverse' :: ExpQ -> ExpQ -> Name -> DecsQ
deriveUniverse' interleaveExp universeExp tName = do deriveUniverse' interleaveExp universeExp tName = do
DatatypeInfo{..} <- reifyDatatype tName DatatypeInfo{..} <- reifyDatatype tName
let datatype = foldl appT (conT datatypeName) $ map pure datatypeVars let datatype = foldl appT (conT datatypeName) $ map (varT . getTVBName) datatypeVars
consUniverse ConstructorInfo{..} = do consUniverse ConstructorInfo{..} = do
unless (null constructorVars) $ unless (null constructorVars) $
fail "Constructors with variables no supported" fail "Constructors with variables no supported"

View File

@ -6,7 +6,6 @@ module Data.Vector.Instances
import ClassyPrelude import ClassyPrelude
import Data.Vector (Vector)
import qualified Data.Vector as Vector import qualified Data.Vector as Vector
import Data.Binary (Binary) import Data.Binary (Binary)

View File

@ -8,7 +8,6 @@ module Database.Persist.Class.Instances
import ClassyPrelude import ClassyPrelude
import Database.Persist.Class import Database.Persist.Class
import Database.Persist.Types (HaskellName, DBName, PersistValue)
import Database.Persist.Types.Instances () import Database.Persist.Types.Instances ()
import Database.Persist.Sql import Database.Persist.Sql
@ -19,6 +18,8 @@ import qualified Data.Map as Map
import Data.Aeson (ToJSONKey, FromJSONKey) import Data.Aeson (ToJSONKey, FromJSONKey)
import Control.Monad.Fail
instance PersistEntity record => Hashable (Key record) where instance PersistEntity record => Hashable (Key record) where
hashWithSalt s = hashWithSalt s . toPersistValue hashWithSalt s = hashWithSalt s . toPersistValue

View File

@ -2,7 +2,7 @@
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedLabels #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} -- MonadCrypto {-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-uni-patterns #-} -- MonadCrypto
module Foundation module Foundation
( module Foundation ( module Foundation
@ -29,43 +29,36 @@ import qualified Yesod.Core.Unsafe as Unsafe
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.ByteArray (convert) import Data.ByteArray (convert)
import Crypto.Hash (Digest, SHAKE256, SHAKE128) import Crypto.Hash (SHAKE256, SHAKE128)
import Crypto.Hash.Conduit (sinkHash) import Crypto.Hash.Conduit (sinkHash)
import qualified Data.UUID as UUID import qualified Data.UUID as UUID
import qualified Data.Binary as Binary import qualified Data.Binary as Binary
import qualified Data.ByteString.Base64.URL as Base64 (encode) import qualified Data.ByteString.Base64.URL as Base64 (encode)
import Data.ByteString (ByteString)
import qualified Data.ByteString.Lazy as Lazy.ByteString import qualified Data.ByteString.Lazy as Lazy.ByteString
import qualified Data.ByteString as ByteString import qualified Data.ByteString as ByteString
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map (Map, (!?)) import Data.Map ((!?))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.HashSet as HashSet import qualified Data.HashSet as HashSet
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import Data.List (nubBy, (!!), findIndex, inits) import Data.List ((!!), findIndex, inits)
import qualified Data.List as List import qualified Data.List as List
import Web.Cookie import Web.Cookie
import Data.Monoid (Any(..))
import Data.Conduit.List (sourceList) import Data.Conduit.List (sourceList)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import Control.Monad.Except (MonadError(..), ExceptT) import Control.Monad.Except (MonadError(..), ExceptT)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Trans.Reader (runReader, mapReaderT)
import Control.Monad.Trans.Writer (WriterT(..), runWriterT)
import Control.Monad.Trans.State (execStateT) import Control.Monad.Trans.State (execStateT)
import Control.Monad.Writer.Class (MonadWriter(..)) import Control.Monad.Writer.Class (MonadWriter(..))
import Control.Monad.Memo.Class (MonadMemo(..), for4) import Control.Monad.Memo.Class (MonadMemo(..), for4)
@ -82,7 +75,6 @@ import Utils.Form
import Utils.Sheet import Utils.Sheet
import Utils.SystemMessage import Utils.SystemMessage
import Text.Shakespeare.Text (st)
import Text.Cassius (cassiusFile) import Text.Cassius (cassiusFile)
import Yesod.Form.I18n.German import Yesod.Form.I18n.German
@ -1121,12 +1113,12 @@ tagAccessPredicate AuthCapacity = APDB $ \_ route _ -> case route of
CTutorialR tid ssh csh tutn _ -> maybeT (unauthorizedI MsgTutorialNoCapacity) $ do CTutorialR tid ssh csh tutn _ -> maybeT (unauthorizedI MsgTutorialNoCapacity) $ do
cid <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh cid <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh
Entity tutId Tutorial{..} <- $cachedHereBinary (cid, tutn) . MaybeT . getBy $ UniqueTutorial cid tutn Entity tutId Tutorial{..} <- $cachedHereBinary (cid, tutn) . MaybeT . getBy $ UniqueTutorial cid tutn
registered <- $cachedHereBinary tutId . lift $ fromIntegral <$> count [ TutorialParticipantTutorial ==. tutId ] registered <- $cachedHereBinary tutId . lift $ count [ TutorialParticipantTutorial ==. tutId ]
guard $ NTop tutorialCapacity > NTop (Just registered) guard $ NTop tutorialCapacity > NTop (Just registered)
return Authorized return Authorized
CourseR tid ssh csh _ -> maybeT (unauthorizedI MsgCourseNoCapacity) $ do CourseR tid ssh csh _ -> maybeT (unauthorizedI MsgCourseNoCapacity) $ do
Entity cid Course{..} <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getBy $ TermSchoolCourseShort tid ssh csh Entity cid Course{..} <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getBy $ TermSchoolCourseShort tid ssh csh
registered <- $cachedHereBinary cid . lift $ fromIntegral <$> count [ CourseParticipantCourse ==. cid ] registered <- $cachedHereBinary cid . lift $ count [ CourseParticipantCourse ==. cid ]
guard $ NTop courseCapacity > NTop (Just registered) guard $ NTop courseCapacity > NTop (Just registered)
return Authorized return Authorized
r -> $unsupportedAuthPredicate AuthCapacity r r -> $unsupportedAuthPredicate AuthCapacity r
@ -1298,7 +1290,7 @@ routeAuthTags = fmap (PredDNF . Set.mapMonotonic impureNonNull) . ofoldM partiti
| otherwise | otherwise
= Left $ InvalidAuthTag t = Left $ InvalidAuthTag t
evalAuthTags :: forall m. (MonadAP m, MonadLogger m) => AuthTagActive -> AuthDNF -> Maybe (AuthId UniWorX) -> Route UniWorX -> Bool -> WriterT (Set AuthTag) m AuthResult evalAuthTags :: forall m. MonadAP m => AuthTagActive -> AuthDNF -> Maybe (AuthId UniWorX) -> Route UniWorX -> Bool -> WriterT (Set AuthTag) m AuthResult
-- ^ `tell`s disabled predicates, identified as pivots -- ^ `tell`s disabled predicates, identified as pivots
evalAuthTags AuthTagActive{..} (map (Set.toList . toNullable) . Set.toList . dnfTerms -> authDNF') mAuthId route isWrite evalAuthTags AuthTagActive{..} (map (Set.toList . toNullable) . Set.toList . dnfTerms -> authDNF') mAuthId route isWrite
= do = do

View File

@ -32,8 +32,6 @@ import qualified Data.Text as Text
import Utils.Form import Utils.Form
import Text.Shakespeare.Text (st)
import GHC.Exts (IsList(..)) import GHC.Exts (IsList(..))

View File

@ -13,8 +13,6 @@ import Jobs.Types
import Yesod.Core.Types (Logger) import Yesod.Core.Types (Logger)
import Data.Set (Set)
import qualified Crypto.Saltine.Core.SecretBox as SecretBox import qualified Crypto.Saltine.Core.SecretBox as SecretBox
import qualified Jose.Jwk as Jose import qualified Jose.Jwk as Jose

View File

@ -250,7 +250,7 @@ postAdminFeaturesR = do
-> DBRow r -> DBRow r
-> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r)))
textInputCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) textInputCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex)
(\row _mkUnique -> (\(res,fieldView) -> (set lensRes . assertM (not . Text.null) <$> res, fvInput fieldView)) (\row _mkUnique -> bimap (fmap $ set lensRes . assertM (not . Text.null)) fvInput
<$> mopt (textField & cfStrip) "" (Just $ row ^. lensDefault) <$> mopt (textField & cfStrip) "" (Just $ row ^. lensDefault)
) )
@ -261,7 +261,7 @@ postAdminFeaturesR = do
-> DBRow r -> DBRow r
-> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r)))
checkboxCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) checkboxCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex)
( \row _mkUnique -> (\(res, fieldView) -> (set lensRes <$> res, fvInput fieldView)) ( \row _mkUnique -> bimap (fmap $ set lensRes) fvInput
<$> mpopt checkBoxField "" (Just $ row ^. lensDefault) <$> mpopt checkBoxField "" (Just $ row ^. lensDefault)
) )
@ -283,7 +283,7 @@ postAdminFeaturesR = do
-> DBRow r -> DBRow r
-> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r)))
parentsCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) parentsCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex)
( \row mkUnique -> (\(res, fieldView) -> (set lensRes . Set.fromList <$> res, fvInput fieldView)) ( \row mkUnique -> bimap (fmap $ set lensRes . Set.fromList) fvInput
<$> massInputList <$> massInputList
(intField & isoField (from _StudyTermsId)) (intField & isoField (from _StudyTermsId))
(const "") (const "")
@ -302,7 +302,7 @@ postAdminFeaturesR = do
-> DBRow r -> DBRow r
-> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r)))
degreeCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) degreeCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex)
( \row _mkUnique -> (\(res, fieldView) -> (set lensRes <$> res, fvInput fieldView)) ( \row _mkUnique -> bimap (fmap $ set lensRes) fvInput
<$> mopt degreeField "" (Just $ row ^. lensDefault) <$> mopt degreeField "" (Just $ row ^. lensDefault)
) )
@ -313,7 +313,7 @@ postAdminFeaturesR = do
-> DBRow r -> DBRow r
-> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r)))
fieldTypeCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex) fieldTypeCell lensRes lensDefault lensIndex = formCell id (return . view lensIndex)
( \row _mkUnique -> (\(res, fieldView) -> (set lensRes <$> res, fvInput fieldView)) ( \row _mkUnique -> bimap (fmap $ set lensRes) fvInput
<$> mopt (selectField optionsFinite) "" (Just $ row ^. lensDefault) <$> mopt (selectField optionsFinite) "" (Just $ row ^. lensDefault)
) )

View File

@ -7,16 +7,12 @@ import Import
import Handler.Utils import Handler.Utils
import Jobs import Jobs
import Control.Monad.Trans.Writer (mapWriterT)
import Data.Char (isDigit) import Data.Char (isDigit)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
import Database.Persist.Sql (fromSqlKey)
-- BEGIN - Buttons needed only here -- BEGIN - Buttons needed only here
data ButtonCreate = CreateMath | CreateInf -- Dummy for Example data ButtonCreate = CreateMath | CreateInf -- Dummy for Example
@ -158,7 +154,7 @@ postAdminTestR = do
mkAddForm 0 0 nudge submitBtn = Just $ \csrf -> do mkAddForm 0 0 nudge submitBtn = Just $ \csrf -> do
(addRes, addView) <- mpreq textField ("" & addName (nudge "text")) Nothing -- Any old field; for demonstration (addRes, addView) <- mpreq textField ("" & addName (nudge "text")) Nothing -- Any old field; for demonstration
let addRes' = fromMaybe 0 . readMay . Text.filter isDigit <$> addRes -- Do something semi-interesting on the result of the @textField@ to demonstrate that further processing can be done let addRes' = fromMaybe 0 . readMay . Text.filter isDigit <$> addRes -- Do something semi-interesting on the result of the @textField@ to demonstrate that further processing can be done
addRes'' = addRes' <&> \dat prev -> FormSuccess (Map.singleton (maybe 0 succ . fmap fst $ Map.lookupMax prev) dat) -- Construct the callback to determine new cell positions and data within @FormResult@ as required, nested @FormResult@ allows aborting the add depending on previous data addRes'' = addRes' <&> \dat prev -> FormSuccess (Map.singleton (maybe 0 (succ . fst) $ Map.lookupMax prev) dat) -- Construct the callback to determine new cell positions and data within @FormResult@ as required, nested @FormResult@ allows aborting the add depending on previous data
return (addRes'', toWidget csrf >> fvInput addView >> fvInput submitBtn) return (addRes'', toWidget csrf >> fvInput addView >> fvInput submitBtn)
mkAddForm _pos _dim _ _ = error "Dimension and Position is always 0 for our 1-dimensional form" mkAddForm _pos _dim _ _ = error "Dimension and Position is always 0 for our 1-dimensional form"

View File

@ -11,18 +11,13 @@ import Handler.Utils.SheetType
import Handler.Utils.Delete import Handler.Utils.Delete
-- import Handler.Utils.Zip -- import Handler.Utils.Zip
import Data.List as List (nub, foldl, foldr) import Data.List as List (foldl, foldr)
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map.Strict (Map, (!)) import Data.Map.Strict ((!))
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.CaseInsensitive (CI)
import Data.Semigroup (Sum(..))
import Data.Monoid (All(..))
-- import Data.Time -- import Data.Time
-- import Data.Function ((&)) -- import Data.Function ((&))
@ -49,14 +44,8 @@ import Database.Persist.Sql (updateWhereCount)
import Data.List (genericLength) import Data.List (genericLength)
import Control.Monad.Trans.Writer (WriterT(..), runWriter, execWriterT)
import Control.Monad.Trans.Reader (mapReaderT)
import Control.Monad.Trans.State (State, runState)
import qualified Control.Monad.State.Class as State import qualified Control.Monad.State.Class as State
import Data.Foldable (foldrM)
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C

View File

@ -8,8 +8,6 @@ module Handler.Course.Application.Files
import Import import Import
import Handler.Utils import Handler.Utils
import System.FilePath (addExtension, (</>))
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E

View File

@ -18,7 +18,6 @@ import qualified Data.Csv as Csv
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.Lens as Text import qualified Data.Text.Lens as Text
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import qualified Data.Map as Map import qualified Data.Map as Map

View File

@ -10,14 +10,12 @@ import Handler.Utils
import Handler.Utils.Invitations import Handler.Utils.Invitations
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.Function ((&))
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map ((!)) import Data.Map ((!))
import qualified Data.Map as Map import qualified Data.Map as Map
import Control.Monad.Trans.Writer (execWriterT)
import qualified Control.Monad.State.Class as State import qualified Control.Monad.State.Class as State
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E

View File

@ -12,7 +12,6 @@ import Utils.Form
import Handler.Utils.Invitations import Handler.Utils.Invitations
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.Function ((&))
import Data.Aeson hiding (Result(..)) import Data.Aeson hiding (Result(..))
@ -74,6 +73,7 @@ lecturerInvitationConfig = InvitationConfig{..}
Just lType -> aforced (selectField optionsFinite) lFs lType Just lType -> aforced (selectField optionsFinite) lFs lType
where where
toJunction jLecturerType = (JunctionLecturer{..}, ()) toJunction jLecturerType = (JunctionLecturer{..}, ())
lFs :: FieldSettings UniWorX
lFs = fslI MsgLecturerType & setTooltip MsgCourseLecturerRightsIdentical lFs = fslI MsgLecturerType & setTooltip MsgCourseLecturerRightsIdentical
invitationInsertHook _ _ _ _ _ = id invitationInsertHook _ _ _ _ _ = id
invitationSuccessMsg (Entity _ Course{..}) (Entity _ Lecturer{..}) = do invitationSuccessMsg (Entity _ Course{..}) (Entity _ Lecturer{..}) = do

View File

@ -14,8 +14,6 @@ import Utils.Form
-- import Utils.DB -- import Utils.DB
import Handler.Utils hiding (colSchoolShort) import Handler.Utils hiding (colSchoolShort)
import Data.Function ((&))
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map

View File

@ -5,6 +5,8 @@ module Handler.Course.News.Show
import Import import Import
import Handler.Utils import Handler.Utils
{-# ANN module ("HLint: ignore Too strict maybe"::String) #-}
getCNShowR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> Handler Html getCNShowR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> Handler Html
getCNShowR tid ssh csh cID = do getCNShowR tid ssh csh cID = do

View File

@ -16,7 +16,6 @@ import Handler.Utils
import Handler.Utils.Invitations import Handler.Utils.Invitations
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.Function ((&))
import qualified Data.Set as Set import qualified Data.Set as Set
@ -26,7 +25,6 @@ import Data.Aeson hiding (Result(..))
import Text.Hamlet (ihamlet) import Text.Hamlet (ihamlet)
import Control.Monad.Trans.Writer (WriterT, execWriterT)
import Control.Monad.Except (MonadError(..)) import Control.Monad.Except (MonadError(..))
import Generics.Deriving.Monoid (memptydefault, mappenddefault) import Generics.Deriving.Monoid (memptydefault, mappenddefault)

View File

@ -10,8 +10,6 @@ import Import
import Handler.Utils import Handler.Utils
import Data.Function ((&))
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C

View File

@ -18,8 +18,6 @@ import qualified Database.Esqueleto as E
import Handler.Course.Register import Handler.Course.Register
import System.FilePath (addExtension, pathSeparator)
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C

View File

@ -8,8 +8,6 @@ import Utils.Form
import Handler.Utils import Handler.Utils
import Database.Esqueleto.Utils.TH import Database.Esqueleto.Utils.TH
import Data.Function ((&))
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import Text.Blaze.Html.Renderer.Text (renderHtml) import Text.Blaze.Html.Renderer.Text (renderHtml)

View File

@ -16,8 +16,6 @@ import Database.Esqueleto.Utils.TH
import Handler.Course.Register (deregisterParticipant) import Handler.Course.Register (deregisterParticipant)
import Data.Function ((&))
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Text as Text import qualified Data.Text as Text

View File

@ -7,11 +7,10 @@ import Import
import qualified Data.Text as Text import qualified Data.Text as Text
import Yesod.Core.Types (HandlerContents(..), ErrorResponse(..)) import Yesod.Core.Types (HandlerContents(..))
import qualified Control.Monad.Catch as E (Handler(..)) import qualified Control.Monad.Catch as E (Handler(..))
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI

View File

@ -13,7 +13,6 @@ import qualified Data.Set as Set
import Data.Semigroup (Option(..)) import Data.Semigroup (Option(..))
import Control.Monad.Trans.Writer (WriterT, execWriterT)
import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Error.Class (MonadError(..))
import Jobs.Queue import Jobs.Queue

View File

@ -71,8 +71,8 @@ postCExamNewR tid ssh csh = do
let (invites, adds) = partitionEithers $ Set.toList efCorrectors let (invites, adds) = partitionEithers $ Set.toList efCorrectors
insertMany_ [ ExamCorrector{..} insertMany_ [ ExamCorrector{..}
| examCorrectorUser <- adds | let examCorrectorExam = examid
, let examCorrectorExam = examid , examCorrectorUser <- adds
] ]
sinkInvitationsF examCorrectorInvitationConfig $ map (, examid, (InvDBDataExamCorrector, InvTokenDataExamCorrector)) invites sinkInvitationsF examCorrectorInvitationConfig $ map (, examid, (InvDBDataExamCorrector, InvTokenDataExamCorrector)) invites
return insertRes return insertRes

View File

@ -7,8 +7,6 @@ import qualified Data.Text.Lazy.Builder as Builder
import qualified Data.UUID as UUID import qualified Data.UUID as UUID
import Data.Semigroup (Min(..), Max(..))
import qualified Data.Set as Set import qualified Data.Set as Set
import Control.Concurrent.STM.Delay import Control.Concurrent.STM.Delay

View File

@ -2,8 +2,6 @@ module Handler.Material where
import Import import Import
import Data.Monoid (Any(..))
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
-- import Data.Map (Map) -- import Data.Map (Map)
import qualified Data.Map as Map import qualified Data.Map as Map
@ -18,10 +16,6 @@ import Utils.Form
import Handler.Utils import Handler.Utils
import Handler.Utils.Delete import Handler.Utils.Delete
import Control.Monad.Writer (MonadWriter(..), execWriterT)
import System.FilePath (addExtension)
data MaterialForm = MaterialForm data MaterialForm = MaterialForm
{ mfName :: MaterialName { mfName :: MaterialName

View File

@ -1,4 +1,4 @@
{-# OPTIONS_GHC -fno-warn-redundant-constraints #-} {-# OPTIONS_GHC -fno-warn-redundant-constraints -fno-warn-incomplete-uni-patterns #-}
module Handler.Participants module Handler.Participants
( getParticipantsListR ( getParticipantsListR
, getParticipantsR , getParticipantsR

View File

@ -16,7 +16,6 @@ import Handler.Utils.Tokens
-- import Colonnade hiding (fromMaybe, singleton) -- import Colonnade hiding (fromMaybe, singleton)
-- import Yesod.Colonnade -- import Yesod.Colonnade
import Data.Monoid (Any(..))
import Data.Map ((!)) import Data.Map ((!))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -30,31 +30,18 @@ import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
-- import qualified Database.Esqueleto.Internal.Sql as E -- import qualified Database.Esqueleto.Internal.Sql as E
import Control.Monad.Writer (MonadWriter(..), execWriterT)
-- import Control.Monad.Trans.RWS.Lazy (RWST, local)
-- import qualified Text.Email.Validate as Email
-- import qualified Data.List as List
import Control.Monad.Trans.Except (runExceptT, mapExceptT, throwE) import Control.Monad.Trans.Except (runExceptT, mapExceptT, throwE)
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Map (Map, (!)) import Data.Map ((!))
import Data.Monoid (Any(..))
import Control.Monad.Random.Class (MonadRandom(..))
import Utils.Sql import Utils.Sql
import Data.Aeson hiding (Result(..)) import Data.Aeson hiding (Result(..))
import Text.Hamlet (ihamlet) import Text.Hamlet (ihamlet)
import System.FilePath (addExtension)
import Data.Time.Clock.System (systemEpochDay) import Data.Time.Clock.System (systemEpochDay)

View File

@ -1,4 +1,4 @@
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-uni-patterns #-}
module Handler.Submission where module Handler.Submission where
@ -17,7 +17,6 @@ import Handler.Utils.Invitations
-- import Control.Monad.State.Class -- import Control.Monad.State.Class
-- import Control.Monad.Trans.State.Strict (StateT) -- import Control.Monad.Trans.State.Strict (StateT)
import Data.Monoid (Any(..))
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
-- import qualified Data.Maybe -- import qualified Data.Maybe
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text
@ -30,7 +29,7 @@ import qualified Data.Conduit.List as Conduit
-- import Data.Set (Set) -- import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map (Map, (!), (!?)) import Data.Map ((!), (!?))
import qualified Data.Map as Map import qualified Data.Map as Map
-- import Data.Bifunctor -- import Data.Bifunctor
@ -42,8 +41,6 @@ import Text.Hamlet (ihamlet)
-- import qualified Yesod.Colonnade as Yesod -- import qualified Yesod.Colonnade as Yesod
-- import qualified Text.Blaze.Html5.Attributes as HA -- import qualified Text.Blaze.Html5.Attributes as HA
import System.FilePath (addExtension)
-- DEPRECATED: We always show all edits! -- DEPRECATED: We always show all edits!
-- numberOfSubmissionEditDates :: Int64 -- numberOfSubmissionEditDates :: Int64
-- numberOfSubmissionEditDates = 3 -- for debugging only, should be 1 in production. -- numberOfSubmissionEditDates = 3 -- for debugging only, should be 1 in production.

View File

@ -11,7 +11,6 @@ import Handler.Utils.Tutorial
import Database.Persist.Sql (deleteWhereCount) import Database.Persist.Sql (deleteWhereCount)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import Data.Function ((&))
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map

View File

@ -25,8 +25,6 @@ import Handler.Utils.Widgets as Handler.Utils
import Handler.Utils.Database as Handler.Utils import Handler.Utils.Database as Handler.Utils
import Handler.Utils.Occurrences as Handler.Utils import Handler.Utils.Occurrences as Handler.Utils
import System.FilePath.Posix (takeFileName)
import Control.Monad.Logger import Control.Monad.Logger

View File

@ -27,7 +27,6 @@ import System.Random (mkStdGen)
import Utils.Allocation import Utils.Allocation
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C
import Data.Conduit.Lift (evalStateC)
import Data.Generics.Product.Param import Data.Generics.Product.Param
@ -176,12 +175,14 @@ doAllocation allocId regs = 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 . insertUnique $ CourseParticipant cid uid now mField (Just allocId) void . insertUnique $ CourseParticipant cid uid now mField (Just allocId)
ppMatchingLog :: ( MonoFoldable mono ppMatchingLog :: forall mono.
( MonoFoldable mono
, Element mono ~ MatchingLog UserId CourseId Natural , Element mono ~ MatchingLog UserId CourseId Natural
) )
=> mono -> Text => mono -> Text
ppMatchingLog = unlines . map (tshow . pretty) . otoList ppMatchingLog = unlines . map (tshow . pretty) . otoList
where where
pretty :: MatchingLog UserId CourseId Natural -> MatchingLog Int64 Int64 Natural
pretty = over (param @1) fromSqlKey pretty = over (param @1) fromSqlKey
. over (param @2) fromSqlKey . over (param @2) fromSqlKey

View File

@ -11,7 +11,6 @@ import Import
import Handler.Utils import Handler.Utils
import Jobs.Queue import Jobs.Queue
import Control.Monad.Trans.Reader (mapReaderT)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI

View File

@ -20,7 +20,6 @@ import Import hiding (Header, mapM_)
import Data.Csv import Data.Csv
import Data.Csv.Conduit import Data.Csv.Conduit
import Data.Function ((&))
import Control.Monad (mapM_) import Control.Monad (mapM_)
-- import qualified Data.Csv.Util as Csv -- import qualified Data.Csv.Util as Csv
@ -75,6 +74,7 @@ decodeCsv' fromCsv' = do
$logInfoS "decodeCsv" [st|Guessed Csv.DecodeOptions from buffer of size #{tshow (LBS.length testBuffer)}/#{tshow testBufferSize}: #{tshow decodeOptions}|] $logInfoS "decodeCsv" [st|Guessed Csv.DecodeOptions from buffer of size #{tshow (LBS.length testBuffer)}/#{tshow testBufferSize}: #{tshow decodeOptions}|]
fromCsv' decodeOptions fromCsv' decodeOptions
testBufferSize :: Num a => a
testBufferSize = 4096 testBufferSize = 4096
accumTestBuffer acc accumTestBuffer acc
| LBS.length acc >= testBufferSize = return acc | LBS.length acc >= testBufferSize = return acc

View File

@ -24,7 +24,6 @@ import Data.Time hiding (formatTime, localTimeToUTC, utcToLocalTime, utcToZonedT
-- import Data.Time.Clock (addUTCTime,nominalDay) -- import Data.Time.Clock (addUTCTime,nominalDay)
import qualified Data.Time.Format as Time import qualified Data.Time.Format as Time
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Time.Clock.System (systemEpochDay) import Data.Time.Clock.System (systemEpochDay)

View File

@ -27,10 +27,11 @@ import Data.Char (isAlphaNum)
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect) import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect)
import qualified Database.Esqueleto.Internal.Language as E (From)
import Jobs.Queue import Jobs.Queue
{-# ANN deleteR ("HLint: ignore Use const" :: String) #-}
data DeleteRoute record = forall tables infoExpr info. (E.SqlSelect infoExpr info, E.From tables) => DeleteRoute data DeleteRoute record = forall tables infoExpr info. (E.SqlSelect infoExpr info, E.From tables) => DeleteRoute
{ drRecords :: Set (Key record) -- ^ Records to be deleted { drRecords :: Set (Key record) -- ^ Records to be deleted

View File

@ -1,4 +1,4 @@
{-# OPTIONS_GHC -fno-warn-deprecations #-} {-# OPTIONS_GHC -fno-warn-deprecations -fno-warn-incomplete-uni-patterns #-}
module Handler.Utils.Exam module Handler.Utils.Exam
( fetchExamAux ( fetchExamAux
@ -24,7 +24,6 @@ import qualified Data.Conduit.List as C
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Fixed (Fixed(..))
import qualified Data.Foldable as F import qualified Data.Foldable as F
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI

View File

@ -14,6 +14,8 @@ import Handler.Utils.Pandoc
import Handler.Utils.DateTime import Handler.Utils.DateTime
import Handler.Utils.Widgets
import Import import Import
import Data.Char (chr, ord) import Data.Char (chr, ord)
import qualified Data.Char as Char import qualified Data.Char as Char
@ -31,19 +33,15 @@ import qualified Data.Conduit.List as C
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map (Map, (!)) import Data.Map ((!))
import qualified Data.Map as Map import qualified Data.Map as Map
import Control.Monad.Trans.Writer (execWriterT, WriterT)
import Control.Monad.Trans.Except (throwE, runExceptT) import Control.Monad.Trans.Except (throwE, runExceptT)
import Control.Monad.Writer.Class import Control.Monad.Writer.Class
import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Error.Class (MonadError(..))
import Data.Either (partitionEithers)
import Data.Aeson (eitherDecodeStrict') import Data.Aeson (eitherDecodeStrict')
import Data.Aeson.Text (encodeToLazyText) import Data.Aeson.Text (encodeToLazyText)
@ -51,7 +49,6 @@ import qualified Text.Email.Validate as Email
import Yesod.Core.Types (FileInfo(..)) import Yesod.Core.Types (FileInfo(..))
import System.FilePath (isExtensionOf)
import Data.Text.Lens (unpacked) import Data.Text.Lens (unpacked)
import Data.Char (isDigit) import Data.Char (isDigit)
@ -548,6 +545,7 @@ uploadModeForm prev = multiActionA actions (fslI MsgSheetUploadMode) (classifyUp
return (addRes', formWidget') return (addRes', formWidget')
miCell _ initFile _ nudge csrf = miCell _ initFile _ nudge csrf =
sFileForm nudge (Just initFile) csrf sFileForm nudge (Just initFile) csrf
miDelete :: MassInputDelete ListLength
miDelete = miDeleteList miDelete = miDeleteList
miAllowAdd _ _ _ = True miAllowAdd _ _ _ = True
miAddEmpty _ _ _ = Set.empty miAddEmpty _ _ _ = Set.empty
@ -815,7 +813,8 @@ multiFileField permittedFiles' = Field{..}
| Right sentVals' <- sentVals = fuiId' `elem` sentVals' | Right sentVals' <- sentVals = fuiId' `elem` sentVals'
| otherwise = True | otherwise = True
return FileUploadInfo{..} return FileUploadInfo{..}
autoUnzipInfo = [whamlet| _{MsgAutoUnzipInfo} |] autoUnzipInfo :: Widget
autoUnzipInfo = i18n MsgAutoUnzipInfo
fileInfos' <- mapM toFUI <=< handlerToWidget . runDB . E.select . E.from $ \file -> do fileInfos' <- mapM toFUI <=< handlerToWidget . runDB . E.select . E.from $ \file -> do
E.where_ $ file E.^. FileId `E.in_` E.valList (setToList pVals) E.where_ $ file E.^. FileId `E.in_` E.valList (setToList pVals)
E.orderBy [E.asc $ file E.^. FileTitle] E.orderBy [E.asc $ file E.^. FileTitle]

View File

@ -1,8 +1,8 @@
{-# OPTIONS_GHC -fno-warn-orphans #-} -- tupleBoxCoord {-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-record-updates #-} -- tupleBoxCoord
{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-}
module Handler.Utils.Form.MassInput module Handler.Utils.Form.MassInput
( MassInput(..), MassInputLayout ( MassInput(..), MassInputLayout, MassInputDelete
, defaultMiLayout, listMiLayout , defaultMiLayout, listMiLayout
, massInput , massInput
, module Handler.Utils.Form.MassInput.Liveliness , module Handler.Utils.Form.MassInput.Liveliness
@ -34,6 +34,8 @@ import Control.Monad.Reader.Class (MonadReader(local))
import Text.Hamlet (hamletFile) import Text.Hamlet (hamletFile)
import Algebra.Lattice.Ordered (Ordered(..))
$(mapM tupleBoxCoord [2..4]) $(mapM tupleBoxCoord [2..4])
@ -44,11 +46,8 @@ newtype ListLength = ListLength { unListLength :: Natural }
makeWrapped ''ListLength makeWrapped ''ListLength
instance JoinSemiLattice ListLength where deriving via Ordered ListLength instance Lattice ListLength
(\/) = max
instance MeetSemiLattice ListLength where
(/\) = min
instance Lattice ListLength
instance BoundedJoinSemiLattice ListLength where instance BoundedJoinSemiLattice ListLength where
bottom = 0 bottom = 0
@ -85,16 +84,13 @@ newtype EnumLiveliness enum = EnumLiveliness { unEnumLiveliness :: IntSet }
makeWrapped ''EnumLiveliness makeWrapped ''EnumLiveliness
instance JoinSemiLattice (EnumLiveliness enum) where instance Lattice (EnumLiveliness enum) where
(EnumLiveliness a) \/ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.union` b (EnumLiveliness a) \/ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.union` b
instance MeetSemiLattice (EnumLiveliness enum) where
(EnumLiveliness a) /\ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.intersection` b (EnumLiveliness a) /\ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.intersection` b
instance Lattice (EnumLiveliness enum)
instance BoundedJoinSemiLattice (EnumLiveliness enum) where instance BoundedJoinSemiLattice (EnumLiveliness enum) where
bottom = EnumLiveliness IntSet.empty bottom = EnumLiveliness IntSet.empty
instance (Enum enum, Bounded enum) => BoundedMeetSemiLattice (EnumLiveliness enum) where instance (Enum enum, Bounded enum) => BoundedMeetSemiLattice (EnumLiveliness enum) where
top = EnumLiveliness . IntSet.fromList $ map (fromEnum :: enum -> Int) [minBound..maxBound] top = EnumLiveliness . IntSet.fromList $ map (fromEnum :: enum -> Int) [minBound..maxBound]
instance (Enum enum, Bounded enum) => BoundedLattice (EnumLiveliness enum)
newtype EnumPosition enum = EnumPosition { unEnumPosition :: enum } newtype EnumPosition enum = EnumPosition { unEnumPosition :: enum }
@ -111,7 +107,9 @@ instance (Enum enum, Bounded enum, PathPiece enum, ToJSON enum, FromJSON enum, T
type BoxCoord (EnumLiveliness enum) = EnumPosition enum type BoxCoord (EnumLiveliness enum) = EnumPosition enum
liveCoords = iso fromSet toSet liveCoords = iso fromSet toSet
where where
toSet :: EnumLiveliness enum -> Set (EnumPosition enum)
toSet = Set.fromList . map toEnum . IntSet.toList . unEnumLiveliness toSet = Set.fromList . map toEnum . IntSet.toList . unEnumLiveliness
fromSet :: Set (EnumPosition enum) -> EnumLiveliness enum
fromSet = EnumLiveliness . IntSet.fromList . map fromEnum . Set.toList fromSet = EnumLiveliness . IntSet.fromList . map fromEnum . Set.toList
@ -120,12 +118,9 @@ newtype MapLiveliness l1 l2 = MapLiveliness { unMapLiveliness :: Map (BoxCoord l
makeWrapped ''MapLiveliness makeWrapped ''MapLiveliness
deriving instance (Ord (BoxCoord l1), JoinSemiLattice l2) => JoinSemiLattice (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), MeetSemiLattice l2) => MeetSemiLattice (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), Lattice l2) => Lattice (MapLiveliness l1 l2) deriving instance (Ord (BoxCoord l1), Lattice l2) => Lattice (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), BoundedJoinSemiLattice l2) => BoundedJoinSemiLattice (MapLiveliness l1 l2) deriving instance (Ord (BoxCoord l1), BoundedJoinSemiLattice l2) => BoundedJoinSemiLattice (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), Finite (BoxCoord l1), BoundedMeetSemiLattice l2) => BoundedMeetSemiLattice (MapLiveliness l1 l2) deriving instance (Ord (BoxCoord l1), Finite (BoxCoord l1), BoundedMeetSemiLattice l2) => BoundedMeetSemiLattice (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), Finite (BoxCoord l1), BoundedLattice l2) => BoundedLattice (MapLiveliness l1 l2)
deriving instance (Eq (BoxCoord l1), Eq l2) => Eq (MapLiveliness l1 l2) deriving instance (Eq (BoxCoord l1), Eq l2) => Eq (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), Ord l2) => Ord (MapLiveliness l1 l2) deriving instance (Ord (BoxCoord l1), Ord l2) => Ord (MapLiveliness l1 l2)
deriving instance (Ord (BoxCoord l1), Read (BoxCoord l1), Read l2) => Read (MapLiveliness l1 l2) deriving instance (Ord (BoxCoord l1), Read (BoxCoord l1), Read l2) => Read (MapLiveliness l1 l2)
@ -138,8 +133,10 @@ 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) (\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))
miDeleteList :: Applicative m => Map ListPosition a -> ListPosition -> m (Map ListPosition ListPosition)
miDeleteList :: MassInputDelete ListLength
miDeleteList dat pos miDeleteList dat pos
-- Close gap left by deleted position with values from further down the list; try prohibiting certain deletions by utilising `guard` -- Close gap left by deleted position with values from further down the list; try prohibiting certain deletions by utilising `guard`
| Just l <- preview liveCoords $ Map.keysSet dat :: Maybe ListLength | Just l <- preview liveCoords $ Map.keysSet dat :: Maybe ListLength
@ -289,6 +286,7 @@ massInput MassInput{ miIdent = toPathPiece -> miIdent, ..} FieldSettings{..} fvR
let let
shapeName :: MassInputFieldName (BoxCoord liveliness) shapeName :: MassInputFieldName (BoxCoord liveliness)
shapeName = MassInputShape{..} shapeName = MassInputShape{..}
shapeField :: Field handler (Map (BoxCoord liveliness) cellData)
shapeField = secretJsonField shapeField = secretJsonField
sentShape <- runMaybeT $ do sentShape <- runMaybeT $ do
ts <- fromMaybe [] . Map.lookup (toPathPiece shapeName) <$> MaybeT askParams ts <- fromMaybe [] . Map.lookup (toPathPiece shapeName) <$> MaybeT askParams
@ -536,6 +534,7 @@ massInputAccum miAdd' miCell' miButtonAction miLayout miIdent fSettings fRequire
-> (Markup -> MForm handler (FormResult (), Widget)) -> (Markup -> MForm handler (FormResult (), Widget))
miCell _pos dat _mPrev _nudge csrf' = return (FormSuccess (), toWidget csrf' <> miCell' dat) miCell _pos dat _mPrev _nudge csrf' = return (FormSuccess (), toWidget csrf' <> miCell' dat)
miDelete :: MassInputDelete ListLength
miDelete = miDeleteList miDelete = miDeleteList
miAllowAdd _ _ _ = True miAllowAdd _ _ _ = True
@ -613,6 +612,7 @@ massInputAccumEdit miAdd' miCell' miButtonAction miLayout miIdent fSettings fReq
-> (Markup -> MForm handler (FormResult cellData, Widget)) -> (Markup -> MForm handler (FormResult cellData, Widget))
miCell _pos dat _mPrev nudge = miCell' nudge dat miCell _pos dat _mPrev nudge = miCell' nudge dat
miDelete :: MassInputDelete ListLength
miDelete = miDeleteList miDelete = miDeleteList
miAllowAdd _ _ _ = True miAllowAdd _ _ _ = True

View File

@ -26,11 +26,12 @@ class (ToJSON x, FromJSON x, ToJSONKey x, FromJSONKey x, PathPiece x, Eq x, Ord
boxDimensions :: [BoxDimension x] boxDimensions :: [BoxDimension x]
boxOrigin :: x boxOrigin :: x
boxDimension :: IsBoxCoord x => Natural -> BoxDimension x boxDimension :: forall x. IsBoxCoord x => Natural -> BoxDimension x
boxDimension n boxDimension n
| n < genericLength dims = genericIndex dims n | n < genericLength dims = genericIndex dims n
| otherwise = error "boxDimension: insufficient dimensions" | otherwise = error "boxDimension: insufficient dimensions"
where where
dims :: [BoxDimension x]
dims = boxDimensions dims = boxDimensions
-- zeroDimension :: IsBoxCoord x => Natural -> x -> x -- zeroDimension :: IsBoxCoord x => Natural -> x -> x

View File

@ -11,8 +11,6 @@ import Language.Haskell.TH
import Control.Lens import Control.Lens
import Data.List ((!!))
import Control.Monad (replicateM) import Control.Monad (replicateM)

View File

@ -20,7 +20,6 @@ import qualified Data.Map as Map
import qualified Data.Text as Text import qualified Data.Text as Text
import System.Directory (listDirectory) import System.Directory (listDirectory)
import System.FilePath.Posix (takeBaseName)
-- | Add language dependent template files -- | Add language dependent template files

View File

@ -25,9 +25,6 @@ import Handler.Utils.Tokens
import Text.Hamlet import Text.Hamlet
import Control.Monad.Trans.Writer (WriterT)
import Control.Monad.Trans.Reader (mapReaderT, withReaderT)
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.HashSet as HashSet import qualified Data.HashSet as HashSet
@ -36,7 +33,6 @@ import qualified Data.Set as Set
import Data.Aeson (fromJSON) import Data.Aeson (fromJSON)
import qualified Data.Aeson as JSON import qualified Data.Aeson as JSON
import Data.Proxy (Proxy(..))
import Data.Typeable import Data.Typeable
import Database.Persist.Sql (SqlBackendCanWrite) import Database.Persist.Sql (SqlBackendCanWrite)

View File

@ -15,10 +15,6 @@ import qualified Data.ByteString.Lazy as LBS
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C
import System.FilePath (takeBaseName)
import Control.Monad.Trans.State (StateT)
import qualified Text.Pandoc as P import qualified Text.Pandoc as P
import qualified Text.Hamlet as Hamlet (Translate) import qualified Text.Hamlet as Hamlet (Translate)
@ -79,8 +75,8 @@ addFileDB fId = runMaybeT $ do
lift . addPart $ do lift . addPart $ do
_partType .= decodeUtf8 (mimeLookup fileName) _partType .= decodeUtf8 (mimeLookup fileName)
_partEncoding .= Base64 _partEncoding .= Base64
_partFilename .= Just fileName _partDisposition .= AttachmentDisposition fileName
_partContent .= LBS.fromStrict fileContent _partContent .= PartContent (LBS.fromStrict fileContent)
setMailObjectIdCrypto fId :: StateT Part (HandlerFor UniWorX) MailObjectId setMailObjectIdCrypto fId :: StateT Part (HandlerFor UniWorX) MailObjectId

View File

@ -20,11 +20,9 @@ import Text.PrettyPrint.Leijen.Text hiding ((<$>))
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text import qualified Data.Text.Encoding as Text
import Data.Text.Encoding.Error (UnicodeException(..))
import qualified Data.Text.Lazy.Encoding as Lazy.Text import qualified Data.Text.Lazy.Encoding as Lazy.Text
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import qualified Data.ByteString.Lazy as Lazy (ByteString) import qualified Data.ByteString.Lazy as Lazy (ByteString)
@ -138,8 +136,10 @@ parseRating File{ fileContent = Just input, .. } = do
(headerLines', commentLines) = break (commentSep `Text.isInfixOf`) $ Text.lines inputText (headerLines', commentLines) = break (commentSep `Text.isInfixOf`) $ Text.lines inputText
(reverse -> ratingLines, reverse -> _headerLines) = break (sep' `Text.isInfixOf`) $ reverse headerLines' (reverse -> ratingLines, reverse -> _headerLines) = break (sep' `Text.isInfixOf`) $ reverse headerLines'
ratingLines' = filter (rating `Text.isInfixOf`) ratingLines ratingLines' = filter (rating `Text.isInfixOf`) ratingLines
commentSep :: Text
commentSep = "Beginn der Kommentare" commentSep = "Beginn der Kommentare"
sep' = Text.pack $ replicate 40 '=' sep' = Text.pack $ replicate 40 '='
rating :: Text
rating = "Bewertung:" rating = "Bewertung:"
comment' <- case commentLines of comment' <- case commentLines of
(_:commentLines') -> return . Text.strip $ Text.unlines commentLines' (_:commentLines') -> return . Text.strip $ Text.unlines commentLines'

View File

@ -7,7 +7,6 @@ import Import.NoFoundation hiding (try, (<|>), choice)
import Text.Parsec import Text.Parsec
import Text.Parsec.Text import Text.Parsec.Text
import Data.CaseInsensitive (CI)
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -4,7 +4,6 @@ module Handler.Utils.SheetType
) where ) where
import Import import Import
import Data.Monoid (Sum(..))
addBonusToPoints :: SheetTypeSummary -> SheetTypeSummary addBonusToPoints :: SheetTypeSummary -> SheetTypeSummary
addBonusToPoints sts = addBonusToPoints sts =

View File

@ -13,24 +13,20 @@ module Handler.Utils.Submission
import Import hiding (joinPath) import Import hiding (joinPath)
import Jobs.Queue import Jobs.Queue
import Yesod.Core.Types (HandlerContents(..), ErrorResponse(..)) import Yesod.Core.Types (HandlerContents(..))
import Control.Monad.State as State (StateT)
import Control.Monad.State.Class as State import Control.Monad.State.Class as State
import Control.Monad.Writer (MonadWriter(..), execWriterT, execWriter)
import Control.Monad.RWS.Lazy (MonadRWS, RWST, execRWST) import Control.Monad.RWS.Lazy (MonadRWS, RWST, execRWST)
import qualified Control.Monad.Random as Rand import qualified Control.Monad.Random as Rand
import Data.Maybe () import Data.Maybe ()
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Map (Map, (!), (!?)) import Data.Map ((!), (!?))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.Monoid (Monoid, Any(..), Sum(..))
import Generics.Deriving.Monoid (memptydefault, mappenddefault) import Generics.Deriving.Monoid (memptydefault, mappenddefault)
import Handler.Utils import Handler.Utils

View File

@ -10,7 +10,6 @@ import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..))
import System.FilePath.Glob import System.FilePath.Glob
import Data.Text (Text)
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.IO as Text import qualified Data.Text.IO as Text

View File

@ -2,12 +2,7 @@ module Handler.Utils.Table.Cells where
import Import hiding (link) import Import hiding (link)
import Data.CaseInsensitive (CI)
-- import qualified Data.CaseInsensitive as CI
import Data.Monoid (Any(..))
import Control.Monad.Writer.Class (MonadWriter(..)) import Control.Monad.Writer.Class (MonadWriter(..))
import Control.Monad.Trans.Writer (WriterT)
import Text.Blaze (ToMarkup(..)) import Text.Blaze (ToMarkup(..))

View File

@ -61,21 +61,18 @@ import qualified Yesod.Form.Functions as Yesod
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
import qualified Database.Esqueleto.Utils as E import qualified Database.Esqueleto.Utils as E
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect,unsafeSqlValue) import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect,unsafeSqlValue)
import qualified Database.Esqueleto.Internal.Language as E (From)
import qualified Network.Wai as Wai import qualified Network.Wai as Wai
import Control.Monad.RWS (RWST(..), execRWS) import Control.Monad.RWS (RWST(..), execRWS)
import Control.Monad.Writer (WriterT(..)) import Control.Monad.State (evalStateT)
import Control.Monad.Reader (ReaderT(..), mapReaderT)
import Control.Monad.State (StateT(..), evalStateT)
import Control.Monad.Trans.Maybe import Control.Monad.Trans.Maybe
import Control.Monad.State.Class (modify) import Control.Monad.State.Class (modify)
import qualified Control.Monad.State.Class as State import qualified Control.Monad.State.Class as State
import Data.Foldable (Foldable(foldMap)) import Data.Foldable (Foldable(foldMap))
import Data.Map (Map, (!)) import Data.Map ((!))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
@ -90,20 +87,14 @@ import Colonnade.Encode hiding (row)
import Text.Hamlet (hamletFile) import Text.Hamlet (hamletFile)
import Data.Ratio ((%))
import Data.List (elemIndex) import Data.List (elemIndex)
import Data.Maybe (fromJust) import Data.Maybe (fromJust)
import Data.Aeson (Options(..), SumEncoding(..), defaultOptions)
import Data.Aeson.Text import Data.Aeson.Text
import Data.Aeson.TH (deriveJSON)
import qualified Data.Text as Text import qualified Data.Text as Text
import Data.Proxy (Proxy(..))
import qualified Data.Binary as B import qualified Data.Binary as B
import qualified Data.ByteArray as BA (convert) import qualified Data.ByteArray as BA (convert)
import Crypto.MAC.HMAC (hmac, HMAC) import Crypto.MAC.HMAC (hmac, HMAC)
@ -140,7 +131,8 @@ instance PathPiece x => PathPiece (WithIdent x) where
| not . null $ toPathPiece ident = toPathPiece ident <> "-" <> toPathPiece x | not . null $ toPathPiece ident = toPathPiece ident <> "-" <> toPathPiece x
| otherwise = toPathPiece x | otherwise = toPathPiece x
fromPathPiece txt = do fromPathPiece txt = do
let sep = "-" let sep :: Text
sep = "-"
(ident, (Text.stripSuffix sep -> Just rest)) <- return $ Text.breakOn sep txt (ident, (Text.stripSuffix sep -> Just rest)) <- return $ Text.breakOn sep txt
WithIdent <$> pure ident <*> fromPathPiece rest WithIdent <$> pure ident <*> fromPathPiece rest
@ -188,7 +180,8 @@ deriveJSON defaultOptions
instance PathPiece SortingSetting where instance PathPiece SortingSetting where
toPathPiece SortingSetting{..} = toPathPiece sortKey <> "-" <> toPathPiece sortDir toPathPiece SortingSetting{..} = toPathPiece sortKey <> "-" <> toPathPiece sortDir
fromPathPiece str = do fromPathPiece str = do
let sep = "-" let sep :: Text
sep = "-"
let (Text.dropEnd (Text.length sep) -> key, dir) = Text.breakOnEnd sep str let (Text.dropEnd (Text.length sep) -> key, dir) = Text.breakOnEnd sep str
SortingSetting <$> fromPathPiece key <*> fromPathPiece dir SortingSetting <$> fromPathPiece key <*> fromPathPiece dir
@ -829,8 +822,9 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db
dbsAttrs' dbsAttrs'
| not $ null dbtIdent = ("id", dbtIdent) : dbsAttrs | not $ null dbtIdent = ("id", dbtIdent) : dbsAttrs
| otherwise = dbsAttrs | otherwise = dbsAttrs
multiTextField :: forall m'. Applicative m' => Field m' [Text]
multiTextField = Field multiTextField = Field
{ fieldParse = \ts _ -> return . Right $ Just ts { fieldParse = \ts _ -> pure . Right $ Just ts
, fieldView = error "multiTextField: should not be rendered" , fieldView = error "multiTextField: should not be rendered"
, fieldEnctype = UrlEncoded , fieldEnctype = UrlEncoded
} }
@ -939,6 +933,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db
, formSubmit = FormSubmit , formSubmit = FormSubmit
, formAnchor = Just $ wIdent "csv-import" , formAnchor = Just $ wIdent "csv-import"
} }
csvImportExplanation :: Widget
csvImportExplanation = modal [whamlet|_{MsgCsvImportExplanationLabel}|] $ Right $(i18nWidgetFile "table/csv-import-explanation") csvImportExplanation = modal [whamlet|_{MsgCsvImportExplanationLabel}|] $ Right $(i18nWidgetFile "table/csv-import-explanation")
csvColExplanations = case dbtCsvEncode of csvColExplanations = case dbtCsvEncode of
Just (DBTCsvEncode{} :: DBTCsvEncode r' k' csv) -> assertM' (not . null) . Map.toList . csvColumnsExplanations $ Proxy @csv Just (DBTCsvEncode{} :: DBTCsvEncode r' k' csv) -> assertM' (not . null) . Map.toList . csvColumnsExplanations $ Proxy @csv
@ -1246,6 +1241,7 @@ pagesizeOptions psLim = impureNonNull . Set.toAscList . Set.fromList $ psLim : P
opts :: [Int64] opts :: [Int64]
opts = filter (> 0) $ opts' <> map (`div` 2) opts' opts = filter (> 0) $ opts' <> map (`div` 2) opts'
opts' :: [Int64]
opts' = [ 10^n | n <- [1..3]] opts' = [ 10^n | n <- [1..3]]
pagesizeField :: PagesizeLimit -> Field Handler PagesizeLimit pagesizeField :: PagesizeLimit -> Field Handler PagesizeLimit

View File

@ -14,10 +14,6 @@ import Import hiding (singleton)
import Colonnade import Colonnade
import Colonnade.Encode import Colonnade.Encode
import Data.CaseInsensitive (CI)
import Data.Aeson (FromJSON, ToJSON, FromJSONKey, ToJSONKey)
{-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-} {-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-}
newtype FilterKey = FilterKey { _unFilterKey :: CI Text } newtype FilterKey = FilterKey { _unFilterKey :: CI Text }

View File

@ -17,10 +17,8 @@ import Import
-- import qualified Data.UUID.Cryptographic as UUID -- import qualified Data.UUID.Cryptographic as UUID
-- import Control.Monad.Trans.Writer (mapWriterT) -- import Control.Monad.Trans.Writer (mapWriterT)
-- import Database.Persist.Sql (fromSqlKey) -- import Database.Persist.Sql (fromSqlKey)
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.List as List import qualified Data.List as List
import Data.Map (Map)
import qualified Data.Map as Map import qualified Data.Map as Map

View File

@ -5,8 +5,6 @@ module Handler.Utils.Tokens
import Import import Import
import Control.Monad.Trans.Maybe (runMaybeT)
maybeBearerToken :: (MonadHandler m, HandlerSite m ~ UniWorX, MonadCatch m) => m (Maybe (BearerToken UniWorX)) maybeBearerToken :: (MonadHandler m, HandlerSite m ~ UniWorX, MonadCatch m) => m (Maybe (BearerToken UniWorX))
maybeBearerToken = runMaybeT $ catchIfMaybeT cPred requireBearerToken maybeBearerToken = runMaybeT $ catchIfMaybeT cPred requireBearerToken

View File

@ -9,7 +9,7 @@ module Handler.Utils.Users
import Import import Import
import Auth.LDAP (campusUserMatr') import Auth.LDAP (campusUserMatr')
import Crypto.Hash (Digest, SHA3_256, hashlazy) import Crypto.Hash (hashlazy)
import Data.ByteArray (constEq) import Data.ByteArray (constEq)

View File

@ -109,6 +109,7 @@ i18n = toWidget . (SomeMessage :: msg -> SomeMessage (HandlerSite m))
examOccurrenceMappingDescriptionWidget :: ExamOccurrenceRule -> Set ExamOccurrenceMappingDescription -> Widget examOccurrenceMappingDescriptionWidget :: ExamOccurrenceRule -> Set ExamOccurrenceMappingDescription -> Widget
examOccurrenceMappingDescriptionWidget rule descriptions = $(widgetFile "widgets/exam-occurrence-mapping-description") examOccurrenceMappingDescriptionWidget rule descriptions = $(widgetFile "widgets/exam-occurrence-mapping-description")
where where
titleCase :: [CI Char] -> String
titleCase = over _head Char.toUpper . map CI.foldedCase titleCase = over _head Char.toUpper . map CI.foldedCase
doPrefix doPrefix
| ExamRoomMatriculation <- rule | ExamRoomMatriculation <- rule

View File

@ -20,7 +20,6 @@ import Codec.Archive.Zip.Conduit.Zip
-- import qualified Data.ByteString.Lazy as Lazy (ByteString) -- import qualified Data.ByteString.Lazy as Lazy (ByteString)
import qualified Data.ByteString.Lazy as Lazy.ByteString import qualified Data.ByteString.Lazy as Lazy.ByteString
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString import qualified Data.ByteString as ByteString
import System.FilePath import System.FilePath

View File

@ -1,6 +1,7 @@
module Import.NoModel module Import.NoModel
( module Import ( module Import
, MForm , MForm
, WeekDay
) where ) where
import ClassyPrelude.Yesod as Import import ClassyPrelude.Yesod as Import
@ -16,7 +17,6 @@ import ClassyPrelude.Yesod as Import
, HasHttpManager(..) , HasHttpManager(..)
, embed , embed
, try, embed, catches, handle, catch, bracket, bracketOnError, bracket_, catchJust, finally, handleJust, mask, mask_, onException, tryJust, uninterruptibleMask, uninterruptibleMask_ , try, embed, catches, handle, catch, bracket, bracketOnError, bracket_, catchJust, finally, handleJust, mask, mask_, onException, tryJust, uninterruptibleMask, uninterruptibleMask_
, fail
, htmlField , htmlField
) )
@ -30,7 +30,6 @@ import Mail as Import
import Yesod.Auth as Import import Yesod.Auth as Import
import Yesod.Core.Types as Import (loggerSet) import Yesod.Core.Types as Import (loggerSet)
import Yesod.Default.Config2 as Import import Yesod.Default.Config2 as Import
import Yesod.Core.Json as Import (provideJson)
import Yesod.Core.Types.Instances as Import import Yesod.Core.Types.Instances as Import
import Utils as Import import Utils as Import
@ -53,15 +52,13 @@ import UnliftIO.Pool as Import (Pool)
import Network.HaskellNet.SMTP as Import (SMTPConnection) import Network.HaskellNet.SMTP as Import (SMTPConnection)
import Data.Data as Import (Data) import Data.Data as Import (Data)
import Data.Typeable as Import (Typeable)
import GHC.Generics as Import (Generic)
import GHC.Exts as Import (IsList) import GHC.Exts as Import (IsList)
import Data.Ix as Import (Ix) import Data.Ix as Import (Ix)
import Data.Hashable as Import import Data.Hashable as Import
import Data.List.NonEmpty as Import (NonEmpty(..), nonEmpty) import Data.List.NonEmpty as Import (NonEmpty(..), nonEmpty)
import Data.Text.Encoding.Error as Import(UnicodeException(..)) import Data.Text.Encoding.Error as Import(UnicodeException(..))
import Data.Semigroup as Import (Semigroup, Min(..), Max(..)) import Data.Semigroup as Import (Min(..), Max(..))
import Data.Monoid as Import (Last(..), First(..), Any(..), All(..), Sum(..), Endo(..), Alt(..)) import Data.Monoid as Import (Last(..), First(..), Any(..), All(..), Sum(..), Endo(..), Alt(..))
import Data.Binary as Import (Binary) import Data.Binary as Import (Binary)
@ -82,8 +79,8 @@ import Control.Monad.Random.Class as Import (MonadRandom(..))
import Control.Monad.Morph as Import import Control.Monad.Morph as Import
import Control.Monad.Trans.Resource as Import (ReleaseKey) import Control.Monad.Trans.Resource as Import (ReleaseKey)
import Control.Monad.Trans.Reader as Import import Control.Monad.Trans.Reader as Import
( reader, Reader, runReader, mapReader, withReader ( reader, runReader, mapReader, withReader
, ReaderT(..), mapReaderT, withReaderT , mapReaderT, withReaderT
) )
import Control.Monad.Trans.State as Import import Control.Monad.Trans.State as Import
( state, State, runState, mapState, withState ( state, State, runState, mapState, withState
@ -103,17 +100,15 @@ import Jose.Jwt as Import (Jwt)
import Data.Time.Calendar as Import import Data.Time.Calendar as Import
import Data.Time.Clock as Import import Data.Time.Clock as Import
import Data.Time.LocalTime as Import hiding (utcToLocalTime, utcToZonedTime, localTimeToUTC) import Data.Time.LocalTime as Import hiding (utcToLocalTime, utcToZonedTime, localTimeToUTC)
import Time.Types as Import (WeekDay(..))
import Network.Mime as Import import Network.Mime as Import
import Data.Aeson.TH as Import import Data.Aeson.TH as Import
import Data.Aeson.Types as Import (FromJSON(..), ToJSON(..), FromJSONKey(..), ToJSONKey(..), toJSONKeyText, FromJSONKeyFunction(..), ToJSONKeyFunction(..), Value) import Data.Aeson.Types as Import (FromJSONKey(..), ToJSONKey(..), toJSONKeyText, FromJSONKeyFunction(..), ToJSONKeyFunction(..))
import Data.Constraint as Import (Dict(..)) import Data.Constraint as Import (Dict(..))
import Data.Void as Import (Void)
import Algebra.Lattice as Import hiding (meet, join) import Algebra.Lattice as Import
import Data.Proxy as Import (Proxy(..)) import Data.Proxy as Import (Proxy(..))
@ -133,7 +128,6 @@ import Data.Time.Clock.Instances as Import ()
import Data.Time.LocalTime.Instances as Import () import Data.Time.LocalTime.Instances as Import ()
import Data.Time.Calendar.Instances as Import () import Data.Time.Calendar.Instances as Import ()
import Data.Time.Format.Instances as Import () import Data.Time.Format.Instances as Import ()
import Time.Types.Instances as Import ()
import Network.Mail.Mime.Instances as Import () import Network.Mail.Mime.Instances as Import ()
import Yesod.Core.Instances as Import () import Yesod.Core.Instances as Import ()
import Data.Aeson.Types.Instances as Import () import Data.Aeson.Types.Instances as Import ()
@ -177,3 +171,5 @@ import Data.Encoding.UTF8 as Import (UTF8(UTF8))
import Control.Monad.Trans.RWS (RWST) import Control.Monad.Trans.RWS (RWST)
type MForm m = RWST (Maybe (Env, FileEnv), HandlerSite m, [Lang]) Enctype Ints m type MForm m = RWST (Maybe (Env, FileEnv), HandlerSite m, [Lang]) Enctype Ints m
type WeekDay = DayOfWeek

View File

@ -7,7 +7,6 @@ module Jobs
import Import import Import
import Jobs.Types as Types hiding (JobCtl(JobCtlQueue)) import Jobs.Types as Types hiding (JobCtl(JobCtlQueue))
import Jobs.Types (JobCtl(JobCtlQueue))
import Jobs.Queue import Jobs.Queue
import Jobs.Crontab import Jobs.Crontab
@ -18,17 +17,13 @@ import qualified Data.Text.Lazy as LT
import Data.Aeson (fromJSON) import Data.Aeson (fromJSON)
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Types as Aeson import qualified Data.Aeson.Types as Aeson
import Database.Persist.Sql (fromSqlKey)
import Data.Semigroup (Max(..))
import Utils.Sql import Utils.Sql
import Control.Monad.Random (evalRand, mkStdGen, getRandomR, uniformMay) import Control.Monad.Random (evalRand, mkStdGen, uniformMay)
import Cron import Cron
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap
import Data.HashMap.Strict (HashMap)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
@ -36,16 +31,9 @@ import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Data.Map.Strict ((!)) import Data.Map.Strict ((!))
import Data.Foldable (foldrM)
import Control.Monad.Trans.Reader (mapReaderT)
import Control.Monad.Trans.Writer (execWriterT)
import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST, evalRWST) import Control.Monad.Trans.RWS.Lazy (RWST, mapRWST, evalRWST)
import qualified Control.Monad.State.Class as State import qualified Control.Monad.State.Class as State
import Control.Monad.Writer.Class (MonadWriter(..)) import Control.Monad.Writer.Class (MonadWriter(..))
import Control.Monad.Reader.Class (MonadReader(..))
import Control.Monad.Trans.Resource (runResourceT)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Trans.Cont (ContT(..), callCC) import Control.Monad.Trans.Cont (ContT(..), callCC)
import Control.Monad.Random.Lazy (evalRandTIO, mapRandT) import Control.Monad.Random.Lazy (evalRandTIO, mapRandT)
import Control.Monad.Logger import Control.Monad.Logger

View File

@ -1,3 +1,5 @@
{-# OPTIONS_GHC -fno-warn-incomplete-record-updates #-}
module Jobs.Crontab module Jobs.Crontab
( determineCrontab ( determineCrontab
) where ) where
@ -9,7 +11,6 @@ import Jobs.Types
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Semigroup (Max(..))
import Data.Time.Zones import Data.Time.Zones
import Data.Time.Clock.POSIX import Data.Time.Clock.POSIX
@ -17,7 +18,6 @@ import Data.Time.Clock.POSIX
import Handler.Utils.DateTime import Handler.Utils.DateTime
import Handler.Utils.Allocation (allocationDone) import Handler.Utils.Allocation (allocationDone)
import Control.Monad.Trans.Writer (WriterT, execWriterT)
import Control.Monad.Writer.Class (MonadWriter(..)) import Control.Monad.Writer.Class (MonadWriter(..))
import qualified Data.Conduit.List as C import qualified Data.Conduit.List as C

View File

@ -6,8 +6,6 @@ import Import
import Jobs.Queue import Jobs.Queue
import Control.Monad.Trans.Reader (mapReaderT)
import Handler.Utils.Submission import Handler.Utils.Submission
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -4,8 +4,6 @@ module Jobs.Handler.QueueNotification
import Import import Import
import Data.List (nub)
import Jobs.Types import Jobs.Types
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E

View File

@ -12,6 +12,9 @@ import qualified Data.CaseInsensitive as CI
import Handler.Utils.Csv (partIsAttachmentCsv) import Handler.Utils.Csv (partIsAttachmentCsv)
{-# ANN module ("HLint: ignore Too strict maybe"::String) #-}
dispatchJobSendCourseCommunication :: Either UserEmail UserId dispatchJobSendCourseCommunication :: Either UserEmail UserId
-> Set Address -> Set Address
-> CourseId -> CourseId

View File

@ -51,6 +51,7 @@ dispatchJobSynchroniseLdapUser jUser = do
Nothing -> Nothing ->
throwM SynchroniseLdapNoLdap throwM SynchroniseLdapNoLdap
where where
handleExc :: MaybeT DB a -> MaybeT DB a
handleExc handleExc
= catchMPlus (Proxy @CampusUserException) = catchMPlus (Proxy @CampusUserException)
. catchMPlus (Proxy @CampusUserConversionException) . catchMPlus (Proxy @CampusUserConversionException)

View File

@ -10,7 +10,6 @@ import Data.List (genericLength)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import Data.Proxy (Proxy(..))
import qualified Data.ByteArray as ByteArray import qualified Data.ByteArray as ByteArray
@ -124,7 +123,9 @@ dispatchHealthCheckWidgetMemcached :: Handler HealthReport
dispatchHealthCheckWidgetMemcached = fmap HealthWidgetMemcached . yesodTimeout (^. _appHealthCheckActiveWidgetMemcachedTimeout) (Just False) $ do dispatchHealthCheckWidgetMemcached = fmap HealthWidgetMemcached . yesodTimeout (^. _appHealthCheckActiveWidgetMemcachedTimeout) (Just False) $ do
memcachedConn <- getsYesod appWidgetMemcached memcachedConn <- getsYesod appWidgetMemcached
for memcachedConn $ \_memcachedConn' -> do for memcachedConn $ \_memcachedConn' -> do
let ext = "bin" let ext :: Text
ext = "bin"
mimeType :: Text
mimeType = "application/octet-stream" mimeType = "application/octet-stream"
content <- pack . take 256 <$> liftIO getRandoms content <- pack . take 256 <$> liftIO getRandoms
staticLink <- addStaticContent ext mimeType content staticLink <- addStaticContent ext mimeType content

View File

@ -14,9 +14,7 @@ import Import hiding ((<>))
import Utils.Sql import Utils.Sql
import Jobs.Types import Jobs.Types
import Control.Monad.Trans.Writer (WriterT, runWriterT)
import Control.Monad.Writer.Class (MonadWriter(..)) import Control.Monad.Writer.Class (MonadWriter(..))
import Control.Monad.Trans.Reader (ReaderT, mapReaderT)
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import qualified Data.Set as Set import qualified Data.Set as Set

View File

@ -1,3 +1,4 @@
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Jobs.Types module Jobs.Types
@ -19,13 +20,9 @@ module Jobs.Types
import Import.NoFoundation hiding (Unique, state) import Import.NoFoundation hiding (Unique, state)
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import Data.Aeson (defaultOptions, Options(..), SumEncoding(..))
import Data.Aeson.TH (deriveJSON)
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap
import Data.List.NonEmpty (NonEmpty)
import Data.Unique import Data.Unique
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map

View File

@ -35,8 +35,6 @@ data LdapExecutor = LdapExecutor
, ldapAsync :: Async () , ldapAsync :: Async ()
} }
instance Exception LdapError
data LdapPoolError = LdapPoolTimeout | LdapError LdapError data LdapPoolError = LdapPoolTimeout | LdapError LdapError
deriving (Eq, Show, Generic, Typeable) deriving (Eq, Show, Generic, Typeable)
@ -93,7 +91,10 @@ createLdapPool host port stripes timeoutConn (round . (* 1e6) -> timeoutAct) lim
$logErrorS "LdapExecutor" "Could not return result" $logErrorS "LdapExecutor" "Could not return result"
either throwM (const $ return ()) res either throwM (const $ return ()) res
`catches` `catches`
[ Handler (\(Ldap.ResponseError _) -> return ()) [ Handler $ \case
Ldap.ResponseError _ -> return ()
Ldap.DisconnectError _ -> return ()
other -> throwM other
] ]
go Nothing ldap go Nothing ldap

View File

@ -33,7 +33,7 @@ module Mail
, setMailSmtpData , setMailSmtpData
, _addressName, _addressEmail , _addressName, _addressEmail
, _mailFrom, _mailTo, _mailCc, _mailBcc, _mailHeaders, _mailHeader, _mailParts , _mailFrom, _mailTo, _mailCc, _mailBcc, _mailHeaders, _mailHeader, _mailParts
, _partType, _partEncoding, _partFilename, _partHeaders, _partContent , _partType, _partEncoding, _partDisposition, _partFilename, _partHeaders, _partContent
) where ) where
import ClassyPrelude.Yesod hiding (snoc, (.=), getMessageRender, derivePersistFieldJSON) import ClassyPrelude.Yesod hiding (snoc, (.=), getMessageRender, derivePersistFieldJSON)
@ -49,18 +49,15 @@ import Data.Monoid (Last(..))
import Control.Monad.Trans.RWS (RWST(..)) import Control.Monad.Trans.RWS (RWST(..))
import Control.Monad.Trans.State (StateT(..), execStateT, mapStateT) import Control.Monad.Trans.State (StateT(..), execStateT, mapStateT)
import Control.Monad.Trans.Writer (execWriter, Writer) import Control.Monad.Trans.Writer (execWriter, Writer)
import Control.Monad.RWS.Class (MonadWriter(..), MonadReader(..), MonadState(..), modify) import Control.Monad.RWS.Class (MonadWriter(..), MonadState(..), modify)
import Control.Monad.Fail import Control.Monad.Fail
import Control.Monad.Base import Control.Monad.Base
import Control.Monad.Catch import Control.Monad.Catch
import GHC.Generics (Generic)
import Generics.Deriving.Monoid (memptydefault, mappenddefault) import Generics.Deriving.Monoid (memptydefault, mappenddefault)
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq import qualified Data.Sequence as Seq
import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Text as Text import qualified Data.Text as Text
@ -88,7 +85,7 @@ import qualified Data.Binary as Binary
import "network-bsd" Network.BSD (getHostName) import "network-bsd" Network.BSD (getHostName)
import Data.Time.Zones (TZ, utcTZ, utcToLocalTimeTZ, timeZoneForUTCTime) import Data.Time.Zones (utcTZ, utcToLocalTimeTZ, timeZoneForUTCTime)
import Data.Time.LocalTime (ZonedTime(..), TimeZone(..)) import Data.Time.LocalTime (ZonedTime(..), TimeZone(..))
import Data.Time.Format (rfc822DateFormat) import Data.Time.Format (rfc822DateFormat)
@ -100,7 +97,6 @@ import qualified Text.Shakespeare as Shakespeare (RenderUrl)
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encode.Pretty as Aeson import qualified Data.Aeson.Encode.Pretty as Aeson
import Data.Aeson (Options(..))
import Data.Aeson.TH import Data.Aeson.TH
import Utils.PathPiece (splitCamel) import Utils.PathPiece (splitCamel)
import Utils.DateTime import Utils.DateTime
@ -125,6 +121,14 @@ makeLenses_ ''Address
makeLenses_ ''Mail makeLenses_ ''Mail
makeLenses_ ''Part makeLenses_ ''Part
_partFilename :: Traversal' Part Text
_partFilename = _partDisposition . dispositionFilename
where
dispositionFilename :: Traversal' Disposition Text
dispositionFilename f (AttachmentDisposition t) = AttachmentDisposition <$> f t
dispositionFilename f (InlineDisposition t) = InlineDisposition <$> f t
dispositionFilename _ DefaultDisposition = pure DefaultDisposition
_mailHeader :: CI ByteString -> Traversal' Mail Text _mailHeader :: CI ByteString -> Traversal' Mail Text
_mailHeader hdrName = _mailHeaders . traverse . filtered (views _1 $ (== hdrName) . CI.mk) . _2 _mailHeader hdrName = _mailHeaders . traverse . filtered (views _1 $ (== hdrName) . CI.mk) . _2
@ -328,7 +332,7 @@ instance YesodMail site => ToMailPart site LT.Text where
toMailPart text = do toMailPart text = do
_partType .= decodeUtf8 typePlain _partType .= decodeUtf8 typePlain
_partEncoding .= QuotedPrintableText _partEncoding .= QuotedPrintableText
_partContent .= encodeUtf8 text _partContent .= PartContent (encodeUtf8 text)
instance YesodMail site => ToMailPart site Text where instance YesodMail site => ToMailPart site Text where
toMailPart = toMailPart . LT.fromStrict toMailPart = toMailPart . LT.fromStrict
@ -340,7 +344,7 @@ instance YesodMail site => ToMailPart site Html where
toMailPart html = do toMailPart html = do
_partType .= decodeUtf8 typeHtml _partType .= decodeUtf8 typeHtml
_partEncoding .= QuotedPrintableText _partEncoding .= QuotedPrintableText
_partContent .= renderMarkup html _partContent .= PartContent (renderMarkup html)
instance (ToMailPart site a, RenderMessage site msg) => ToMailPart site (Hamlet.Translate msg -> a) where instance (ToMailPart site a, RenderMessage site msg) => ToMailPart site (Hamlet.Translate msg -> a) where
type MailPartReturn site (Hamlet.Translate msg -> a) = MailPartReturn site a type MailPartReturn site (Hamlet.Translate msg -> a) = MailPartReturn site a
@ -364,7 +368,7 @@ instance YesodMail site => ToMailPart site Aeson.Value where
toMailPart val = do toMailPart val = do
_partType .= decodeUtf8 typeJson _partType .= decodeUtf8 typeJson
_partEncoding .= QuotedPrintableText _partEncoding .= QuotedPrintableText
_partContent .= Aeson.encodePretty val _partContent .= PartContent (Aeson.encodePretty val)
addAlternatives :: (MonadMail m) addAlternatives :: (MonadMail m)
@ -400,9 +404,9 @@ initialPart :: Part
initialPart = Part initialPart = Part
{ partType = decodeUtf8 defaultMimeType { partType = decodeUtf8 defaultMimeType
, partEncoding = Base64 , partEncoding = Base64
, partFilename = Nothing , partDisposition = DefaultDisposition
, partHeaders = [] , partHeaders = []
, partContent = mempty , partContent = PartContent mempty
} }
modifyPart :: (MonadMail m, HandlerSite m ~ site, YesodMail site) modifyPart :: (MonadMail m, HandlerSite m ~ site, YesodMail site)
@ -413,7 +417,7 @@ modifyPart = toMailPart
partIsAttachment :: (Textual t, MonadMail m, HandlerSite m ~ site, YesodMail site) partIsAttachment :: (Textual t, MonadMail m, HandlerSite m ~ site, YesodMail site)
=> t => t
-> StateT Part m () -> StateT Part m ()
partIsAttachment (repack -> fName) = modifyPart $ _partFilename .= Just fName partIsAttachment (repack -> fName) = modifyPart $ _partDisposition .= AttachmentDisposition fName
class MonadHandler m => MonadHeader m where class MonadHandler m => MonadHeader m where

View File

@ -1,4 +1,4 @@
{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances, DeriveAnyClass #-}
module Model module Model
( module Model ( module Model
@ -14,13 +14,9 @@ import Database.Persist.TH.Directory
import Model.Types hiding (_maxPoints, _passingPoints) import Model.Types hiding (_maxPoints, _passingPoints)
import Cron.Types import Cron.Types
import Data.Aeson (Value) import Data.CaseInsensitive (original)
import Data.CaseInsensitive (CI, original)
import Data.CaseInsensitive.Instances () import Data.CaseInsensitive.Instances ()
import Utils.Message (MessageStatus)
import Settings.Cluster (ClusterSettingsKey) import Settings.Cluster (ClusterSettingsKey)
import Text.Blaze (ToMarkup(..)) import Text.Blaze (ToMarkup(..))

View File

@ -1,21 +1,17 @@
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances, GeneralizedNewtypeDeriving #-}
module Model.Migration module Model.Migration
( migrateAll ( migrateAll
, requiresMigration , requiresMigration
) where ) where
import Utils (lastMaybe)
import Import.NoModel import Import.NoModel
import Model import Model
import Audit.Types import Audit.Types
import Model.Migration.Version import Model.Migration.Version
import qualified Model.Migration.Types as Legacy import qualified Model.Migration.Types as Legacy
import Data.Map (Map)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Set ()
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Data.Text as Text import qualified Data.Text as Text
@ -26,25 +22,15 @@ import Database.Persist.Sql
import Database.Persist.Sql.Raw.QQ import Database.Persist.Sql.Raw.QQ
import Database.Persist.Postgresql import Database.Persist.Postgresql
import Control.Monad.Trans.Maybe (MaybeT(..))
import Text.Read (readMaybe) import Text.Read (readMaybe)
import Data.CaseInsensitive (CI)
import Text.Shakespeare.Text (st)
import Control.Monad.Trans.Reader (mapReaderT)
import Control.Monad.Except (MonadError(..)) import Control.Monad.Except (MonadError(..))
import Utils (exceptT, allM, whenIsJust, guardM)
import Utils.Lens (_NoUpload) import Utils.Lens (_NoUpload)
import Utils.DB (getKeyBy)
import qualified Net.IP as IP import qualified Net.IP as IP
import qualified Net.IPv4 as IPv4 import qualified Net.IPv4 as IPv4
import qualified Net.IPv6 as IPv6 import qualified Net.IPv6 as IPv6
import Data.Aeson (toJSON)
import qualified Data.Char as Char import qualified Data.Char as Char
import qualified Data.CaseInsensitive as CI import qualified Data.CaseInsensitive as CI

View File

@ -2,7 +2,7 @@ module Model.Migration.Types where
import ClassyPrelude.Yesod import ClassyPrelude.Yesod
import Data.Aeson import Data.Aeson
import Data.Aeson.TH (deriveJSON, defaultOptions) import Data.Aeson.TH (deriveJSON)
import Utils.PathPiece import Utils.PathPiece

View File

@ -4,8 +4,6 @@ import ClassyPrelude.Yesod
import Model import Model
-- import Data.Text (Text) -- import Data.Text (Text)
import Data.Text.Encoding.Error (UnicodeException(..)) import Data.Text.Encoding.Error (UnicodeException(..))
import GHC.Generics (Generic)
import Data.Typeable (Typeable)
data Rating = Rating data Rating = Rating

View File

@ -1,3 +1,4 @@
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances #-}
module Model.Tokens module Model.Tokens
@ -23,14 +24,12 @@ import qualified Jose.Jwt as Jose
import Jose.Jwt.Instances () import Jose.Jwt.Instances ()
import Data.Aeson.Types.Instances () import Data.Aeson.Types.Instances ()
import Data.HashSet (HashSet)
import qualified Data.HashMap.Strict as HashMap import qualified Data.HashMap.Strict as HashMap
import Data.HashMap.Strict.Instances () import Data.HashMap.Strict.Instances ()
import Data.HashSet.Instances () import Data.HashSet.Instances ()
import Data.Time.Clock.Instances () import Data.Time.Clock.Instances ()
import Data.Aeson.Types (Parser, (.:?), (.:), (.!=), (.=)) import Data.Aeson.Types (Parser, (.:?), (.!=))
import qualified Data.Aeson as JSON import qualified Data.Aeson as JSON
import qualified Data.Aeson.Types as JSON import qualified Data.Aeson.Types as JSON

View File

@ -14,7 +14,7 @@ import qualified Data.Vector as Vector
import qualified Data.Map.Strict as Map import qualified Data.Map.Strict as Map
import Crypto.Hash (Digest, SHAKE128) import Crypto.Hash (SHAKE128)
{-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-} {-# ANN module ("HLint: ignore Use newtype instead of data"::String) #-}

View File

@ -1,3 +1,4 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-| {-|
Module: Model.Types.DateTime Module: Model.Types.DateTime
Description: Time related types Description: Time related types
@ -20,9 +21,6 @@ import Web.HttpApiData
import Data.Aeson.Types as Aeson import Data.Aeson.Types as Aeson
import Time.Types (WeekDay(..))
import Data.Time.LocalTime (LocalTime, TimeOfDay)
---- ----
-- Terms, Seaons, anything loosely related to time -- Terms, Seaons, anything loosely related to time
@ -42,6 +40,7 @@ seasonFromChar c
| c ~= 'W' = Right Winter | c ~= 'W' = Right Winter
| otherwise = Left $ "Invalid season character: " <> tshow c <> "" | otherwise = Left $ "Invalid season character: " <> tshow c <> ""
where where
(~=) :: Char -> Char -> Bool
(~=) = (==) `on` CI.mk (~=) = (==) `on` CI.mk
data TermIdentifier = TermIdentifier data TermIdentifier = TermIdentifier
@ -64,6 +63,7 @@ shortened :: Iso' Integer Integer
-- ^ Year numbers shortened to two digits -- ^ Year numbers shortened to two digits
shortened = iso shorten expand shortened = iso shorten expand
where where
century :: Integer
century = ($currentYear `div` 100) * 100 century = ($currentYear `div` 100) * 100
expand year expand year
| 0 <= year | 0 <= year
@ -189,3 +189,5 @@ deriveJSON defaultOptions
} ''Occurrences } ''Occurrences
derivePersistFieldJSON ''Occurrences derivePersistFieldJSON ''Occurrences
nullaryPathPiece ''DayOfWeek camelToPathPiece

View File

@ -231,6 +231,7 @@ instance Finite ExamGrade
numberGrade :: Prism' Rational ExamGrade numberGrade :: Prism' Rational ExamGrade
numberGrade = prism toNumberGrade fromNumberGrade numberGrade = prism toNumberGrade fromNumberGrade
where where
toNumberGrade :: ExamGrade -> Rational
toNumberGrade = \case toNumberGrade = \case
Grade50 -> 5.0 Grade50 -> 5.0
Grade40 -> 4.0 Grade40 -> 4.0
@ -243,6 +244,7 @@ numberGrade = prism toNumberGrade fromNumberGrade
Grade17 -> 1.7 Grade17 -> 1.7
Grade13 -> 1.3 Grade13 -> 1.3
Grade10 -> 1.0 Grade10 -> 1.0
fromNumberGrade :: Rational -> Either Rational ExamGrade
fromNumberGrade = \case fromNumberGrade = \case
5.0 -> Right Grade50 5.0 -> Right Grade50
4.0 -> Right Grade40 4.0 -> Right Grade40
@ -271,7 +273,8 @@ instance Csv.FromField ExamGrade where
[ parse =<< Csv.parseField x [ parse =<< Csv.parseField x
, parse . Text.replace "," "." =<< Csv.parseField x -- Ugh. , parse . Text.replace "," "." =<< Csv.parseField x -- Ugh.
] ]
where parse = maybe (fail "Could not decode PathPiece") return . fromPathPiece where parse :: Text -> Csv.Parser ExamGrade
parse = maybe (fail "Could not decode PathPiece") return . fromPathPiece
instance PersistField ExamGrade where instance PersistField ExamGrade where
toPersistValue = PersistRational . review numberGrade toPersistValue = PersistRational . review numberGrade

Some files were not shown because too many files have changed in this diff Show More