diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 97f40010b..a024f19a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,6 @@ default: image: - name: fpco/stack-build:lts-13.21 + name: fpco/stack-build:lts-15.0 cache: paths: - node_modules diff --git a/.hlint.yaml b/.hlint.yaml index 6b2cec643..7f5b23d47 100644 --- a/.hlint.yaml +++ b/.hlint.yaml @@ -5,6 +5,7 @@ - ignore: { name: "Parse error" } - ignore: { name: "Reduce duplication" } - ignore: { name: "Redundant lambda" } + - ignore: { name: "Redundant multi-way if" } - ignore: { name: "Use ||" } - ignore: { name: "Use &&" } - ignore: { name: "Use ++" } diff --git a/ghci.sh b/ghci.sh index 750d384b8..441f9f649 100755 --- a/ghci.sh +++ b/ghci.sh @@ -20,4 +20,4 @@ if [[ -d .stack-work-ghci ]]; then trap move-back EXIT 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} diff --git a/package.yaml b/package.yaml index 32a5bd8df..1d643c348 100644 --- a/package.yaml +++ b/package.yaml @@ -120,7 +120,6 @@ dependencies: - lens-aeson - systemd - streaming-commons - - hourglass - unix - stm-delay - cassava @@ -201,6 +200,8 @@ ghc-options: - -Wall - -Wmissing-home-modules - -Wredundant-constraints + - -Widentities + - -Wincomplete-uni-patterns - -fno-warn-type-defaults - -fno-warn-unrecognised-pragmas - -fno-warn-partial-type-signatures diff --git a/src/Application.hs b/src/Application.hs index 83a229d82..ec6220a6f 100644 --- a/src/Application.hs +++ b/src/Application.hs @@ -86,8 +86,6 @@ import Control.Monad.Trans.Cont (runContT, callCC) import qualified Data.Set as Set -import Data.Semigroup (Min(..)) - import Handler.Utils.Routes (classifyHandler) -- Import all relevant handler modules here. @@ -511,6 +509,8 @@ shutdownApp app = do destroyAllResources $ appConnPool app release . fst $ appLogger app + liftIO $ threadDelay 2e4 + --------------------------------------------- -- Functions for use in development with GHCi diff --git a/src/Auth/Dummy.hs b/src/Auth/Dummy.hs index 90f3e3cee..898349bf0 100644 --- a/src/Auth/Dummy.hs +++ b/src/Auth/Dummy.hs @@ -8,7 +8,6 @@ import Database.Persist.Sql (SqlBackendCanRead) import Utils.Form -import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI @@ -22,7 +21,6 @@ dummyForm :: ( RenderMessage (HandlerSite m) FormMessage , RenderMessage (HandlerSite m) DummyMessage , YesodPersist (HandlerSite m) , SqlBackendCanRead (YesodPersistBackend (HandlerSite m)) - , Button (HandlerSite m) ButtonSubmit , MonadHandler m ) => AForm m (CI Text) dummyForm = wFormToAForm $ do diff --git a/src/Auth/LDAP.hs b/src/Auth/LDAP.hs index 9db9fa7fb..feaa31c44 100644 --- a/src/Auth/LDAP.hs +++ b/src/Auth/LDAP.hs @@ -14,14 +14,12 @@ module Auth.LDAP import Import.NoFoundation import Network.Connection -import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI import qualified Control.Monad.Catch as Exc import Utils.Form -import Ldap.Client (Ldap) import qualified Ldap.Client as Ldap import qualified Data.Text.Encoding as Text diff --git a/src/Auth/PWHash.hs b/src/Auth/PWHash.hs index 3fd716694..2812b67eb 100644 --- a/src/Auth/PWHash.hs +++ b/src/Auth/PWHash.hs @@ -8,7 +8,6 @@ import Database.Persist.Sql (SqlBackendCanRead) import Utils.Form -import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI import Yesod.Auth.Util.PasswordStore (verifyPasswordWith) diff --git a/src/Cron.hs b/src/Cron.hs index 36a063321..4cfc505ac 100644 --- a/src/Cron.hs +++ b/src/Cron.hs @@ -296,20 +296,21 @@ nextCronMatch tz mPrev prec now c@Cron{..} = onlyOnceWithinPrec $ case notAfter <*> genMatch 60 True True cdMinute cronMinute <*> 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 | Just (year, month, dayOfMonth) <- mCronGregorianDate -> return (year, month, dayOfMonth) - | Just (weekYear, week, dayOfWeek) <- mCronWeekDate - -> return . toGregorian' $ fromWeekDate (fromIntegral weekYear) (fromIntegral week) (fromIntegral dayOfWeek) + | Just (weekYear, week, dow) <- mCronWeekDate + -> return . toGregorian' $ fromWeekDate (fromIntegral weekYear) (fromIntegral week) (fromIntegral dow) | Just (year, dayOfYear) <- mCronOrdinalDate -> maybeToList . fmap toGregorian' $ fromOrdinalDateValid (fromIntegral year) (fromIntegral dayOfYear) - | Just (weekYear, month, weekOfMonth, dayOfWeek) <- mCronWeekOfMonthDate + | Just (weekYear, month, weekOfMonth, dow) <- mCronWeekOfMonthDate -> do year <- genMatch 400 False True cdYear cronYear day <- genMatch 31 True False cdDayOfMonth cronDayOfMonth 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) | otherwise -> 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 mCronWeekOfMonth <- if - | Just (weekYear, month, weekOfMonth, dayOfWeek) <- mCronWeekOfMonthDate - -> weekOfMonth <$ guard (weekYear == mCronWeekYear && month == mCronMonth && dayOfWeek == mCronDayOfWeek) + | Just (weekYear, month, weekOfMonth, dow) <- mCronWeekOfMonthDate + -> weekOfMonth <$ guard (weekYear == mCronWeekYear && month == mCronMonth && dow == mCronDayOfWeek) | otherwise -> genMatch 5 True False cdWeekOfMonth cronWeekOfMonth diff --git a/src/Cron/Types.hs b/src/Cron/Types.hs index 576796038..00eec5047 100644 --- a/src/Cron/Types.hs +++ b/src/Cron/Types.hs @@ -15,7 +15,6 @@ import Data.Time import Numeric.Natural -import Data.HashMap.Strict (HashMap) import qualified Data.Set as Set diff --git a/src/Crypto/Hash/Instances.hs b/src/Crypto/Hash/Instances.hs index 3c07f0882..ae803ae92 100644 --- a/src/Crypto/Hash/Instances.hs +++ b/src/Crypto/Hash/Instances.hs @@ -11,15 +11,12 @@ import Database.Persist import Database.Persist.Sql import Data.ByteArray (convert) -import Data.ByteArray.Encoding - -import qualified Data.ByteString.Char8 as CBS import Web.PathPieces import Web.HttpApiData import Data.Aeson as Aeson -import Text.Read as Read +import Control.Monad.Fail 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 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 toPathPiece = showToPathPiece fromPathPiece = readFromPathPiece diff --git a/src/CryptoID.hs b/src/CryptoID.hs index efcc099ca..c7b8618cc 100644 --- a/src/CryptoID.hs +++ b/src/CryptoID.hs @@ -21,10 +21,9 @@ import System.FilePath.Cryptographic.ImplicitNamespace import qualified Data.Text as Text -import Data.CaseInsensitive (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 Text.Blaze (ToMarkup(..)) diff --git a/src/CryptoID/TH.hs b/src/CryptoID/TH.hs index 85f73dc03..0e1065a27 100644 --- a/src/CryptoID/TH.hs +++ b/src/CryptoID/TH.hs @@ -9,7 +9,6 @@ import Data.UUID.Types (UUID) import Data.Binary.SerializationLength import Data.CaseInsensitive (CI) -import System.FilePath (FilePath) import Data.Binary (Binary) import qualified Data.Binary as Binary diff --git a/src/Data/Aeson/Types/Instances.hs b/src/Data/Aeson/Types/Instances.hs index 4e87d05a9..10d4c106e 100644 --- a/src/Data/Aeson/Types/Instances.hs +++ b/src/Data/Aeson/Types/Instances.hs @@ -16,6 +16,8 @@ import Data.Vector.Instances () import Model.Types.TH.JSON (derivePersistFieldJSON) +import Control.Monad.Fail + instance MonadThrow Parser where throwM = fail . show diff --git a/src/Data/Bool/Instances.hs b/src/Data/Bool/Instances.hs index d5eb7a2e0..6ea955599 100644 --- a/src/Data/Bool/Instances.hs +++ b/src/Data/Bool/Instances.hs @@ -12,6 +12,8 @@ import Data.CaseInsensitive.Instances () import qualified Data.Text as Text +import Control.Monad.Fail + instance Csv.ToField Bool where toField True = "t" diff --git a/src/Data/CaseInsensitive/Instances.hs b/src/Data/CaseInsensitive/Instances.hs index f218308f5..77f626338 100644 --- a/src/Data/CaseInsensitive/Instances.hs +++ b/src/Data/CaseInsensitive/Instances.hs @@ -16,12 +16,11 @@ import Database.Persist.Sql import Text.Blaze (ToMarkup(..)) import Text.Shakespeare.Text (ToText(..)) -import Data.Text (Text) import qualified Data.Text.Encoding as Text 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 diff --git a/src/Data/Encoding/Instances.hs b/src/Data/Encoding/Instances.hs index ee73551fb..d9bf3748d 100644 --- a/src/Data/Encoding/Instances.hs +++ b/src/Data/Encoding/Instances.hs @@ -6,13 +6,14 @@ module Data.Encoding.Instances import ClassyPrelude import Utils.PathPiece -import Data.String (IsString(..)) import Text.Read import Web.PathPieces import Data.Encoding +import Control.Monad.Fail + instance PathPiece DynEncoding where toPathPiece = showToPathPiece diff --git a/src/Data/HashMap/Strict/Instances.hs b/src/Data/HashMap/Strict/Instances.hs index 7d56f03a8..daa36c68a 100644 --- a/src/Data/HashMap/Strict/Instances.hs +++ b/src/Data/HashMap/Strict/Instances.hs @@ -7,7 +7,6 @@ module Data.HashMap.Strict.Instances import ClassyPrelude import Data.Binary (Binary(..)) -import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap diff --git a/src/Data/HashSet/Instances.hs b/src/Data/HashSet/Instances.hs index 3fc16cd43..320ac8940 100644 --- a/src/Data/HashSet/Instances.hs +++ b/src/Data/HashSet/Instances.hs @@ -6,7 +6,6 @@ module Data.HashSet.Instances import ClassyPrelude -import Data.HashSet (HashSet) import qualified Data.HashSet as HashSet import Data.Binary (Binary(..)) diff --git a/src/Data/NonNull/Instances.hs b/src/Data/NonNull/Instances.hs index 55981d6ff..8c7c3dca8 100644 --- a/src/Data/NonNull/Instances.hs +++ b/src/Data/NonNull/Instances.hs @@ -11,6 +11,8 @@ import Data.Aeson import Data.Binary (Binary) import qualified Data.Binary as Binary +import Control.Monad.Fail + instance ToJSON a => ToJSON (NonNull a) where toJSON = toJSON . toNullable diff --git a/src/Data/Set/Instances.hs b/src/Data/Set/Instances.hs index 9dc1c48cd..5fe431d92 100644 --- a/src/Data/Set/Instances.hs +++ b/src/Data/Set/Instances.hs @@ -6,7 +6,6 @@ module Data.Set.Instances import ClassyPrelude -import Data.Set (Set) import qualified Data.Set as Set diff --git a/src/Data/Time/Calendar/Instances.hs b/src/Data/Time/Calendar/Instances.hs index 395f455f8..d5dd127ed 100644 --- a/src/Data/Time/Calendar/Instances.hs +++ b/src/Data/Time/Calendar/Instances.hs @@ -7,12 +7,16 @@ module Data.Time.Calendar.Instances import ClassyPrelude 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 Binary Day -instance Binary Day where - get = ModifiedJulianDay <$> Binary.get - put = Binary.put . toModifiedJulianDay - +deriving instance Ord DayOfWeek +instance Universe DayOfWeek where + universe = [Monday .. Sunday] +instance Finite DayOfWeek diff --git a/src/Data/Universe/Instances/Reverse/JSON.hs b/src/Data/Universe/Instances/Reverse/JSON.hs index 7c8dbb3ed..8aed56f14 100644 --- a/src/Data/Universe/Instances/Reverse/JSON.hs +++ b/src/Data/Universe/Instances/Reverse/JSON.hs @@ -15,6 +15,8 @@ import Data.HashMap.Strict ((!)) import Data.Universe +import Control.Monad.Fail + 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] diff --git a/src/Data/Universe/TH.hs b/src/Data/Universe/TH.hs index 1dd097e9f..192182320 100644 --- a/src/Data/Universe/TH.hs +++ b/src/Data/Universe/TH.hs @@ -17,12 +17,21 @@ import Control.Monad (unless) 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 -- ^ Declare generic `Enum`- and `Bounded`-Instances given `Finite`- and `Eq`-Instances finiteEnum tName = do 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)]|] [d| @@ -48,14 +57,14 @@ deriveFinite tName = fmap concat . sequence $ [ deriveUniverse' [e|concat|] [e|universeF|] tName , do 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' interleaveExp universeExp tName = do 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 unless (null constructorVars) $ fail "Constructors with variables no supported" diff --git a/src/Data/Vector/Instances.hs b/src/Data/Vector/Instances.hs index 953130328..ecb64bd69 100644 --- a/src/Data/Vector/Instances.hs +++ b/src/Data/Vector/Instances.hs @@ -6,7 +6,6 @@ module Data.Vector.Instances import ClassyPrelude -import Data.Vector (Vector) import qualified Data.Vector as Vector import Data.Binary (Binary) diff --git a/src/Database/Persist/Class/Instances.hs b/src/Database/Persist/Class/Instances.hs index 193ea1f16..a44e6071b 100644 --- a/src/Database/Persist/Class/Instances.hs +++ b/src/Database/Persist/Class/Instances.hs @@ -8,7 +8,6 @@ module Database.Persist.Class.Instances import ClassyPrelude import Database.Persist.Class -import Database.Persist.Types (HaskellName, DBName, PersistValue) import Database.Persist.Types.Instances () import Database.Persist.Sql @@ -19,6 +18,8 @@ import qualified Data.Map as Map import Data.Aeson (ToJSONKey, FromJSONKey) +import Control.Monad.Fail + instance PersistEntity record => Hashable (Key record) where hashWithSalt s = hashWithSalt s . toPersistValue diff --git a/src/Foundation.hs b/src/Foundation.hs index d79b5a45e..5c39d6b86 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -2,7 +2,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE OverloadedLabels #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -- MonadCrypto +{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-uni-patterns #-} -- MonadCrypto module Foundation ( module Foundation @@ -29,43 +29,36 @@ import qualified Yesod.Core.Unsafe as Unsafe import qualified Data.CaseInsensitive as CI import Data.ByteArray (convert) -import Crypto.Hash (Digest, SHAKE256, SHAKE128) +import Crypto.Hash (SHAKE256, SHAKE128) import Crypto.Hash.Conduit (sinkHash) import qualified Data.UUID as UUID import qualified Data.Binary as Binary 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 as ByteString import qualified Data.Text as Text import qualified Data.Text.Encoding as Text -import Data.Set (Set) import qualified Data.Set as Set -import Data.Map (Map, (!?)) +import Data.Map ((!?)) import qualified Data.Map as Map import qualified Data.HashSet as HashSet 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 Web.Cookie -import Data.Monoid (Any(..)) - import Data.Conduit.List (sourceList) import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils as E 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.Writer.Class (MonadWriter(..)) import Control.Monad.Memo.Class (MonadMemo(..), for4) @@ -82,7 +75,6 @@ import Utils.Form import Utils.Sheet import Utils.SystemMessage -import Text.Shakespeare.Text (st) import Text.Cassius (cassiusFile) 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 cid <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh 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) return Authorized CourseR tid ssh csh _ -> maybeT (unauthorizedI MsgCourseNoCapacity) $ do 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) return Authorized r -> $unsupportedAuthPredicate AuthCapacity r @@ -1298,7 +1290,7 @@ routeAuthTags = fmap (PredDNF . Set.mapMonotonic impureNonNull) . ofoldM partiti | otherwise = 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 evalAuthTags AuthTagActive{..} (map (Set.toList . toNullable) . Set.toList . dnfTerms -> authDNF') mAuthId route isWrite = do diff --git a/src/Foundation/I18n.hs b/src/Foundation/I18n.hs index aa7933300..b1ab71296 100644 --- a/src/Foundation/I18n.hs +++ b/src/Foundation/I18n.hs @@ -32,8 +32,6 @@ import qualified Data.Text as Text import Utils.Form -import Text.Shakespeare.Text (st) - import GHC.Exts (IsList(..)) diff --git a/src/Foundation/Type.hs b/src/Foundation/Type.hs index 5b63b9080..f6292c4f9 100644 --- a/src/Foundation/Type.hs +++ b/src/Foundation/Type.hs @@ -13,8 +13,6 @@ import Jobs.Types import Yesod.Core.Types (Logger) -import Data.Set (Set) - import qualified Crypto.Saltine.Core.SecretBox as SecretBox import qualified Jose.Jwk as Jose diff --git a/src/Handler/Admin/StudyFeatures.hs b/src/Handler/Admin/StudyFeatures.hs index 6fe21e14d..f07bdc979 100644 --- a/src/Handler/Admin/StudyFeatures.hs +++ b/src/Handler/Admin/StudyFeatures.hs @@ -250,7 +250,7 @@ postAdminFeaturesR = do -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) 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) ) @@ -261,7 +261,7 @@ postAdminFeaturesR = do -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) 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) ) @@ -283,7 +283,7 @@ postAdminFeaturesR = do -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) 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 (intField & isoField (from _StudyTermsId)) (const "") @@ -302,7 +302,7 @@ postAdminFeaturesR = do -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) 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) ) @@ -313,7 +313,7 @@ postAdminFeaturesR = do -> DBRow r -> DBCell (MForm (HandlerFor UniWorX)) (FormResult (DBFormResult i a (DBRow r))) 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) ) diff --git a/src/Handler/Admin/Test.hs b/src/Handler/Admin/Test.hs index b08f07dff..d2eedd9b6 100644 --- a/src/Handler/Admin/Test.hs +++ b/src/Handler/Admin/Test.hs @@ -7,16 +7,12 @@ import Import import Handler.Utils import Jobs -import Control.Monad.Trans.Writer (mapWriterT) - import Data.Char (isDigit) import qualified Data.Text as Text import qualified Data.Set as Set import qualified Data.Map as Map -import Database.Persist.Sql (fromSqlKey) - -- BEGIN - Buttons needed only here data ButtonCreate = CreateMath | CreateInf -- Dummy for Example @@ -158,7 +154,7 @@ postAdminTestR = do mkAddForm 0 0 nudge submitBtn = Just $ \csrf -> do (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 - 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) mkAddForm _pos _dim _ _ = error "Dimension and Position is always 0 for our 1-dimensional form" diff --git a/src/Handler/Corrections.hs b/src/Handler/Corrections.hs index 9fb3215e8..40abe8d14 100644 --- a/src/Handler/Corrections.hs +++ b/src/Handler/Corrections.hs @@ -11,18 +11,13 @@ import Handler.Utils.SheetType import Handler.Utils.Delete -- import Handler.Utils.Zip -import Data.List as List (nub, foldl, foldr) -import Data.Set (Set) +import Data.List as List (foldl, foldr) 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.Text as Text import qualified Data.CaseInsensitive as CI -import Data.CaseInsensitive (CI) - -import Data.Semigroup (Sum(..)) -import Data.Monoid (All(..)) -- import Data.Time -- import Data.Function ((&)) @@ -49,14 +44,8 @@ import Database.Persist.Sql (updateWhereCount) 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 Data.Foldable (foldrM) - import qualified Data.Conduit.List as C diff --git a/src/Handler/Course/Application/Files.hs b/src/Handler/Course/Application/Files.hs index b6d3b77a5..124ec688f 100644 --- a/src/Handler/Course/Application/Files.hs +++ b/src/Handler/Course/Application/Files.hs @@ -8,8 +8,6 @@ module Handler.Course.Application.Files import Import import Handler.Utils -import System.FilePath (addExtension, ()) - import qualified Data.Conduit.List as C import qualified Database.Esqueleto as E diff --git a/src/Handler/Course/Application/List.hs b/src/Handler/Course/Application/List.hs index b4e5b7f51..a59370ac0 100644 --- a/src/Handler/Course/Application/List.hs +++ b/src/Handler/Course/Application/List.hs @@ -18,7 +18,6 @@ import qualified Data.Csv as Csv import qualified Data.Text as Text import qualified Data.Text.Lens as Text -import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI import qualified Data.Map as Map diff --git a/src/Handler/Course/Edit.hs b/src/Handler/Course/Edit.hs index 9c4805798..8707c568b 100644 --- a/src/Handler/Course/Edit.hs +++ b/src/Handler/Course/Edit.hs @@ -10,14 +10,12 @@ import Handler.Utils import Handler.Utils.Invitations import qualified Data.CaseInsensitive as CI -import Data.Function ((&)) import Data.Maybe (fromJust) import qualified Data.Set as Set import Data.Map ((!)) import qualified Data.Map as Map -import Control.Monad.Trans.Writer (execWriterT) import qualified Control.Monad.State.Class as State import qualified Database.Esqueleto as E diff --git a/src/Handler/Course/LecturerInvite.hs b/src/Handler/Course/LecturerInvite.hs index 9d52eeede..0e410a597 100644 --- a/src/Handler/Course/LecturerInvite.hs +++ b/src/Handler/Course/LecturerInvite.hs @@ -12,7 +12,6 @@ import Utils.Form import Handler.Utils.Invitations import qualified Data.CaseInsensitive as CI -import Data.Function ((&)) import Data.Aeson hiding (Result(..)) @@ -74,6 +73,7 @@ lecturerInvitationConfig = InvitationConfig{..} Just lType -> aforced (selectField optionsFinite) lFs lType where toJunction jLecturerType = (JunctionLecturer{..}, ()) + lFs :: FieldSettings UniWorX lFs = fslI MsgLecturerType & setTooltip MsgCourseLecturerRightsIdentical invitationInsertHook _ _ _ _ _ = id invitationSuccessMsg (Entity _ Course{..}) (Entity _ Lecturer{..}) = do diff --git a/src/Handler/Course/List.hs b/src/Handler/Course/List.hs index 10192bdd5..cc499243b 100644 --- a/src/Handler/Course/List.hs +++ b/src/Handler/Course/List.hs @@ -14,8 +14,6 @@ import Utils.Form -- import Utils.DB import Handler.Utils hiding (colSchoolShort) -import Data.Function ((&)) - import qualified Data.Set as Set import qualified Data.Map as Map diff --git a/src/Handler/Course/News/Show.hs b/src/Handler/Course/News/Show.hs index 9fb4f81b1..5a9298468 100644 --- a/src/Handler/Course/News/Show.hs +++ b/src/Handler/Course/News/Show.hs @@ -5,6 +5,8 @@ module Handler.Course.News.Show import Import import Handler.Utils +{-# ANN module ("HLint: ignore Too strict maybe"::String) #-} + getCNShowR :: TermId -> SchoolId -> CourseShorthand -> CryptoUUIDCourseNews -> Handler Html getCNShowR tid ssh csh cID = do diff --git a/src/Handler/Course/ParticipantInvite.hs b/src/Handler/Course/ParticipantInvite.hs index 99558d12f..cfdba213a 100644 --- a/src/Handler/Course/ParticipantInvite.hs +++ b/src/Handler/Course/ParticipantInvite.hs @@ -16,7 +16,6 @@ import Handler.Utils import Handler.Utils.Invitations import qualified Data.CaseInsensitive as CI -import Data.Function ((&)) import qualified Data.Set as Set @@ -26,7 +25,6 @@ import Data.Aeson hiding (Result(..)) import Text.Hamlet (ihamlet) -import Control.Monad.Trans.Writer (WriterT, execWriterT) import Control.Monad.Except (MonadError(..)) import Generics.Deriving.Monoid (memptydefault, mappenddefault) diff --git a/src/Handler/Course/Register.hs b/src/Handler/Course/Register.hs index 2657455e3..fe3eea1a9 100644 --- a/src/Handler/Course/Register.hs +++ b/src/Handler/Course/Register.hs @@ -10,8 +10,6 @@ import Import import Handler.Utils -import Data.Function ((&)) - import qualified Data.Text as Text import qualified Data.Conduit.List as C diff --git a/src/Handler/Course/Show.hs b/src/Handler/Course/Show.hs index 278df79e8..e07eec99f 100644 --- a/src/Handler/Course/Show.hs +++ b/src/Handler/Course/Show.hs @@ -18,8 +18,6 @@ import qualified Database.Esqueleto as E import Handler.Course.Register -import System.FilePath (addExtension, pathSeparator) - import qualified Data.Conduit.List as C diff --git a/src/Handler/Course/User.hs b/src/Handler/Course/User.hs index 9b9806169..aef35f333 100644 --- a/src/Handler/Course/User.hs +++ b/src/Handler/Course/User.hs @@ -8,8 +8,6 @@ import Utils.Form import Handler.Utils import Database.Esqueleto.Utils.TH -import Data.Function ((&)) - import qualified Database.Esqueleto as E import Text.Blaze.Html.Renderer.Text (renderHtml) diff --git a/src/Handler/Course/Users.hs b/src/Handler/Course/Users.hs index 3ba3d9801..a3a0ee89b 100644 --- a/src/Handler/Course/Users.hs +++ b/src/Handler/Course/Users.hs @@ -16,8 +16,6 @@ import Database.Esqueleto.Utils.TH import Handler.Course.Register (deregisterParticipant) -import Data.Function ((&)) - import qualified Data.Set as Set import qualified Data.Map as Map import qualified Data.Text as Text diff --git a/src/Handler/CryptoIDDispatch.hs b/src/Handler/CryptoIDDispatch.hs index 9270fffe2..66c152c9f 100644 --- a/src/Handler/CryptoIDDispatch.hs +++ b/src/Handler/CryptoIDDispatch.hs @@ -7,11 +7,10 @@ import Import 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 Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI diff --git a/src/Handler/Exam/AddUser.hs b/src/Handler/Exam/AddUser.hs index 9ebbc150a..feee5ddc1 100644 --- a/src/Handler/Exam/AddUser.hs +++ b/src/Handler/Exam/AddUser.hs @@ -13,7 +13,6 @@ import qualified Data.Set as Set import Data.Semigroup (Option(..)) -import Control.Monad.Trans.Writer (WriterT, execWriterT) import Control.Monad.Error.Class (MonadError(..)) import Jobs.Queue diff --git a/src/Handler/Exam/New.hs b/src/Handler/Exam/New.hs index 3614dd0e0..ee30db715 100644 --- a/src/Handler/Exam/New.hs +++ b/src/Handler/Exam/New.hs @@ -71,8 +71,8 @@ postCExamNewR tid ssh csh = do let (invites, adds) = partitionEithers $ Set.toList efCorrectors insertMany_ [ ExamCorrector{..} - | examCorrectorUser <- adds - , let examCorrectorExam = examid + | let examCorrectorExam = examid + , examCorrectorUser <- adds ] sinkInvitationsF examCorrectorInvitationConfig $ map (, examid, (InvDBDataExamCorrector, InvTokenDataExamCorrector)) invites return insertRes diff --git a/src/Handler/Health.hs b/src/Handler/Health.hs index 7cb8aa83b..72a04eee4 100644 --- a/src/Handler/Health.hs +++ b/src/Handler/Health.hs @@ -7,8 +7,6 @@ import qualified Data.Text.Lazy.Builder as Builder import qualified Data.UUID as UUID -import Data.Semigroup (Min(..), Max(..)) - import qualified Data.Set as Set import Control.Concurrent.STM.Delay diff --git a/src/Handler/Material.hs b/src/Handler/Material.hs index 91a2f9939..bf387f85c 100644 --- a/src/Handler/Material.hs +++ b/src/Handler/Material.hs @@ -2,8 +2,6 @@ module Handler.Material where import Import -import Data.Monoid (Any(..)) -import Data.Set (Set) import qualified Data.Set as Set -- import Data.Map (Map) import qualified Data.Map as Map @@ -18,10 +16,6 @@ import Utils.Form import Handler.Utils import Handler.Utils.Delete -import Control.Monad.Writer (MonadWriter(..), execWriterT) - -import System.FilePath (addExtension) - data MaterialForm = MaterialForm { mfName :: MaterialName diff --git a/src/Handler/Participants.hs b/src/Handler/Participants.hs index 146564ce1..d710903b7 100644 --- a/src/Handler/Participants.hs +++ b/src/Handler/Participants.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -fno-warn-redundant-constraints #-} +{-# OPTIONS_GHC -fno-warn-redundant-constraints -fno-warn-incomplete-uni-patterns #-} module Handler.Participants ( getParticipantsListR , getParticipantsR diff --git a/src/Handler/Profile.hs b/src/Handler/Profile.hs index b34ce9cb2..b2988b775 100644 --- a/src/Handler/Profile.hs +++ b/src/Handler/Profile.hs @@ -16,7 +16,6 @@ import Handler.Utils.Tokens -- import Colonnade hiding (fromMaybe, singleton) -- import Yesod.Colonnade -import Data.Monoid (Any(..)) import Data.Map ((!)) import qualified Data.Map as Map import qualified Data.Set as Set diff --git a/src/Handler/Sheet.hs b/src/Handler/Sheet.hs index c54f701ef..dcc7329fd 100644 --- a/src/Handler/Sheet.hs +++ b/src/Handler/Sheet.hs @@ -30,31 +30,18 @@ import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils 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 Data.Set (Set) import qualified Data.Set as Set 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 Data.Aeson hiding (Result(..)) import Text.Hamlet (ihamlet) -import System.FilePath (addExtension) - import Data.Time.Clock.System (systemEpochDay) diff --git a/src/Handler/Submission.hs b/src/Handler/Submission.hs index 2551f6164..a89be407d 100644 --- a/src/Handler/Submission.hs +++ b/src/Handler/Submission.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} +{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-uni-patterns #-} module Handler.Submission where @@ -17,7 +17,6 @@ import Handler.Utils.Invitations -- import Control.Monad.State.Class -- import Control.Monad.Trans.State.Strict (StateT) -import Data.Monoid (Any(..)) import Data.Maybe (fromJust) -- import qualified Data.Maybe import qualified Data.Text.Encoding as Text @@ -30,7 +29,7 @@ import qualified Data.Conduit.List as Conduit -- import Data.Set (Set) import qualified Data.Set as Set -import Data.Map (Map, (!), (!?)) +import Data.Map ((!), (!?)) import qualified Data.Map as Map -- import Data.Bifunctor @@ -42,8 +41,6 @@ import Text.Hamlet (ihamlet) -- import qualified Yesod.Colonnade as Yesod -- import qualified Text.Blaze.Html5.Attributes as HA -import System.FilePath (addExtension) - -- DEPRECATED: We always show all edits! -- numberOfSubmissionEditDates :: Int64 -- numberOfSubmissionEditDates = 3 -- for debugging only, should be 1 in production. diff --git a/src/Handler/Tutorial/Users.hs b/src/Handler/Tutorial/Users.hs index 532c38fd6..90a0cb1d2 100644 --- a/src/Handler/Tutorial/Users.hs +++ b/src/Handler/Tutorial/Users.hs @@ -11,7 +11,6 @@ import Handler.Utils.Tutorial import Database.Persist.Sql (deleteWhereCount) import qualified Data.CaseInsensitive as CI -import Data.Function ((&)) import qualified Data.Set as Set import qualified Data.Map as Map diff --git a/src/Handler/Utils.hs b/src/Handler/Utils.hs index 07ba75a72..8ba6f99ce 100644 --- a/src/Handler/Utils.hs +++ b/src/Handler/Utils.hs @@ -25,8 +25,6 @@ import Handler.Utils.Widgets as Handler.Utils import Handler.Utils.Database as Handler.Utils import Handler.Utils.Occurrences as Handler.Utils -import System.FilePath.Posix (takeFileName) - import Control.Monad.Logger diff --git a/src/Handler/Utils/Allocation.hs b/src/Handler/Utils/Allocation.hs index 92ced534b..39246dafe 100644 --- a/src/Handler/Utils/Allocation.hs +++ b/src/Handler/Utils/Allocation.hs @@ -27,7 +27,6 @@ import System.Random (mkStdGen) import Utils.Allocation import qualified Data.Conduit.List as C -import Data.Conduit.Lift (evalStateC) 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] [] void . insertUnique $ CourseParticipant cid uid now mField (Just allocId) -ppMatchingLog :: ( MonoFoldable mono +ppMatchingLog :: forall mono. + ( MonoFoldable mono , Element mono ~ MatchingLog UserId CourseId Natural ) => mono -> Text ppMatchingLog = unlines . map (tshow . pretty) . otoList where + pretty :: MatchingLog UserId CourseId Natural -> MatchingLog Int64 Int64 Natural pretty = over (param @1) fromSqlKey . over (param @2) fromSqlKey diff --git a/src/Handler/Utils/Communication.hs b/src/Handler/Utils/Communication.hs index e648530ad..197f795d5 100644 --- a/src/Handler/Utils/Communication.hs +++ b/src/Handler/Utils/Communication.hs @@ -11,7 +11,6 @@ import Import import Handler.Utils import Jobs.Queue -import Control.Monad.Trans.Reader (mapReaderT) import qualified Database.Esqueleto as E import qualified Data.CaseInsensitive as CI diff --git a/src/Handler/Utils/Csv.hs b/src/Handler/Utils/Csv.hs index 13ea6546c..81705aa53 100644 --- a/src/Handler/Utils/Csv.hs +++ b/src/Handler/Utils/Csv.hs @@ -20,7 +20,6 @@ import Import hiding (Header, mapM_) import Data.Csv import Data.Csv.Conduit -import Data.Function ((&)) import Control.Monad (mapM_) -- 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}|] fromCsv' decodeOptions + testBufferSize :: Num a => a testBufferSize = 4096 accumTestBuffer acc | LBS.length acc >= testBufferSize = return acc diff --git a/src/Handler/Utils/DateTime.hs b/src/Handler/Utils/DateTime.hs index 6ff98943e..64afdc7ef 100644 --- a/src/Handler/Utils/DateTime.hs +++ b/src/Handler/Utils/DateTime.hs @@ -24,7 +24,6 @@ import Data.Time hiding (formatTime, localTimeToUTC, utcToLocalTime, utcToZonedT -- import Data.Time.Clock (addUTCTime,nominalDay) import qualified Data.Time.Format as Time -import Data.Set (Set) import qualified Data.Set as Set import Data.Time.Clock.System (systemEpochDay) diff --git a/src/Handler/Utils/Delete.hs b/src/Handler/Utils/Delete.hs index 6f758786f..a97c830ab 100644 --- a/src/Handler/Utils/Delete.hs +++ b/src/Handler/Utils/Delete.hs @@ -27,10 +27,11 @@ import Data.Char (isAlphaNum) import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect) -import qualified Database.Esqueleto.Internal.Language as E (From) 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 { drRecords :: Set (Key record) -- ^ Records to be deleted diff --git a/src/Handler/Utils/Exam.hs b/src/Handler/Utils/Exam.hs index 129d11b7e..cac40a135 100644 --- a/src/Handler/Utils/Exam.hs +++ b/src/Handler/Utils/Exam.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -fno-warn-deprecations #-} +{-# OPTIONS_GHC -fno-warn-deprecations -fno-warn-incomplete-uni-patterns #-} module Handler.Utils.Exam ( fetchExamAux @@ -24,7 +24,6 @@ import qualified Data.Conduit.List as C import qualified Data.Map as Map import qualified Data.Set as Set -import Data.Fixed (Fixed(..)) import qualified Data.Foldable as F import qualified Data.CaseInsensitive as CI diff --git a/src/Handler/Utils/Form.hs b/src/Handler/Utils/Form.hs index dd9cadba6..f3b38f2d3 100644 --- a/src/Handler/Utils/Form.hs +++ b/src/Handler/Utils/Form.hs @@ -14,6 +14,8 @@ import Handler.Utils.Pandoc import Handler.Utils.DateTime +import Handler.Utils.Widgets + import Import import Data.Char (chr, ord) 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.Utils as E -import Data.Set (Set) import qualified Data.Set as Set -import Data.Map (Map, (!)) +import Data.Map ((!)) import qualified Data.Map as Map -import Control.Monad.Trans.Writer (execWriterT, WriterT) import Control.Monad.Trans.Except (throwE, runExceptT) import Control.Monad.Writer.Class import Control.Monad.Error.Class (MonadError(..)) -import Data.Either (partitionEithers) - import Data.Aeson (eitherDecodeStrict') import Data.Aeson.Text (encodeToLazyText) @@ -51,7 +49,6 @@ import qualified Text.Email.Validate as Email import Yesod.Core.Types (FileInfo(..)) -import System.FilePath (isExtensionOf) import Data.Text.Lens (unpacked) import Data.Char (isDigit) @@ -548,6 +545,7 @@ uploadModeForm prev = multiActionA actions (fslI MsgSheetUploadMode) (classifyUp return (addRes', formWidget') miCell _ initFile _ nudge csrf = sFileForm nudge (Just initFile) csrf + miDelete :: MassInputDelete ListLength miDelete = miDeleteList miAllowAdd _ _ _ = True miAddEmpty _ _ _ = Set.empty @@ -815,7 +813,8 @@ multiFileField permittedFiles' = Field{..} | Right sentVals' <- sentVals = fuiId' `elem` sentVals' | otherwise = True return FileUploadInfo{..} - autoUnzipInfo = [whamlet| _{MsgAutoUnzipInfo} |] + autoUnzipInfo :: Widget + autoUnzipInfo = i18n MsgAutoUnzipInfo fileInfos' <- mapM toFUI <=< handlerToWidget . runDB . E.select . E.from $ \file -> do E.where_ $ file E.^. FileId `E.in_` E.valList (setToList pVals) E.orderBy [E.asc $ file E.^. FileTitle] diff --git a/src/Handler/Utils/Form/MassInput.hs b/src/Handler/Utils/Form/MassInput.hs index a0ba3dfb4..ef53aeb4d 100644 --- a/src/Handler/Utils/Form/MassInput.hs +++ b/src/Handler/Utils/Form/MassInput.hs @@ -1,8 +1,8 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} -- tupleBoxCoord +{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-incomplete-record-updates #-} -- tupleBoxCoord {-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-} module Handler.Utils.Form.MassInput - ( MassInput(..), MassInputLayout + ( MassInput(..), MassInputLayout, MassInputDelete , defaultMiLayout, listMiLayout , massInput , module Handler.Utils.Form.MassInput.Liveliness @@ -34,6 +34,8 @@ import Control.Monad.Reader.Class (MonadReader(local)) import Text.Hamlet (hamletFile) +import Algebra.Lattice.Ordered (Ordered(..)) + $(mapM tupleBoxCoord [2..4]) @@ -44,11 +46,8 @@ newtype ListLength = ListLength { unListLength :: Natural } makeWrapped ''ListLength -instance JoinSemiLattice ListLength where - (\/) = max -instance MeetSemiLattice ListLength where - (/\) = min -instance Lattice ListLength +deriving via Ordered ListLength instance Lattice ListLength + instance BoundedJoinSemiLattice ListLength where bottom = 0 @@ -85,16 +84,13 @@ newtype EnumLiveliness enum = EnumLiveliness { unEnumLiveliness :: IntSet } makeWrapped ''EnumLiveliness -instance JoinSemiLattice (EnumLiveliness enum) where +instance Lattice (EnumLiveliness enum) where (EnumLiveliness a) \/ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.union` b -instance MeetSemiLattice (EnumLiveliness enum) where (EnumLiveliness a) /\ (EnumLiveliness b) = EnumLiveliness $ a `IntSet.intersection` b -instance Lattice (EnumLiveliness enum) instance BoundedJoinSemiLattice (EnumLiveliness enum) where bottom = EnumLiveliness IntSet.empty instance (Enum enum, Bounded enum) => BoundedMeetSemiLattice (EnumLiveliness enum) where top = EnumLiveliness . IntSet.fromList $ map (fromEnum :: enum -> Int) [minBound..maxBound] -instance (Enum enum, Bounded enum) => BoundedLattice (EnumLiveliness 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 liveCoords = iso fromSet toSet where + toSet :: EnumLiveliness enum -> Set (EnumPosition enum) toSet = Set.fromList . map toEnum . IntSet.toList . unEnumLiveliness + fromSet :: Set (EnumPosition enum) -> EnumLiveliness enum fromSet = EnumLiveliness . IntSet.fromList . map fromEnum . Set.toList @@ -120,12 +118,9 @@ newtype MapLiveliness l1 l2 = MapLiveliness { unMapLiveliness :: Map (BoxCoord l 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), 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), BoundedLattice l2) => BoundedLattice (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), 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) +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 -- 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 @@ -289,6 +286,7 @@ massInput MassInput{ miIdent = toPathPiece -> miIdent, ..} FieldSettings{..} fvR let shapeName :: MassInputFieldName (BoxCoord liveliness) shapeName = MassInputShape{..} + shapeField :: Field handler (Map (BoxCoord liveliness) cellData) shapeField = secretJsonField sentShape <- runMaybeT $ do 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)) miCell _pos dat _mPrev _nudge csrf' = return (FormSuccess (), toWidget csrf' <> miCell' dat) + miDelete :: MassInputDelete ListLength miDelete = miDeleteList miAllowAdd _ _ _ = True @@ -613,6 +612,7 @@ massInputAccumEdit miAdd' miCell' miButtonAction miLayout miIdent fSettings fReq -> (Markup -> MForm handler (FormResult cellData, Widget)) miCell _pos dat _mPrev nudge = miCell' nudge dat + miDelete :: MassInputDelete ListLength miDelete = miDeleteList miAllowAdd _ _ _ = True diff --git a/src/Handler/Utils/Form/MassInput/Liveliness.hs b/src/Handler/Utils/Form/MassInput/Liveliness.hs index 9891350d8..14709ec9b 100644 --- a/src/Handler/Utils/Form/MassInput/Liveliness.hs +++ b/src/Handler/Utils/Form/MassInput/Liveliness.hs @@ -26,11 +26,12 @@ class (ToJSON x, FromJSON x, ToJSONKey x, FromJSONKey x, PathPiece x, Eq x, Ord boxDimensions :: [BoxDimension x] boxOrigin :: x -boxDimension :: IsBoxCoord x => Natural -> BoxDimension x +boxDimension :: forall x. IsBoxCoord x => Natural -> BoxDimension x boxDimension n | n < genericLength dims = genericIndex dims n | otherwise = error "boxDimension: insufficient dimensions" where + dims :: [BoxDimension x] dims = boxDimensions -- zeroDimension :: IsBoxCoord x => Natural -> x -> x diff --git a/src/Handler/Utils/Form/MassInput/TH.hs b/src/Handler/Utils/Form/MassInput/TH.hs index 01d0e8e56..dac5203b0 100644 --- a/src/Handler/Utils/Form/MassInput/TH.hs +++ b/src/Handler/Utils/Form/MassInput/TH.hs @@ -11,8 +11,6 @@ import Language.Haskell.TH import Control.Lens -import Data.List ((!!)) - import Control.Monad (replicateM) diff --git a/src/Handler/Utils/I18n.hs b/src/Handler/Utils/I18n.hs index 03ae640e6..0394aa578 100644 --- a/src/Handler/Utils/I18n.hs +++ b/src/Handler/Utils/I18n.hs @@ -20,7 +20,6 @@ import qualified Data.Map as Map import qualified Data.Text as Text import System.Directory (listDirectory) -import System.FilePath.Posix (takeBaseName) -- | Add language dependent template files diff --git a/src/Handler/Utils/Invitations.hs b/src/Handler/Utils/Invitations.hs index 983ea7b3c..2da19bd90 100644 --- a/src/Handler/Utils/Invitations.hs +++ b/src/Handler/Utils/Invitations.hs @@ -25,9 +25,6 @@ import Handler.Utils.Tokens 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.List.NonEmpty as NonEmpty import qualified Data.HashSet as HashSet @@ -36,7 +33,6 @@ import qualified Data.Set as Set import Data.Aeson (fromJSON) import qualified Data.Aeson as JSON -import Data.Proxy (Proxy(..)) import Data.Typeable import Database.Persist.Sql (SqlBackendCanWrite) diff --git a/src/Handler/Utils/Mail.hs b/src/Handler/Utils/Mail.hs index d40782758..f564ae3d4 100644 --- a/src/Handler/Utils/Mail.hs +++ b/src/Handler/Utils/Mail.hs @@ -15,10 +15,6 @@ import qualified Data.ByteString.Lazy as LBS 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.Hamlet as Hamlet (Translate) @@ -79,8 +75,8 @@ addFileDB fId = runMaybeT $ do lift . addPart $ do _partType .= decodeUtf8 (mimeLookup fileName) _partEncoding .= Base64 - _partFilename .= Just fileName - _partContent .= LBS.fromStrict fileContent + _partDisposition .= AttachmentDisposition fileName + _partContent .= PartContent (LBS.fromStrict fileContent) setMailObjectIdCrypto fId :: StateT Part (HandlerFor UniWorX) MailObjectId diff --git a/src/Handler/Utils/Rating.hs b/src/Handler/Utils/Rating.hs index 4bea35d2b..d96ae3784 100644 --- a/src/Handler/Utils/Rating.hs +++ b/src/Handler/Utils/Rating.hs @@ -20,11 +20,9 @@ import Text.PrettyPrint.Leijen.Text hiding ((<$>)) import qualified Data.Text 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 Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI 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 (reverse -> ratingLines, reverse -> _headerLines) = break (sep' `Text.isInfixOf`) $ reverse headerLines' ratingLines' = filter (rating `Text.isInfixOf`) ratingLines + commentSep :: Text commentSep = "Beginn der Kommentare" sep' = Text.pack $ replicate 40 '=' + rating :: Text rating = "Bewertung:" comment' <- case commentLines of (_:commentLines') -> return . Text.strip $ Text.unlines commentLines' diff --git a/src/Handler/Utils/SchoolLdap.hs b/src/Handler/Utils/SchoolLdap.hs index b9b825aff..782d533c9 100644 --- a/src/Handler/Utils/SchoolLdap.hs +++ b/src/Handler/Utils/SchoolLdap.hs @@ -7,7 +7,6 @@ import Import.NoFoundation hiding (try, (<|>), choice) import Text.Parsec import Text.Parsec.Text -import Data.CaseInsensitive (CI) import qualified Data.CaseInsensitive as CI import qualified Data.Set as Set diff --git a/src/Handler/Utils/SheetType.hs b/src/Handler/Utils/SheetType.hs index 494729793..5f269fa55 100644 --- a/src/Handler/Utils/SheetType.hs +++ b/src/Handler/Utils/SheetType.hs @@ -4,7 +4,6 @@ module Handler.Utils.SheetType ) where import Import -import Data.Monoid (Sum(..)) addBonusToPoints :: SheetTypeSummary -> SheetTypeSummary addBonusToPoints sts = diff --git a/src/Handler/Utils/Submission.hs b/src/Handler/Utils/Submission.hs index 23d9aed0b..ee7e7fc56 100644 --- a/src/Handler/Utils/Submission.hs +++ b/src/Handler/Utils/Submission.hs @@ -13,24 +13,20 @@ module Handler.Utils.Submission import Import hiding (joinPath) 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.Writer (MonadWriter(..), execWriterT, execWriter) import Control.Monad.RWS.Lazy (MonadRWS, RWST, execRWST) import qualified Control.Monad.Random as Rand import Data.Maybe () -import Data.Set (Set) import qualified Data.Set as Set -import Data.Map (Map, (!), (!?)) +import Data.Map ((!), (!?)) import qualified Data.Map as Map import qualified Data.Text as Text -import Data.Monoid (Monoid, Any(..), Sum(..)) import Generics.Deriving.Monoid (memptydefault, mappenddefault) import Handler.Utils diff --git a/src/Handler/Utils/Submission/TH.hs b/src/Handler/Utils/Submission/TH.hs index 0b24a4da1..14504b6cf 100644 --- a/src/Handler/Utils/Submission/TH.hs +++ b/src/Handler/Utils/Submission/TH.hs @@ -10,7 +10,6 @@ import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..)) import System.FilePath.Glob -import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.IO as Text diff --git a/src/Handler/Utils/Table/Cells.hs b/src/Handler/Utils/Table/Cells.hs index 5a53a8070..eae560b6a 100644 --- a/src/Handler/Utils/Table/Cells.hs +++ b/src/Handler/Utils/Table/Cells.hs @@ -2,12 +2,7 @@ module Handler.Utils.Table.Cells where 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.Trans.Writer (WriterT) import Text.Blaze (ToMarkup(..)) diff --git a/src/Handler/Utils/Table/Pagination.hs b/src/Handler/Utils/Table/Pagination.hs index 53184935c..e3689add8 100644 --- a/src/Handler/Utils/Table/Pagination.hs +++ b/src/Handler/Utils/Table/Pagination.hs @@ -61,21 +61,18 @@ import qualified Yesod.Form.Functions as Yesod import qualified Database.Esqueleto as E import qualified Database.Esqueleto.Utils as E 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 Control.Monad.RWS (RWST(..), execRWS) -import Control.Monad.Writer (WriterT(..)) -import Control.Monad.Reader (ReaderT(..), mapReaderT) -import Control.Monad.State (StateT(..), evalStateT) +import Control.Monad.State (evalStateT) import Control.Monad.Trans.Maybe import Control.Monad.State.Class (modify) import qualified Control.Monad.State.Class as State import Data.Foldable (Foldable(foldMap)) -import Data.Map (Map, (!)) +import Data.Map ((!)) import qualified Data.Map as Map import qualified Data.Set as Set @@ -90,20 +87,14 @@ import Colonnade.Encode hiding (row) import Text.Hamlet (hamletFile) -import Data.Ratio ((%)) - import Data.List (elemIndex) import Data.Maybe (fromJust) -import Data.Aeson (Options(..), SumEncoding(..), defaultOptions) import Data.Aeson.Text -import Data.Aeson.TH (deriveJSON) import qualified Data.Text as Text -import Data.Proxy (Proxy(..)) - import qualified Data.Binary as B import qualified Data.ByteArray as BA (convert) 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 | otherwise = toPathPiece x fromPathPiece txt = do - let sep = "-" + let sep :: Text + sep = "-" (ident, (Text.stripSuffix sep -> Just rest)) <- return $ Text.breakOn sep txt WithIdent <$> pure ident <*> fromPathPiece rest @@ -188,7 +180,8 @@ deriveJSON defaultOptions instance PathPiece SortingSetting where toPathPiece SortingSetting{..} = toPathPiece sortKey <> "-" <> toPathPiece sortDir fromPathPiece str = do - let sep = "-" + let sep :: Text + sep = "-" let (Text.dropEnd (Text.length sep) -> key, dir) = Text.breakOnEnd sep str SortingSetting <$> fromPathPiece key <*> fromPathPiece dir @@ -829,8 +822,9 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db dbsAttrs' | not $ null dbtIdent = ("id", dbtIdent) : dbsAttrs | otherwise = dbsAttrs + multiTextField :: forall m'. Applicative m' => Field m' [Text] multiTextField = Field - { fieldParse = \ts _ -> return . Right $ Just ts + { fieldParse = \ts _ -> pure . Right $ Just ts , fieldView = error "multiTextField: should not be rendered" , fieldEnctype = UrlEncoded } @@ -939,6 +933,7 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db , formSubmit = FormSubmit , formAnchor = Just $ wIdent "csv-import" } + csvImportExplanation :: Widget csvImportExplanation = modal [whamlet|_{MsgCsvImportExplanationLabel}|] $ Right $(i18nWidgetFile "table/csv-import-explanation") csvColExplanations = case dbtCsvEncode of 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 = filter (> 0) $ opts' <> map (`div` 2) opts' + opts' :: [Int64] opts' = [ 10^n | n <- [1..3]] pagesizeField :: PagesizeLimit -> Field Handler PagesizeLimit diff --git a/src/Handler/Utils/Table/Pagination/Types.hs b/src/Handler/Utils/Table/Pagination/Types.hs index 64da8980a..141e0b0b9 100644 --- a/src/Handler/Utils/Table/Pagination/Types.hs +++ b/src/Handler/Utils/Table/Pagination/Types.hs @@ -14,10 +14,6 @@ import Import hiding (singleton) import Colonnade import Colonnade.Encode -import Data.CaseInsensitive (CI) - -import Data.Aeson (FromJSON, ToJSON, FromJSONKey, ToJSONKey) - {-# ANN module ("HLint: ignore Use newtype instead of data" :: String) #-} newtype FilterKey = FilterKey { _unFilterKey :: CI Text } diff --git a/src/Handler/Utils/TermCandidates.hs b/src/Handler/Utils/TermCandidates.hs index 729fd0eaa..7d49f451f 100644 --- a/src/Handler/Utils/TermCandidates.hs +++ b/src/Handler/Utils/TermCandidates.hs @@ -17,10 +17,8 @@ import Import -- import qualified Data.UUID.Cryptographic as UUID -- import Control.Monad.Trans.Writer (mapWriterT) -- import Database.Persist.Sql (fromSqlKey) -import Data.Set (Set) import qualified Data.Set as Set import qualified Data.List as List -import Data.Map (Map) import qualified Data.Map as Map diff --git a/src/Handler/Utils/Tokens.hs b/src/Handler/Utils/Tokens.hs index 54a0b4da5..e7d831cba 100644 --- a/src/Handler/Utils/Tokens.hs +++ b/src/Handler/Utils/Tokens.hs @@ -5,8 +5,6 @@ module Handler.Utils.Tokens import Import -import Control.Monad.Trans.Maybe (runMaybeT) - maybeBearerToken :: (MonadHandler m, HandlerSite m ~ UniWorX, MonadCatch m) => m (Maybe (BearerToken UniWorX)) maybeBearerToken = runMaybeT $ catchIfMaybeT cPred requireBearerToken diff --git a/src/Handler/Utils/Users.hs b/src/Handler/Utils/Users.hs index df7125023..dc23e8739 100644 --- a/src/Handler/Utils/Users.hs +++ b/src/Handler/Utils/Users.hs @@ -9,7 +9,7 @@ module Handler.Utils.Users import Import import Auth.LDAP (campusUserMatr') -import Crypto.Hash (Digest, SHA3_256, hashlazy) +import Crypto.Hash (hashlazy) import Data.ByteArray (constEq) diff --git a/src/Handler/Utils/Widgets.hs b/src/Handler/Utils/Widgets.hs index be3e0424d..b9e5b5f95 100644 --- a/src/Handler/Utils/Widgets.hs +++ b/src/Handler/Utils/Widgets.hs @@ -109,6 +109,7 @@ i18n = toWidget . (SomeMessage :: msg -> SomeMessage (HandlerSite m)) examOccurrenceMappingDescriptionWidget :: ExamOccurrenceRule -> Set ExamOccurrenceMappingDescription -> Widget examOccurrenceMappingDescriptionWidget rule descriptions = $(widgetFile "widgets/exam-occurrence-mapping-description") where + titleCase :: [CI Char] -> String titleCase = over _head Char.toUpper . map CI.foldedCase doPrefix | ExamRoomMatriculation <- rule diff --git a/src/Handler/Utils/Zip.hs b/src/Handler/Utils/Zip.hs index 3948253f9..9ee8fbf96 100644 --- a/src/Handler/Utils/Zip.hs +++ b/src/Handler/Utils/Zip.hs @@ -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 Data.ByteString (ByteString) import qualified Data.ByteString as ByteString import System.FilePath diff --git a/src/Import/NoModel.hs b/src/Import/NoModel.hs index 618a783b6..d01136a6d 100644 --- a/src/Import/NoModel.hs +++ b/src/Import/NoModel.hs @@ -1,6 +1,7 @@ module Import.NoModel ( module Import , MForm + , WeekDay ) where import ClassyPrelude.Yesod as Import @@ -16,7 +17,6 @@ import ClassyPrelude.Yesod as Import , HasHttpManager(..) , embed , try, embed, catches, handle, catch, bracket, bracketOnError, bracket_, catchJust, finally, handleJust, mask, mask_, onException, tryJust, uninterruptibleMask, uninterruptibleMask_ - , fail , htmlField ) @@ -30,7 +30,6 @@ import Mail as Import import Yesod.Auth as Import import Yesod.Core.Types as Import (loggerSet) import Yesod.Default.Config2 as Import -import Yesod.Core.Json as Import (provideJson) import Yesod.Core.Types.Instances as Import import Utils as Import @@ -53,15 +52,13 @@ import UnliftIO.Pool as Import (Pool) import Network.HaskellNet.SMTP as Import (SMTPConnection) 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 Data.Ix as Import (Ix) import Data.Hashable as Import import Data.List.NonEmpty as Import (NonEmpty(..), nonEmpty) 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.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.Trans.Resource as Import (ReleaseKey) import Control.Monad.Trans.Reader as Import - ( reader, Reader, runReader, mapReader, withReader - , ReaderT(..), mapReaderT, withReaderT + ( reader, runReader, mapReader, withReader + , mapReaderT, withReaderT ) import Control.Monad.Trans.State as Import ( state, State, runState, mapState, withState @@ -103,17 +100,15 @@ import Jose.Jwt as Import (Jwt) import Data.Time.Calendar as Import import Data.Time.Clock as Import import Data.Time.LocalTime as Import hiding (utcToLocalTime, utcToZonedTime, localTimeToUTC) -import Time.Types as Import (WeekDay(..)) import Network.Mime 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.Void as Import (Void) -import Algebra.Lattice as Import hiding (meet, join) +import Algebra.Lattice as Import 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.Calendar.Instances as Import () import Data.Time.Format.Instances as Import () -import Time.Types.Instances as Import () import Network.Mail.Mime.Instances as Import () import Yesod.Core.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) type MForm m = RWST (Maybe (Env, FileEnv), HandlerSite m, [Lang]) Enctype Ints m + +type WeekDay = DayOfWeek diff --git a/src/Jobs.hs b/src/Jobs.hs index 423e0c20c..600294731 100644 --- a/src/Jobs.hs +++ b/src/Jobs.hs @@ -7,7 +7,6 @@ module Jobs import Import import Jobs.Types as Types hiding (JobCtl(JobCtlQueue)) -import Jobs.Types (JobCtl(JobCtlQueue)) import Jobs.Queue import Jobs.Crontab @@ -18,17 +17,13 @@ import qualified Data.Text.Lazy as LT import Data.Aeson (fromJSON) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Types as Aeson -import Database.Persist.Sql (fromSqlKey) - -import Data.Semigroup (Max(..)) import Utils.Sql -import Control.Monad.Random (evalRand, mkStdGen, getRandomR, uniformMay) +import Control.Monad.Random (evalRand, mkStdGen, uniformMay) import Cron import qualified Data.HashMap.Strict as HashMap -import Data.HashMap.Strict (HashMap) import qualified Data.Set as Set 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 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 qualified Control.Monad.State.Class as State 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.Random.Lazy (evalRandTIO, mapRandT) import Control.Monad.Logger diff --git a/src/Jobs/Crontab.hs b/src/Jobs/Crontab.hs index 9c5d81203..b631b052e 100644 --- a/src/Jobs/Crontab.hs +++ b/src/Jobs/Crontab.hs @@ -1,3 +1,5 @@ +{-# OPTIONS_GHC -fno-warn-incomplete-record-updates #-} + module Jobs.Crontab ( determineCrontab ) where @@ -9,7 +11,6 @@ import Jobs.Types import qualified Data.Set as Set import qualified Data.Map as Map -import Data.Semigroup (Max(..)) import Data.Time.Zones import Data.Time.Clock.POSIX @@ -17,7 +18,6 @@ import Data.Time.Clock.POSIX import Handler.Utils.DateTime import Handler.Utils.Allocation (allocationDone) -import Control.Monad.Trans.Writer (WriterT, execWriterT) import Control.Monad.Writer.Class (MonadWriter(..)) import qualified Data.Conduit.List as C diff --git a/src/Jobs/Handler/DistributeCorrections.hs b/src/Jobs/Handler/DistributeCorrections.hs index 192c4dea3..af61ddfb7 100644 --- a/src/Jobs/Handler/DistributeCorrections.hs +++ b/src/Jobs/Handler/DistributeCorrections.hs @@ -6,8 +6,6 @@ import Import import Jobs.Queue -import Control.Monad.Trans.Reader (mapReaderT) - import Handler.Utils.Submission import qualified Data.Set as Set diff --git a/src/Jobs/Handler/QueueNotification.hs b/src/Jobs/Handler/QueueNotification.hs index c38575bbc..394516dac 100644 --- a/src/Jobs/Handler/QueueNotification.hs +++ b/src/Jobs/Handler/QueueNotification.hs @@ -4,8 +4,6 @@ module Jobs.Handler.QueueNotification import Import -import Data.List (nub) - import Jobs.Types import qualified Database.Esqueleto as E diff --git a/src/Jobs/Handler/SendCourseCommunication.hs b/src/Jobs/Handler/SendCourseCommunication.hs index 1cb5ea554..2030d0c29 100644 --- a/src/Jobs/Handler/SendCourseCommunication.hs +++ b/src/Jobs/Handler/SendCourseCommunication.hs @@ -12,6 +12,9 @@ import qualified Data.CaseInsensitive as CI import Handler.Utils.Csv (partIsAttachmentCsv) +{-# ANN module ("HLint: ignore Too strict maybe"::String) #-} + + dispatchJobSendCourseCommunication :: Either UserEmail UserId -> Set Address -> CourseId diff --git a/src/Jobs/Handler/SynchroniseLdap.hs b/src/Jobs/Handler/SynchroniseLdap.hs index 3769f76a4..1c82569ed 100644 --- a/src/Jobs/Handler/SynchroniseLdap.hs +++ b/src/Jobs/Handler/SynchroniseLdap.hs @@ -51,6 +51,7 @@ dispatchJobSynchroniseLdapUser jUser = do Nothing -> throwM SynchroniseLdapNoLdap where + handleExc :: MaybeT DB a -> MaybeT DB a handleExc = catchMPlus (Proxy @CampusUserException) . catchMPlus (Proxy @CampusUserConversionException) diff --git a/src/Jobs/HealthReport.hs b/src/Jobs/HealthReport.hs index 60eb2aa7f..97fc6e229 100644 --- a/src/Jobs/HealthReport.hs +++ b/src/Jobs/HealthReport.hs @@ -10,7 +10,6 @@ import Data.List (genericLength) import qualified Data.Map.Strict as Map import qualified Data.Aeson as Aeson -import Data.Proxy (Proxy(..)) import qualified Data.ByteArray as ByteArray @@ -124,7 +123,9 @@ dispatchHealthCheckWidgetMemcached :: Handler HealthReport dispatchHealthCheckWidgetMemcached = fmap HealthWidgetMemcached . yesodTimeout (^. _appHealthCheckActiveWidgetMemcachedTimeout) (Just False) $ do memcachedConn <- getsYesod appWidgetMemcached for memcachedConn $ \_memcachedConn' -> do - let ext = "bin" + let ext :: Text + ext = "bin" + mimeType :: Text mimeType = "application/octet-stream" content <- pack . take 256 <$> liftIO getRandoms staticLink <- addStaticContent ext mimeType content diff --git a/src/Jobs/Queue.hs b/src/Jobs/Queue.hs index c85ba0d9d..38158efe0 100644 --- a/src/Jobs/Queue.hs +++ b/src/Jobs/Queue.hs @@ -14,9 +14,7 @@ import Import hiding ((<>)) import Utils.Sql import Jobs.Types -import Control.Monad.Trans.Writer (WriterT, runWriterT) import Control.Monad.Writer.Class (MonadWriter(..)) -import Control.Monad.Trans.Reader (ReaderT, mapReaderT) import qualified Data.Map.Strict as Map import qualified Data.Set as Set diff --git a/src/Jobs/Types.hs b/src/Jobs/Types.hs index a22298065..54bb430cc 100644 --- a/src/Jobs/Types.hs +++ b/src/Jobs/Types.hs @@ -1,3 +1,4 @@ +{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Jobs.Types @@ -19,13 +20,9 @@ module Jobs.Types import Import.NoFoundation hiding (Unique, state) 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 Data.List.NonEmpty (NonEmpty) - import Data.Unique import qualified Data.Map.Strict as Map diff --git a/src/Ldap/Client/Pool.hs b/src/Ldap/Client/Pool.hs index 4668f4b23..9a33e9e0f 100644 --- a/src/Ldap/Client/Pool.hs +++ b/src/Ldap/Client/Pool.hs @@ -35,8 +35,6 @@ data LdapExecutor = LdapExecutor , ldapAsync :: Async () } -instance Exception LdapError - data LdapPoolError = LdapPoolTimeout | LdapError LdapError deriving (Eq, Show, Generic, Typeable) @@ -93,7 +91,10 @@ createLdapPool host port stripes timeoutConn (round . (* 1e6) -> timeoutAct) lim $logErrorS "LdapExecutor" "Could not return result" either throwM (const $ return ()) res `catches` - [ Handler (\(Ldap.ResponseError _) -> return ()) + [ Handler $ \case + Ldap.ResponseError _ -> return () + Ldap.DisconnectError _ -> return () + other -> throwM other ] go Nothing ldap diff --git a/src/Mail.hs b/src/Mail.hs index 81457b574..c472a75f2 100644 --- a/src/Mail.hs +++ b/src/Mail.hs @@ -33,7 +33,7 @@ module Mail , setMailSmtpData , _addressName, _addressEmail , _mailFrom, _mailTo, _mailCc, _mailBcc, _mailHeaders, _mailHeader, _mailParts - , _partType, _partEncoding, _partFilename, _partHeaders, _partContent + , _partType, _partEncoding, _partDisposition, _partFilename, _partHeaders, _partContent ) where 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.State (StateT(..), execStateT, mapStateT) 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.Base import Control.Monad.Catch -import GHC.Generics (Generic) import Generics.Deriving.Monoid (memptydefault, mappenddefault) -import Data.Sequence (Seq) import qualified Data.Sequence as Seq -import Data.Set (Set) import qualified Data.Set as Set import qualified Data.Text as Text @@ -88,7 +85,7 @@ import qualified Data.Binary as Binary 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.Format (rfc822DateFormat) @@ -100,7 +97,6 @@ import qualified Text.Shakespeare as Shakespeare (RenderUrl) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Encode.Pretty as Aeson -import Data.Aeson (Options(..)) import Data.Aeson.TH import Utils.PathPiece (splitCamel) import Utils.DateTime @@ -125,6 +121,14 @@ makeLenses_ ''Address makeLenses_ ''Mail 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 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 _partType .= decodeUtf8 typePlain _partEncoding .= QuotedPrintableText - _partContent .= encodeUtf8 text + _partContent .= PartContent (encodeUtf8 text) instance YesodMail site => ToMailPart site Text where toMailPart = toMailPart . LT.fromStrict @@ -340,7 +344,7 @@ instance YesodMail site => ToMailPart site Html where toMailPart html = do _partType .= decodeUtf8 typeHtml _partEncoding .= QuotedPrintableText - _partContent .= renderMarkup html + _partContent .= PartContent (renderMarkup html) instance (ToMailPart site a, RenderMessage site msg) => ToMailPart site (Hamlet.Translate msg -> a) where 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 _partType .= decodeUtf8 typeJson _partEncoding .= QuotedPrintableText - _partContent .= Aeson.encodePretty val + _partContent .= PartContent (Aeson.encodePretty val) addAlternatives :: (MonadMail m) @@ -400,9 +404,9 @@ initialPart :: Part initialPart = Part { partType = decodeUtf8 defaultMimeType , partEncoding = Base64 - , partFilename = Nothing + , partDisposition = DefaultDisposition , partHeaders = [] - , partContent = mempty + , partContent = PartContent mempty } modifyPart :: (MonadMail m, HandlerSite m ~ site, YesodMail site) @@ -413,7 +417,7 @@ modifyPart = toMailPart partIsAttachment :: (Textual t, MonadMail m, HandlerSite m ~ site, YesodMail site) => t -> StateT Part m () -partIsAttachment (repack -> fName) = modifyPart $ _partFilename .= Just fName +partIsAttachment (repack -> fName) = modifyPart $ _partDisposition .= AttachmentDisposition fName class MonadHandler m => MonadHeader m where diff --git a/src/Model.hs b/src/Model.hs index 3821126b6..48c5aa8db 100644 --- a/src/Model.hs +++ b/src/Model.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-} +{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances, DeriveAnyClass #-} module Model ( module Model @@ -14,13 +14,9 @@ import Database.Persist.TH.Directory import Model.Types hiding (_maxPoints, _passingPoints) import Cron.Types -import Data.Aeson (Value) - -import Data.CaseInsensitive (CI, original) +import Data.CaseInsensitive (original) import Data.CaseInsensitive.Instances () -import Utils.Message (MessageStatus) - import Settings.Cluster (ClusterSettingsKey) import Text.Blaze (ToMarkup(..)) diff --git a/src/Model/Migration.hs b/src/Model/Migration.hs index eda1a905a..4fd3bbd83 100644 --- a/src/Model/Migration.hs +++ b/src/Model/Migration.hs @@ -1,21 +1,17 @@ -{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableInstances, GeneralizedNewtypeDeriving #-} module Model.Migration ( migrateAll , requiresMigration ) where -import Utils (lastMaybe) - import Import.NoModel import Model import Audit.Types import Model.Migration.Version import qualified Model.Migration.Types as Legacy -import Data.Map (Map) import qualified Data.Map as Map -import Data.Set () import qualified Data.Set as Set import qualified Data.Text as Text @@ -26,25 +22,15 @@ import Database.Persist.Sql import Database.Persist.Sql.Raw.QQ import Database.Persist.Postgresql -import Control.Monad.Trans.Maybe (MaybeT(..)) - 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 Utils (exceptT, allM, whenIsJust, guardM) import Utils.Lens (_NoUpload) -import Utils.DB (getKeyBy) import qualified Net.IP as IP import qualified Net.IPv4 as IPv4 import qualified Net.IPv6 as IPv6 -import Data.Aeson (toJSON) - import qualified Data.Char as Char import qualified Data.CaseInsensitive as CI diff --git a/src/Model/Migration/Types.hs b/src/Model/Migration/Types.hs index 58e6b7b25..69226bf76 100644 --- a/src/Model/Migration/Types.hs +++ b/src/Model/Migration/Types.hs @@ -2,7 +2,7 @@ module Model.Migration.Types where import ClassyPrelude.Yesod import Data.Aeson -import Data.Aeson.TH (deriveJSON, defaultOptions) +import Data.Aeson.TH (deriveJSON) import Utils.PathPiece diff --git a/src/Model/Rating.hs b/src/Model/Rating.hs index 0e2fcf8cb..62f593d49 100644 --- a/src/Model/Rating.hs +++ b/src/Model/Rating.hs @@ -4,8 +4,6 @@ import ClassyPrelude.Yesod import Model -- import Data.Text (Text) import Data.Text.Encoding.Error (UnicodeException(..)) -import GHC.Generics (Generic) -import Data.Typeable (Typeable) data Rating = Rating diff --git a/src/Model/Tokens.hs b/src/Model/Tokens.hs index 5a2d6335e..613e5ce0d 100644 --- a/src/Model/Tokens.hs +++ b/src/Model/Tokens.hs @@ -1,3 +1,4 @@ +{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} {-# LANGUAGE UndecidableInstances #-} module Model.Tokens @@ -23,14 +24,12 @@ import qualified Jose.Jwt as Jose import Jose.Jwt.Instances () import Data.Aeson.Types.Instances () -import Data.HashSet (HashSet) - import qualified Data.HashMap.Strict as HashMap import Data.HashMap.Strict.Instances () import Data.HashSet.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.Types as JSON diff --git a/src/Model/Types/Allocation.hs b/src/Model/Types/Allocation.hs index 7eca27b58..6fe299312 100644 --- a/src/Model/Types/Allocation.hs +++ b/src/Model/Types/Allocation.hs @@ -14,7 +14,7 @@ import qualified Data.Vector as Vector 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) #-} diff --git a/src/Model/Types/DateTime.hs b/src/Model/Types/DateTime.hs index cff7a0793..db1a8f9d7 100644 --- a/src/Model/Types/DateTime.hs +++ b/src/Model/Types/DateTime.hs @@ -1,3 +1,4 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} {-| Module: Model.Types.DateTime Description: Time related types @@ -20,9 +21,6 @@ import Web.HttpApiData import Data.Aeson.Types as Aeson -import Time.Types (WeekDay(..)) -import Data.Time.LocalTime (LocalTime, TimeOfDay) - ---- -- Terms, Seaons, anything loosely related to time @@ -42,6 +40,7 @@ seasonFromChar c | c ~= 'W' = Right Winter | otherwise = Left $ "Invalid season character: ‘" <> tshow c <> "’" where + (~=) :: Char -> Char -> Bool (~=) = (==) `on` CI.mk data TermIdentifier = TermIdentifier @@ -64,6 +63,7 @@ shortened :: Iso' Integer Integer -- ^ Year numbers shortened to two digits shortened = iso shorten expand where + century :: Integer century = ($currentYear `div` 100) * 100 expand year | 0 <= year @@ -189,3 +189,5 @@ deriveJSON defaultOptions } ''Occurrences derivePersistFieldJSON ''Occurrences + +nullaryPathPiece ''DayOfWeek camelToPathPiece diff --git a/src/Model/Types/Exam.hs b/src/Model/Types/Exam.hs index 8c05bb3cd..265686c14 100644 --- a/src/Model/Types/Exam.hs +++ b/src/Model/Types/Exam.hs @@ -231,6 +231,7 @@ instance Finite ExamGrade numberGrade :: Prism' Rational ExamGrade numberGrade = prism toNumberGrade fromNumberGrade where + toNumberGrade :: ExamGrade -> Rational toNumberGrade = \case Grade50 -> 5.0 Grade40 -> 4.0 @@ -243,6 +244,7 @@ numberGrade = prism toNumberGrade fromNumberGrade Grade17 -> 1.7 Grade13 -> 1.3 Grade10 -> 1.0 + fromNumberGrade :: Rational -> Either Rational ExamGrade fromNumberGrade = \case 5.0 -> Right Grade50 4.0 -> Right Grade40 @@ -271,7 +273,8 @@ instance Csv.FromField ExamGrade where [ parse =<< Csv.parseField x , 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 toPersistValue = PersistRational . review numberGrade diff --git a/src/Model/Types/Mail.hs b/src/Model/Types/Mail.hs index de71b226b..228427ac1 100644 --- a/src/Model/Types/Mail.hs +++ b/src/Model/Types/Mail.hs @@ -54,15 +54,9 @@ instance Finite NotificationTrigger instance Hashable NotificationTrigger -deriveJSON defaultOptions - { constructorTagModifier = intercalate "-" . map toLower . drop 1 . splitCamel - } ''NotificationTrigger - -instance ToJSONKey NotificationTrigger where - toJSONKey = toJSONKeyText $ \v -> let Aeson.String t = toJSON v in t - -instance FromJSONKey NotificationTrigger where - fromJSONKey = FromJSONKeyTextParser $ parseJSON . Aeson.String +nullaryPathPiece ''NotificationTrigger $ camelToPathPiece' 1 +pathPieceJSON ''NotificationTrigger +pathPieceJSONKey ''NotificationTrigger newtype NotificationSettings = NotificationSettings { notificationAllowed :: NotificationTrigger -> Bool } diff --git a/src/Model/Types/Misc.hs b/src/Model/Types/Misc.hs index 7cddd01b0..ea7167d48 100644 --- a/src/Model/Types/Misc.hs +++ b/src/Model/Types/Misc.hs @@ -177,7 +177,7 @@ instance YesodMail site => ToMailPart site (CsvRendered, CsvOptions) where toMailPart (CsvRendered{..}, encOpts) = do _partType .= decodeUtf8 typeCsv' _partEncoding .= QuotedPrintableText - _partContent .= recode' (Csv.encodeByNameWith (encOpts ^. _csvFormat . _CsvEncodeOptions) csvRenderedHeader csvRenderedData) + _partContent .= PartContent (recode' $ Csv.encodeByNameWith (encOpts ^. _csvFormat . _CsvEncodeOptions) csvRenderedHeader csvRenderedData) where recode' :: LBS.ByteString -> LBS.ByteString recode' @@ -218,14 +218,16 @@ deriveJSON defaultOptions } ''Sex nullaryPathPiece ''Sex $ camelToPathPiece' 1 -iso5218 :: Integral n => Prism' n Sex +iso5218 :: forall n. Integral n => Prism' n Sex iso5218 = prism' sexToWord sexFromWord where + sexToWord :: Sex -> n sexToWord = \case SexNotKnown -> 0 SexMale -> 1 SexFemale -> 2 SexNotApplicable -> 9 + sexFromWord :: n -> Maybe Sex sexFromWord = \case 0 -> Just SexNotKnown 1 -> Just SexMale diff --git a/src/Model/Types/Security.hs b/src/Model/Types/Security.hs index 682cbc789..3b5142bce 100644 --- a/src/Model/Types/Security.hs +++ b/src/Model/Types/Security.hs @@ -11,8 +11,6 @@ module Model.Types.Security import Import.NoModel -import Data.Set (Set) - import qualified Data.Text as Text import qualified Data.HashMap.Strict as HashMap @@ -89,17 +87,9 @@ instance Universe AuthTag instance Finite AuthTag instance Hashable AuthTag -deriveJSON defaultOptions - { constructorTagModifier = camelToPathPiece' 1 - } ''AuthTag - -nullaryPathPiece ''AuthTag (camelToPathPiece' 1) - -instance ToJSONKey AuthTag where - toJSONKey = toJSONKeyText $ \v -> let Aeson.String t = toJSON v in t - -instance FromJSONKey AuthTag where - fromJSONKey = FromJSONKeyTextParser $ parseJSON . Aeson.String +nullaryPathPiece ''AuthTag $ camelToPathPiece' 1 +pathPieceJSON ''AuthTag +pathPieceJSONKey ''AuthTag instance Binary AuthTag @@ -175,6 +165,7 @@ instance PathPiece UserGroupName where | "metrics" `ciEq` t -> UserGroupMetrics | otherwise -> UserGroupCustom $ CI.mk t where + ciEq :: Text -> Text -> Bool ciEq = (==) `on` CI.mk pathPieceJSON ''UserGroupName diff --git a/src/Model/Types/Sheet.hs b/src/Model/Types/Sheet.hs index d545c5bbb..26e4bb291 100644 --- a/src/Model/Types/Sheet.hs +++ b/src/Model/Types/Sheet.hs @@ -13,15 +13,11 @@ import Utils.Lens.TH import Generics.Deriving.Monoid (memptydefault, mappenddefault) -import Data.Set (Set) import qualified Data.Set as Set import qualified Data.Map as Map -import Data.Aeson.TH (deriveJSON, defaultOptions, Options(..), SumEncoding(..)) import Text.Blaze (Markup) -import Yesod.Core.Dispatch (PathPiece(..)) - import Data.Maybe (fromJust) diff --git a/src/Model/Types/Submission.hs b/src/Model/Types/Submission.hs index 1c5e4655d..b8ace9549 100644 --- a/src/Model/Types/Submission.hs +++ b/src/Model/Types/Submission.hs @@ -11,7 +11,6 @@ module Model.Types.Submission import Import.NoModel -import Data.Aeson.Types (ToJSON(..), FromJSON(..)) import qualified Data.Aeson.Types as Aeson import Database.Persist.Sql @@ -142,6 +141,7 @@ pseudonymWords = folding where distance = damerauLevenshtein `on` CI.foldedCase -- | Arbitrary cutoff point, for reference: ispell cuts off at 1 + distanceCutoff :: Int distanceCutoff = 2 pseudonymFragments :: Fold Text [PseudonymWord] diff --git a/src/Model/Types/TH/Wordlist.hs b/src/Model/Types/TH/Wordlist.hs index de3d159d8..7ef389c0e 100644 --- a/src/Model/Types/TH/Wordlist.hs +++ b/src/Model/Types/TH/Wordlist.hs @@ -7,7 +7,6 @@ import ClassyPrelude hiding (lift) import Language.Haskell.TH import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..)) -import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.IO as Text diff --git a/src/Network/Mail/Mime/Instances.hs b/src/Network/Mail/Mime/Instances.hs index 83cc59c14..201442aee 100644 --- a/src/Network/Mail/Mime/Instances.hs +++ b/src/Network/Mail/Mime/Instances.hs @@ -6,7 +6,6 @@ module Network.Mail.Mime.Instances import ClassyPrelude import Network.Mail.Mime -import Data.Hashable (Hashable) import Data.Aeson import Data.Aeson.TH diff --git a/src/Network/Mime/TH.hs b/src/Network/Mime/TH.hs index 486eda779..e90033904 100644 --- a/src/Network/Mime/TH.hs +++ b/src/Network/Mime/TH.hs @@ -9,7 +9,6 @@ import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..)) import qualified Data.Set as Set import qualified Data.Map as Map -import Data.Text (Text) import qualified Data.Text as Text import qualified Data.Text.IO as Text import qualified Data.Text.Encoding as Text diff --git a/src/Settings.hs b/src/Settings.hs index 76dea50e7..a611d19b9 100644 --- a/src/Settings.hs +++ b/src/Settings.hs @@ -13,7 +13,6 @@ module Settings ) where import Import.NoModel -import Data.UUID (UUID) import qualified Control.Exception as Exception import Data.Aeson (fromJSON, withObject ,(.!=), (.:?), withScientific @@ -23,12 +22,10 @@ import Data.FileEmbed (embedFile) import Data.Yaml (decodeEither') import Database.Persist.Postgresql (PostgresConf) import Network.Wai.Handler.Warp (HostPreference) -import Yesod.Default.Config2 (applyEnvValue, configSettingsYml) #ifdef DEVELOPMENT import Yesod.Default.Util (WidgetFileSettings, widgetFileReload) import Language.Haskell.TH.Syntax (Exp, Q, location, Loc(..)) -import Text.Shakespeare.Text (st) import Text.Blaze.Html (preEscapedToHtml) #else import Yesod.Default.Util (WidgetFileSettings, widgetFileNoReload, widgetFileReload) @@ -36,8 +33,6 @@ import Language.Haskell.TH.Syntax (Exp, Q) #endif import qualified Yesod.Auth.Util.PasswordStore as PWStore -import Data.Time (NominalDiffTime, nominalDay) - import Data.Scientific (Scientific, toBoundedInteger) import Data.Word (Word16) @@ -47,22 +42,16 @@ import qualified Data.Text.Encoding as Text import qualified Ldap.Client as Ldap import qualified Network.HaskellNet.Auth as HaskellNet (UserName, Password, AuthType(..)) -import qualified Network.Socket as HaskellNet (PortNumber, HostName) -import qualified Network +import qualified Network.Socket as HaskellNet -import Network.Mail.Mime (Address) import Network.Mail.Mime.Instances () -import Mail (VerpMode) - import qualified Database.Memcached.Binary.Types as Memcached import Model import Settings.Cluster import Settings.Mime -import Control.Monad.Trans.Maybe (MaybeT(..)) - import qualified System.FilePath as FilePath import Jose.Jwt (JwtEncoding(..)) @@ -230,13 +219,6 @@ data WidgetMemcachedConf = WidgetMemcachedConf instance FromJSON Memcached.Auth where parseJSON = Aeson.withText "Auth" $ \(Text.breakOn "@" -> (encodeUtf8 -> user, encodeUtf8 -> pw)) -> return $ Memcached.Plain user pw -instance FromJSON Network.PortID where - parseJSON v = Network.UnixSocket <$> pSocket v <|> Network.PortNumber <$> pNumber v <|> Network.Service <$> pService v - where - pSocket = Aeson.withText "UnixSocket" $ fmap unpack . assertM' ("/" `Text.isPrefixOf`) - pNumber = Aeson.withScientific "PortNumber" $ maybe (fail "PortNumber ") (return . (fromIntegral :: Word16 -> Network.PortNumber)) . toBoundedInteger - pService = Aeson.withText "Service" $ return . unpack - instance FromJSON WidgetMemcachedConf where parseJSON = withObject "WidgetMemcachedConf" $ \o -> do connectHost <- o .:? "host" .!= "" @@ -382,13 +364,11 @@ instance FromJSON AppSettings where appLdapConf <- assertM nonEmptyHost <$> o .:? "ldap" appSmtpConf <- assertM (not . null . smtpHost) <$> o .:? "smtp" let validWidgetMemcachedConf WidgetMemcachedConf{ widgetMemcachedConnectInfo = Memcached.ConnectInfo{..}, ..} = and - [ not (null connectHost) || isUnixSocket connectPort + [ not $ null connectHost , not $ null widgetMemcachedBaseUrl , numConnection > 0 , connectionIdleTime >= 0 ] - isUnixSocket (Network.UnixSocket _) = True - isUnixSocket _ = False appWidgetMemcachedConf <- assertM validWidgetMemcachedConf <$> o .:? "widget-memcached" appRoot <- o .:? "approot" appHost <- fromString <$> o .: "host" diff --git a/src/Settings/Cluster.hs b/src/Settings/Cluster.hs index 037c9d967..6b4d0e836 100644 --- a/src/Settings/Cluster.hs +++ b/src/Settings/Cluster.hs @@ -6,19 +6,12 @@ module Settings.Cluster ) where import ClassyPrelude.Yesod -import Database.Persist.Sql import Web.HttpApiData import Utils import Control.Lens import Data.Universe -import Data.Aeson ( FromJSON(..), ToJSON(..) - , Options(..), defaultOptions - , FromJSONKey(..), ToJSONKey(..), FromJSONKeyFunction(..) - ) -import Data.Aeson.TH (deriveJSON) -import Data.Aeson.Types (toJSONKeyText) import qualified Data.Aeson as Aeson import qualified Web.ClientSession as ClientSession @@ -39,6 +32,10 @@ import qualified Jose.Jwt as Jose import Data.UUID (UUID) import Control.Monad.Random.Class (MonadRandom(..)) +import Control.Monad.Fail + +import Model.Types.TH.PathPiece + data ClusterSettingsKey = ClusterCryptoIDKey @@ -51,27 +48,10 @@ data ClusterSettingsKey instance Universe ClusterSettingsKey instance Finite ClusterSettingsKey -nullaryPathPiece ''ClusterSettingsKey (camelToPathPiece' 1) - -deriveJSON - defaultOptions - { constructorTagModifier = camelToPathPiece' 1 - } - ''ClusterSettingsKey - -instance ToJSONKey ClusterSettingsKey where - toJSONKey = toJSONKeyText $ \v -> let String t = toJSON v in t - -instance FromJSONKey ClusterSettingsKey where - fromJSONKey = FromJSONKeyTextParser $ parseJSON . String - -instance PersistField ClusterSettingsKey where - toPersistValue = PersistText . toPathPiece - fromPersistValue (PersistText t) = maybe (Left $ "Could not parse " <> t) Right $ fromPathPiece t - fromPersistValue _other = Left "Expecting PersistText" - -instance PersistFieldSql ClusterSettingsKey where - sqlType _ = SqlString +nullaryPathPiece ''ClusterSettingsKey $ camelToPathPiece' 1 +pathPieceJSON ''ClusterSettingsKey +pathPieceJSONKey ''ClusterSettingsKey +derivePersistFieldPathPiece ''ClusterSettingsKey instance ToHttpApiData ClusterSettingsKey where toUrlPiece = toPathPiece diff --git a/src/Settings/StaticFiles/Generator.hs b/src/Settings/StaticFiles/Generator.hs index 2e2d0ae45..47c04090c 100644 --- a/src/Settings/StaticFiles/Generator.hs +++ b/src/Settings/StaticFiles/Generator.hs @@ -25,6 +25,8 @@ import qualified Data.Foldable as Fold import Settings.Mime +import Control.Monad.Fail + staticGenerator :: FilePath -> Generator staticGenerator staticDir = do diff --git a/src/Settings/WellKnownFiles/TH.hs b/src/Settings/WellKnownFiles/TH.hs index 890184588..e88a25755 100644 --- a/src/Settings/WellKnownFiles/TH.hs +++ b/src/Settings/WellKnownFiles/TH.hs @@ -26,17 +26,18 @@ import qualified Data.Set as Set import Data.List.NonEmpty (NonEmpty(..)) -import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as HashMap import qualified Data.HashSet as HashSet -import System.FilePath ((), splitDirectories, makeRelative) +import System.FilePath (splitDirectories, makeRelative) import Settings.Mime import Text.Blaze.Html (preEscapedToHtml) +import Control.Monad.Fail + nWellKnownFileName :: Name nWellKnownFileName = mkName "WellKnownFileName" diff --git a/src/Text/Blaze/Instances.hs b/src/Text/Blaze/Instances.hs index 3ff06308b..19c479aa9 100644 --- a/src/Text/Blaze/Instances.hs +++ b/src/Text/Blaze/Instances.hs @@ -10,7 +10,6 @@ import qualified Text.Blaze.Renderer.Text as Text import Text.Read (Read(..)) -import Data.Hashable (Hashable(..)) import Data.Aeson (ToJSON(..), FromJSON(..)) import qualified Data.Aeson as Aeson diff --git a/src/Time/Types/Instances.hs b/src/Time/Types/Instances.hs deleted file mode 100644 index fa61bca45..000000000 --- a/src/Time/Types/Instances.hs +++ /dev/null @@ -1,25 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} - -module Time.Types.Instances - ( - ) where - --- import ClassyPrelude - -import Time.Types - -import Data.Universe - -import Utils.PathPiece - -import Data.Aeson.TH - - -instance Universe WeekDay -instance Finite WeekDay - -nullaryPathPiece ''WeekDay camelToPathPiece - -deriveJSON defaultOptions - { constructorTagModifier = camelToPathPiece - } ''WeekDay diff --git a/src/Utils.hs b/src/Utils.hs index c1a05222d..56809e75d 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -35,9 +35,7 @@ import Text.Blaze (Markup, ToMarkup) import Data.Char (isDigit, isSpace, isAscii) import Data.Text (dropWhileEnd, takeWhileEnd, justifyRight) -import Data.Set (Set) import qualified Data.Set as Set -import Data.Map (Map) import qualified Data.Map as Map import qualified Data.List as List @@ -204,7 +202,7 @@ textPercent' trailZero precision part whole -- | Convert number of bytes to human readable format -textBytes :: Integral a => a -> Text +textBytes :: forall a. Integral a => a -> Text textBytes x | v < kb = rshow v <> "B" | v < mb = rshow (v/kb) <> "KB" @@ -212,6 +210,7 @@ textBytes x | otherwise = rshow (v/gb) <> "GB" where v = fromIntegral x + kb :: Double kb = 1024 mb = 1024 * kb gb = 1024 * mb diff --git a/src/Utils/Allocation.hs b/src/Utils/Allocation.hs index d5e80c6b4..ffdd3684d 100644 --- a/src/Utils/Allocation.hs +++ b/src/Utils/Allocation.hs @@ -14,7 +14,6 @@ import Data.Array.ST (STArray) import qualified Data.Array.MArray as MArr import System.Random (RandomGen) -import Control.Monad.Random.Class (getRandom) import Control.Monad.Trans.Random.Strict (evalRandT, RandT) import Control.Monad.Trans.State.Strict (StateT, modify', get, gets, evalStateT) import Control.Monad.Writer (tell) @@ -45,7 +44,6 @@ computeMatching :: forall randomGen student course cloneCount cloneIndex capacit , Ord student, Ord course , NFData student , Ord studentRatingCourse - , Ord courseRatingStudent , Ord courseRatingStudent' , Integral cloneCount, Integral capacity, Num cloneIndex ) @@ -63,7 +61,6 @@ computeMatchingLog :: forall randomGen student course cloneCount cloneIndex capa , Ord student, Ord course , NFData student , Ord studentRatingCourse - , Ord courseRatingStudent , Ord courseRatingStudent' , Integral cloneCount, Integral capacity, Num cloneIndex ) diff --git a/src/Utils/DB.hs b/src/Utils/DB.hs index decb7e4d6..fffdc8c51 100644 --- a/src/Utils/DB.hs +++ b/src/Utils/DB.hs @@ -3,9 +3,7 @@ module Utils.DB where import ClassyPrelude.Yesod import qualified Data.List as List -import Data.Map (Map) import qualified Data.Map as Map -import Data.Set (Set) import qualified Data.Set as Set import qualified Database.Esqueleto as E -- import Database.Persist -- currently not needed here diff --git a/src/Utils/DateTime.hs b/src/Utils/DateTime.hs index 3120f49f5..29861dfc8 100644 --- a/src/Utils/DateTime.hs +++ b/src/Utils/DateTime.hs @@ -15,7 +15,7 @@ module Utils.DateTime import ClassyPrelude.Yesod hiding (lift) import System.Locale.Read -import Data.Time (TimeLocale(..), NominalDiffTime, nominalDay) +import Data.Time (NominalDiffTime, nominalDay) import Data.Time.Zones (TZ) import Data.Time.Zones.TH (includeSystemTZ) @@ -26,14 +26,9 @@ import Language.Haskell.TH.Syntax (Lift(..)) import Instances.TH.Lift () import Data.Data (Data) -import Data.Typeable (Typeable) import Data.Universe -import Database.Persist.Sql (PersistField, PersistFieldSql) - -import Data.Aeson.Types (toJSONKeyText) -import Data.Aeson -import Data.Aeson.TH +import Database.Persist.Sql (PersistFieldSql) import Utils.PathPiece @@ -41,6 +36,8 @@ import Data.Time.Format.Instances () import Algebra.Lattice import Algebra.Lattice.Ordered + +import Control.Monad.Fail -- $(timeLocaleMap _) :: [Lang] -> TimeLocale @@ -89,36 +86,25 @@ instance Universe SelDateTimeFormat instance Finite SelDateTimeFormat instance Hashable SelDateTimeFormat -deriveJSON defaultOptions - { constructorTagModifier = camelToPathPiece' 2 - } ''SelDateTimeFormat - -instance ToJSONKey SelDateTimeFormat where - toJSONKey = toJSONKeyText $ \v -> let String txt = toJSON v in txt -instance FromJSONKey SelDateTimeFormat where - fromJSONKey = FromJSONKeyTextParser $ parseJSON . String +nullaryPathPiece ''SelDateTimeFormat $ camelToPathPiece' 2 +pathPieceJSON ''SelDateTimeFormat +pathPieceJSONKey ''SelDateTimeFormat instance {-# OVERLAPPING #-} Default (SelDateTimeFormat -> DateTimeFormat) where def SelFormatDateTime = "%c" def SelFormatDate = "%F" def SelFormatTime = "%T" -instance JoinSemiLattice SelDateTimeFormat where +instance Lattice SelDateTimeFormat where a \/ b = getOrdered $ ((\/) `on` Ordered) a b - -instance MeetSemiLattice SelDateTimeFormat where a /\ b = getOrdered $ ((/\) `on` Ordered) a b -instance Lattice SelDateTimeFormat - instance BoundedJoinSemiLattice SelDateTimeFormat where bottom = SelFormatTime instance BoundedMeetSemiLattice SelDateTimeFormat where top = SelFormatDateTime -instance BoundedLattice SelDateTimeFormat - --------------------- -- NominalDiffTime -- diff --git a/src/Utils/Form.hs b/src/Utils/Form.hs index 4fa7681b5..1c37049fa 100644 --- a/src/Utils/Form.hs +++ b/src/Utils/Form.hs @@ -24,7 +24,6 @@ import Data.Map.Lazy ((!)) import qualified Data.Map.Lazy as Map import qualified Data.Set as Set -import Control.Monad.Trans.Maybe (MaybeT(..)) import Control.Monad.Reader.Class (MonadReader(..)) import Control.Monad.Writer.Class (MonadWriter(..), censor) import Control.Monad.State.Class (MonadState(..)) @@ -482,7 +481,7 @@ reorderField optList = Field{..} return (i, val) return $ if | Map.keysSet selOptions == Set.fromList [1..olNum] - -> Right . Just $ map (selOptions !) [1..fromIntegral olNum] + -> Right . Just $ map (selOptions !) [1..olNum] | otherwise -> Left "Not a valid permutation" fieldView theId name attrs val isReq = do diff --git a/src/Utils/Lang.hs b/src/Utils/Lang.hs index 3280c62fc..d99c909b3 100644 --- a/src/Utils/Lang.hs +++ b/src/Utils/Lang.hs @@ -11,7 +11,7 @@ import qualified Data.List as List import qualified Data.CaseInsensitive as CI -import Yesod.Core.Types (HandlerData(handlerRequest), YesodRequest(reqLangs)) +import Yesod.Core.Types (HandlerData(handlerRequest)) import qualified Network.Wai.Parse as NWP import Control.Monad.Trans.Maybe (MaybeT(..)) diff --git a/src/Utils/Lens.hs b/src/Utils/Lens.hs index 1e5042171..af91720e8 100644 --- a/src/Utils/Lens.hs +++ b/src/Utils/Lens.hs @@ -21,7 +21,7 @@ import Data.Map.Lens as Utils.Lens import Data.Generics.Product.Types as Utils.Lens -import Yesod.Core.Types (HandlerContents(..), ErrorResponse(..)) +import Yesod.Core.Types (HandlerContents(..)) import qualified Database.Esqueleto as E (Value(..),InnerJoin(..)) diff --git a/src/Utils/Occurrences.hs b/src/Utils/Occurrences.hs index 28ebdab8d..6b4051d89 100644 --- a/src/Utils/Occurrences.hs +++ b/src/Utils/Occurrences.hs @@ -10,7 +10,7 @@ import Model.Types import Utils import Utils.Lens -import Control.Monad.Trans.Reader (runReader, Reader) +import Control.Monad.Trans.Reader (runReader) import Control.Monad.Trans.Except (ExceptT, throwE, runExceptT) diff --git a/src/Utils/PathPiece.hs b/src/Utils/PathPiece.hs index f3b8e0e7b..1ce2b0a94 100644 --- a/src/Utils/PathPiece.hs +++ b/src/Utils/PathPiece.hs @@ -26,6 +26,8 @@ import Data.List (foldl) import Data.Aeson.Types import qualified Data.Aeson.Types as Aeson + +import Control.Monad.Fail finiteFromPathPiece :: (PathPiece a, Finite a) => Text -> Maybe a diff --git a/src/Utils/SystemMessage.hs b/src/Utils/SystemMessage.hs index e5cff0496..8de3add92 100644 --- a/src/Utils/SystemMessage.hs +++ b/src/Utils/SystemMessage.hs @@ -5,8 +5,6 @@ import Import.NoFoundation import qualified Data.List.NonEmpty as NonEmpty import Data.List (findIndex) -import Control.Monad.Trans.Maybe (MaybeT(..)) - getSystemMessage :: MonadHandler m => NonEmpty Lang -- ^ `appLanguages` diff --git a/src/Utils/TH.hs b/src/Utils/TH.hs index be7d53957..9855daeb6 100644 --- a/src/Utils/TH.hs +++ b/src/Utils/TH.hs @@ -13,6 +13,8 @@ import Language.Haskell.TH.Datatype import Data.List ((!!), foldl) +import Control.Monad.Fail + ------------ -- Tuples -- ------------ diff --git a/src/Utils/Tokens.hs b/src/Utils/Tokens.hs index 549ea81e6..5ae042c82 100644 --- a/src/Utils/Tokens.hs +++ b/src/Utils/Tokens.hs @@ -8,9 +8,6 @@ module Utils.Tokens import Import.NoModel -import Yesod.Auth (AuthId) - -import Utils (NTop(..), hoistMaybe, SessionKey(..)) import Utils.Lens import Model @@ -28,9 +25,6 @@ import qualified Data.Aeson.Internal as JSON (iparse, formatError) import qualified Data.HashMap.Strict as HashMap -import Control.Monad.Random (MonadRandom(..)) -import Control.Monad.Trans.Maybe (MaybeT(..)) - import Settings import CryptoID diff --git a/src/Yesod/Core/Instances.hs b/src/Yesod/Core/Instances.hs index 10c369666..e145d6575 100644 --- a/src/Yesod/Core/Instances.hs +++ b/src/Yesod/Core/Instances.hs @@ -12,20 +12,18 @@ import Control.Lens import Data.ByteString.Builder (toLazyByteString) -import System.FilePath (()) - import Data.Aeson import Data.Aeson.Types import Control.Monad.Fix -import Control.Monad.Fail (MonadFail) -import qualified Control.Monad.Fail as MonadFail import Control.Monad.Except (MonadError(..)) import Data.Functor.Extend import Data.Binary (Binary) import qualified Data.Binary as Binary +import Control.Monad.Fail + routeFromPathPiece :: ParseRoute site => Text -> Maybe (Route site) routeFromPathPiece @@ -77,8 +75,6 @@ instance Monad FormResult where FormMissing >>= _ = FormMissing (FormFailure errs) >>= _ = FormFailure errs - fail = MonadFail.fail - instance MonadFail FormResult where fail _ = FormMissing diff --git a/src/Yesod/Core/Types/Instances.hs b/src/Yesod/Core/Types/Instances.hs index faac3b4a3..042255544 100644 --- a/src/Yesod/Core/Types/Instances.hs +++ b/src/Yesod/Core/Types/Instances.hs @@ -22,7 +22,7 @@ import Utils import Language.Haskell.TH import Control.Monad.Reader (MonadReader(..)) -import Control.Monad.Trans.Reader (ReaderT, mapReaderT, runReaderT) +import Control.Monad.Trans.Reader (mapReaderT) import Control.Monad.Base (MonadBase) import Control.Monad.Trans.Control (MonadBaseControl) import Control.Monad.Catch (MonadMask, MonadCatch) diff --git a/stack.yaml b/stack.yaml index d52b84385..20c318374 100644 --- a/stack.yaml +++ b/stack.yaml @@ -12,15 +12,24 @@ packages: extra-deps: - git: git@gitlab2.rz.ifi.lmu.de:uni2work/encoding.git - commit: 67bb87ceff53f0178c988dd4e15eeb2daee92b84 + commit: 22fc3bb14841d8d50997aa47f1be3852e666f787 - git: git@gitlab2.rz.ifi.lmu.de:uni2work/memcached-binary.git - commit: b5461747e7be226d3b67daebc3c9aefe8a4490ad + commit: b7071df50bad3a251a544b984e4bf98fa09b8fae - git: git@gitlab2.rz.ifi.lmu.de:uni2work/conduit-resumablesink.git commit: cbea6159c2975d42f948525e03e12fc390da53c5 + - git: git://github.com/jtdaugherty/HaskellNet.git + commit: 5aa1f3b009253b02c4822005ac59ee208a10a347 + - git: git@gitlab2.rz.ifi.lmu.de:uni2work/HaskellNet-SSL.git + commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8 + - git: git@gitlab2.rz.ifi.lmu.de:uni2work/ldap-client.git + commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0 - - zip-stream-0.2.0.1 + - colonnade-1.2.0.2 + - hsass-0.8.0 + - hlibsass-0.1.8.1 + - tz-0.1.3.3 - - ldap-client-0.3.0 + # - zip-stream-0.2.0.1 - uuid-crypto-1.4.0.0 - filepath-crypto-0.1.0.0 @@ -34,55 +43,54 @@ extra-deps: - pkcs7-1.0.0.1 - - systemd-1.2.0 + - systemd-2.2.0 - - directory-1.3.4.0 + # - directory-1.3.4.0 - - HaXml-1.25.5 + # - HaXml-1.25.5 - - persistent-2.10.4 - - persistent-postgresql-2.10.1 - - persistent-template-2.7.3 - - esqueleto-3.2.3 + # - persistent-2.10.4 + # - persistent-postgresql-2.10.1 + # - persistent-template-2.7.3 + # - esqueleto-3.2.3 - - HaskellNet-SSL-0.3.4.1 - sandi-0.5 - storable-endian-0.2.6 - - universe-1.2 - - universe-base-1.1.1 - - universe-reverse-instances-1.1 - - unliftio-pool-0.2.1.0 - - universe-instances-extended-1.1.1 - - universe-some-1.2 - - some-1.0.0.3 + # - universe-1.2 + # - universe-base-1.1.1 + # - universe-reverse-instances-1.1 + # - unliftio-pool-0.2.1.0 + # - universe-instances-extended-1.1.1 + # - universe-some-1.2 + # - some-1.0.0.3 - - network-bsd-2.8.1.0 + # - network-bsd-2.8.1.0 - - persistent-qq-2.9.1 + # - persistent-qq-2.9.1 - - process-1.6.5.1 + # - process-1.6.5.1 - - generic-lens-1.2.0.0 + # - generic-lens-1.2.0.0 - - prometheus-metrics-ghc-1.0.0 + - prometheus-metrics-ghc-1.0.1 - wai-middleware-prometheus-1.0.0 - - extended-reals-0.2.3.0 + # - extended-reals-0.2.3.0 - pandoc-2.9.2 - doclayout-0.3 - - emojis-0.1 - - hslua-module-system-0.2.1 - - ipynb-0.1 - - jira-wiki-markup-1.0.0 - - HsYAML-0.2.1.0 - - cmark-gfm-0.2.1 - doctemplates-0.8.1 - - haddock-library-1.8.0 - - pandoc-types-1.20 - - skylighting-0.8.3.2 - - skylighting-core-0.8.3.2 - - texmath-0.12.0.1 + # - emojis-0.1 + # - hslua-module-system-0.2.1 + # - ipynb-0.1 + # - jira-wiki-markup-1.0.0 + # - HsYAML-0.2.1.0 + # - cmark-gfm-0.2.1 + # - haddock-library-1.8.0 + # - pandoc-types-1.20 + # - skylighting-0.8.3.2 + # - skylighting-core-0.8.3.2 + # - texmath-0.12.0.1 -resolver: lts-13.21 +resolver: lts-15.0 allow-newer: true diff --git a/stack.yaml.lock b/stack.yaml.lock index b96e82ebb..ecf90088b 100644 --- a/stack.yaml.lock +++ b/stack.yaml.lock @@ -6,32 +6,32 @@ packages: - completed: cabal-file: - size: 4141 - sha256: 88537113b855381b8d70da2442ae644dc979ad6b32aaaec2ebf55306764c8f1a + size: 4229 + sha256: 0dcfe3c4a67be4e96e1ae2e3c4b8744bc11e094853005a32f6074ab776caa3a9 name: encoding version: 0.8.2 git: git@gitlab2.rz.ifi.lmu.de:uni2work/encoding.git pantry-tree: - size: 5668 - sha256: 57160d758802aba6a0d2cc88c53f2f0bb60df7d5e6822938351618b7eca0beab - commit: 67bb87ceff53f0178c988dd4e15eeb2daee92b84 + size: 5723 + sha256: fec12328951021bb4d9326ae0b35f0c459e65f28442366efd4366cd1e18abe19 + commit: 22fc3bb14841d8d50997aa47f1be3852e666f787 original: git: git@gitlab2.rz.ifi.lmu.de:uni2work/encoding.git - commit: 67bb87ceff53f0178c988dd4e15eeb2daee92b84 + commit: 22fc3bb14841d8d50997aa47f1be3852e666f787 - completed: cabal-file: - size: 2384 - sha256: 7b25a0ef819e8a01b485d6d0865baa3445faa826ffb3876c94109dd2469ffbd3 + size: 2399 + sha256: 20cdf97602abb8fd7356c1a64c69fa857e34ab4cfe7834460d2ad783f7e4e4e3 name: memcached-binary version: 0.2.0 git: git@gitlab2.rz.ifi.lmu.de:uni2work/memcached-binary.git pantry-tree: - size: 1170 - sha256: c466f91129410bae1f53e25aec4026f6984ce2dff0ada4516e2548048aba549a - commit: b5461747e7be226d3b67daebc3c9aefe8a4490ad + size: 1277 + sha256: 0da0539b7b9a56d03a116dcd666bc1bbbef085659910420849484d1418aa0857 + commit: b7071df50bad3a251a544b984e4bf98fa09b8fae original: git: git@gitlab2.rz.ifi.lmu.de:uni2work/memcached-binary.git - commit: b5461747e7be226d3b67daebc3c9aefe8a4490ad + commit: b7071df50bad3a251a544b984e4bf98fa09b8fae - completed: cabal-file: size: 1423 @@ -47,19 +47,75 @@ packages: git: git@gitlab2.rz.ifi.lmu.de:uni2work/conduit-resumablesink.git commit: cbea6159c2975d42f948525e03e12fc390da53c5 - completed: - hackage: zip-stream-0.2.0.1@sha256:78cd3244efbfba99184d17f5923980282f7d1b8f6d71c6e8af14e516e4239691,1742 + cabal-file: + size: 2069 + sha256: 9192ac19ea5da3cd4b8c86a4266592aff7b9256311aa5f42ae6de94ccacf1366 + name: HaskellNet + version: 0.5.1 + git: git://github.com/jtdaugherty/HaskellNet.git pantry-tree: - size: 559 - sha256: 85960a435d280e933f697163c2ec6861261214d56f4c326d1ab920f37cb4f8c1 + size: 4011 + sha256: 921b437ef18ccb04f889301c407263d6b5b72c5864803a000b1e61328988ce70 + commit: 5aa1f3b009253b02c4822005ac59ee208a10a347 original: - hackage: zip-stream-0.2.0.1 + git: git://github.com/jtdaugherty/HaskellNet.git + commit: 5aa1f3b009253b02c4822005ac59ee208a10a347 - completed: - hackage: ldap-client-0.3.0@sha256:e62aa1cbe7fc27fc2f197c9cf3601c2fd46e189f8cd84bd25f8323537d31067f,2220 + cabal-file: + size: 1934 + sha256: 9fbe7c3681e963eea213ab38be17966bb690788c1c55a67257916b677d7d2ec2 + name: HaskellNet-SSL + version: 0.3.4.1 + git: git@gitlab2.rz.ifi.lmu.de:uni2work/HaskellNet-SSL.git pantry-tree: - size: 1717 - sha256: 4a682a32028e18a60397d347666fe796e85ef3ba2365c1b5d03cfdd694f0711b + size: 841 + sha256: 95dcec22fdb8af986e59f0f60aa76d4a48f34a546dca799bd571e1d183f773e0 + commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8 original: - hackage: ldap-client-0.3.0 + git: git@gitlab2.rz.ifi.lmu.de:uni2work/HaskellNet-SSL.git + commit: 40393c938111ac78232dc2c7eec5edb4a22d03e8 +- completed: + cabal-file: + size: 2208 + sha256: 48f6e03d8f812bd24e2601497ffe9c8a78907fa2266ba05abeefdfe99221617d + name: ldap-client + version: 0.4.0 + git: git@gitlab2.rz.ifi.lmu.de:uni2work/ldap-client.git + pantry-tree: + size: 6176 + sha256: 3fa8f102427b437b2baaec15cf884e88b47a1621b1c3fd4d8919f0263fde8656 + commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0 + original: + git: git@gitlab2.rz.ifi.lmu.de:uni2work/ldap-client.git + commit: 01afaf599ba6f8a9d804c269e91d3190b249d3f0 +- completed: + hackage: colonnade-1.2.0.2@sha256:c95c2ecff5cfa28c736d8fa662d28b71129f67457068e3f4467b296a621607ab,2099 + pantry-tree: + size: 327 + sha256: 98ccdd327916e0ff0ea2fa93ff9a96f5d492ae88258b330e991e6dcc4d332496 + original: + hackage: colonnade-1.2.0.2 +- completed: + hackage: hsass-0.8.0@sha256:82d55fb2a10342accbc4fe80d263163f40a138d8636e275aa31ffa81b14abf01,2792 + pantry-tree: + size: 1448 + sha256: dc39ed0207b8b22d2713054421dbd5452baa9704df75bedf17f04f97a29f3d9a + original: + hackage: hsass-0.8.0 +- completed: + hackage: hlibsass-0.1.8.1@sha256:7005d0f3fee66e776300117f6bf31583bf310f58df6d7f552c8811bd406abfc8,2564 + pantry-tree: + size: 8441 + sha256: c3c1fe56c35eed093772b9900d7038287b829d67960c6f96a82c9dc46b203db0 + original: + hackage: hlibsass-0.1.8.1 +- completed: + hackage: tz-0.1.3.3@sha256:b9de0c1b10825460ff14a237209a8bf7747f47979601d35621276556bf63d2ca,5086 + pantry-tree: + size: 1180 + sha256: ae6af45f3dba5a478ea9cc77c718f955fcc5c96f2dc0f4ede34c4a15a3e85ac1 + original: + hackage: tz-0.1.3.3 - completed: hackage: uuid-crypto-1.4.0.0@sha256:9e2f271e61467d9ea03e78cddad75a97075d8f5108c36a28d59c65abb3efd290,1325 pantry-tree: @@ -68,17 +124,17 @@ packages: original: hackage: uuid-crypto-1.4.0.0 - completed: - hackage: filepath-crypto-0.1.0.0@sha256:d5d33a2c9d044d025bbbfd4e5fab61f77228604b3cb7ea46e9164f8c8bcc9fb4,1593 + hackage: filepath-crypto-0.1.0.0@sha256:e02bc15858cf06edf9788a38b5b58d45e82c7f5589785a178a903d792af04125,1593 pantry-tree: size: 623 - sha256: 3663e7b1ba2d80c51967a97fb67047bb3d3b5acdaa2b82f4036c4117b3238a49 + sha256: bce236365ebdc6e5c46f740876a6fb5ad688e8ee3b305933822ab027e5b5fd86 original: hackage: filepath-crypto-0.1.0.0 - completed: - hackage: cryptoids-0.5.1.0@sha256:986f0f0e966a83505013f225a4b7805f03c656822704d2a516bf68caf2a9ee04,1570 + hackage: cryptoids-0.5.1.0@sha256:729cd89059c6b6a50e07b2e279f6d95ee9432caeedc7e2f38f71e59c422957bc,1570 pantry-tree: size: 513 - sha256: 4348c28a66cd53602df6c04961f2b980756273f17a1dcefa8c61b6857f7564be + sha256: 563e8d2b616ec3e0e7984d6b069095b6c3959065c0bb047fc8dd5809711a3e6b original: hackage: cryptoids-0.5.1.0 - completed: @@ -117,61 +173,12 @@ packages: original: hackage: pkcs7-1.0.0.1 - completed: - hackage: systemd-1.2.0@sha256:94995d4f1268aa0049d1793b21adb1522b6041e270cea4095c43eb589cc7ce53,1389 + hackage: systemd-2.2.0@sha256:a41399ad921e3c90bb04219a66821631c17c94326961f9b6c71542abb042375f,1477 pantry-tree: - size: 386 - sha256: 16d20860c99050194570c4760337a9d9c156580dbe0ae707f4039f6da1474a93 + size: 520 + sha256: 188d4e07a62653b24091dc25c0222deb7a95037630d17a13327d269391050b7d original: - hackage: systemd-1.2.0 -- completed: - hackage: directory-1.3.4.0@sha256:500019f04494324d1df16cf83eefeb3f809b2b20b32a32ccd755ee0439c18bfd,2829 - pantry-tree: - size: 3365 - sha256: 00c09e0c014d29ebfb921b64c1459e61a0ad6f10e70128d795246a47c06394b0 - original: - hackage: directory-1.3.4.0 -- completed: - hackage: HaXml-1.25.5@sha256:4f8534cda290b3d0a76b4ca5c4b9aa20902dcf029ddd50998d07c5dd608ad6f6,4420 - pantry-tree: - size: 4076 - sha256: 9682020b148433c41f5efee327b66708875015df8d4b3d48f875ac21f8222e1b - original: - hackage: HaXml-1.25.5 -- completed: - hackage: persistent-2.10.4@sha256:16c4c0823dd5e16bac4d607895ab0f4febd0626c020e5755ed1a52bf04068148,4738 - pantry-tree: - size: 2094 - sha256: b40d1783b539ddbbceaa827bf286d0b3bfcf76ca19e604c9d510b2a64008714e - original: - hackage: persistent-2.10.4 -- completed: - hackage: persistent-postgresql-2.10.1@sha256:ea53a0f1f4223b4884b5e19511325367879560d2432a02a976aa4da57c5fb760,2871 - pantry-tree: - size: 740 - sha256: 3cdbc757b1cebb65542fb919369be238b3f120adc45f023084a8b64c214d9675 - original: - hackage: persistent-postgresql-2.10.1 -- completed: - hackage: persistent-template-2.7.3@sha256:ac3e5e8c48e968b927bbf4e97162c52e7e417d69b05efeb1c581d7c682e043d2,2703 - pantry-tree: - size: 560 - sha256: fdfb2a721eb9c9831d7381d36bc52de0808a008ed3d553b6490080f337249684 - original: - hackage: persistent-template-2.7.3 -- completed: - hackage: esqueleto-3.2.3@sha256:5e1e0a8600e2744127ef4bb5956fa84ae6bc1fc337c7b8726fabb7ca53e2d9b3,5466 - pantry-tree: - size: 1461 - sha256: f6215274a43addd339f8bc89f1ca0e8fdfb08180b13d779ae8f7e360acc4c473 - original: - hackage: esqueleto-3.2.3 -- completed: - hackage: HaskellNet-SSL-0.3.4.1@sha256:3ca14dd69460a380cf69aed40654fb10c4c03e344632b6a9986568c87feda157,1843 - pantry-tree: - size: 577 - sha256: 33fbfd0d8bbaa689f0169d442861dafcdcd4fe795a4b42aa0bedbfa41aa65b23 - original: - hackage: HaskellNet-SSL-0.3.4.1 + hackage: systemd-2.2.0 - completed: hackage: sandi-0.5@sha256:b278d072ca717706ea38f9bd646e023f7f2576a778fb43565b434f93638849aa,3010 pantry-tree: @@ -187,89 +194,12 @@ packages: original: hackage: storable-endian-0.2.6 - completed: - hackage: universe-1.2@sha256:23e7486709c06f6b0e048a505f0bd8b82a9c5d0937c8a13ca215ff20adde0a77,1448 - pantry-tree: - size: 292 - sha256: 15f7f0675229769705c128a397c06c41eb86909ff34ddb4c4c0f7d77becbe71b - original: - hackage: universe-1.2 -- completed: - hackage: universe-base-1.1.1@sha256:732e72a3597f834a01710c055d540cbc4174a8465015c1cdaaa542e9aeeadbd0,2476 - pantry-tree: - size: 465 - sha256: 165dbd1fa5eb81244b1ae2f9f527ebf4cc6d430911649347b33a92b97b377267 - original: - hackage: universe-base-1.1.1 -- completed: - hackage: universe-reverse-instances-1.1@sha256:9d46e98a81556a54c5be3346bc6e087cbd0036255eeb34cb28b3e59ab48646d3,1283 - pantry-tree: - size: 549 - sha256: 042fe63484542fa40a6071fad7c2930a85c569dce32280d5bc4b17e243b7cda4 - original: - hackage: universe-reverse-instances-1.1 -- completed: - hackage: unliftio-pool-0.2.1.0@sha256:4de658feb1b10051c5af024c20cd7baa369c777716c54a7b3e2888a73286aecf,922 - pantry-tree: - size: 217 - sha256: ddec03547e1feda7e861b49b2d1f2e188d41dc7bd04ae3d831f57d0813eb09a5 - original: - hackage: unliftio-pool-0.2.1.0 -- completed: - hackage: universe-instances-extended-1.1.1@sha256:6dfe9a7bbeb890a556c7f05ce3447ecd9e268e25a165ee233ad82ce76f91f327,1589 - pantry-tree: - size: 251 - sha256: 35972f6a95c04c018a0a634cc07f3c10c625e25e99e2f2b8090cebcf5f0292bd - original: - hackage: universe-instances-extended-1.1.1 -- completed: - hackage: universe-some-1.2@sha256:e232f660c1cc130c8492e7267868ef6b08d47c54949cdf5c54b8500e6a280e78,2106 - pantry-tree: - size: 299 - sha256: 921349682b8aa7c0ea294cd63d9f8521691cc6247b2520e0ab107c81a4aa1df5 - original: - hackage: universe-some-1.2 -- completed: - hackage: some-1.0.0.3@sha256:d4e7f7ef114b1ae01915fcff15a9b46a078d459e30791276a565f5c015128347,2020 - pantry-tree: - size: 708 - sha256: c2627940f4cf87189dc0cb967a048cabf3292a935efa292d5c1674af56e75a88 - original: - hackage: some-1.0.0.3 -- completed: - hackage: network-bsd-2.8.1.0@sha256:47cb03786ff5371876582babc72cbd88efbcb96053f5bfbefbc024fa80380bb3,3742 - pantry-tree: - size: 264 - sha256: 90120543a56cc76ccd841dcbb73e4725115af9ca428120cde906c1b3ca2e7c88 - original: - hackage: network-bsd-2.8.1.0 -- completed: - hackage: persistent-qq-2.9.1@sha256:1da17d907298ad5bc0798b0f759b59cb1bd4a4530681e0be54ad5366d7c5b1d5,1271 - pantry-tree: - size: 333 - sha256: e75333f07a956842811d48f267f596111b8aebd9ee5b50b9afe64c5efcb17c71 - original: - hackage: persistent-qq-2.9.1 -- completed: - hackage: process-1.6.5.1@sha256:77a9afeb676357f67fe5cf1ad79aca0745fb6f7fb96b786d510af08f622643f6,2468 - pantry-tree: - size: 1211 - sha256: 19d944da6aa37944332e0726372288319852e5f72aa57dbc3516dc15e760a502 - original: - hackage: process-1.6.5.1 -- completed: - hackage: generic-lens-1.2.0.0@sha256:b19e7970c93743a46bc3702331512a96d163de4356472f2d51a2945887aefe8c,6524 - pantry-tree: - size: 4315 - sha256: 9ed161eadfda5b1eb36cfcf077146f7b66db1da69f1041fc720aea287ec021b0 - original: - hackage: generic-lens-1.2.0.0 -- completed: - hackage: prometheus-metrics-ghc-1.0.0@sha256:0f4ecbefa810bd847e66c498ab3387bf21e426525a7c9a94841973c582719ba3,1231 + hackage: prometheus-metrics-ghc-1.0.1@sha256:d12cd520cbedff91bd193e0192056474723e953e69cdf817fb79494d110df390,1231 pantry-tree: size: 293 - sha256: 8a6d6ef3235ab980e867f64b712b5d38f1a84c3ac4920f5b4c3b3e63bcdf6ec9 + sha256: b412f2835ee5791a7f4f634c416227b70bae50511666d9f68683e5e21b5c2821 original: - hackage: prometheus-metrics-ghc-1.0.0 + hackage: prometheus-metrics-ghc-1.0.1 - completed: hackage: wai-middleware-prometheus-1.0.0@sha256:1625792914fb2139f005685be8ce519111451cfb854816e430fbf54af46238b4,1314 pantry-tree: @@ -277,13 +207,6 @@ packages: sha256: 6d64803c639ed4c7204ea6fab0536b97d3ee16cdecb9b4a883cd8e56d3c61402 original: hackage: wai-middleware-prometheus-1.0.0 -- completed: - hackage: extended-reals-0.2.3.0@sha256:78a498d703fffcecfba8e66cfb3e64c4307b2c126a442f6d28cfdd997829f1bf,1563 - pantry-tree: - size: 398 - sha256: 29629bb0ac41c49671b7f792e540165ee091eb24ffd0eaff229a2f40cc03f3af - original: - hackage: extended-reals-0.2.3.0 - completed: hackage: pandoc-2.9.2@sha256:fa04b214c79328a4519093a5e82fe961a21179539165b98773a6f8bfb66bc662,36181 pantry-tree: @@ -298,48 +221,6 @@ packages: sha256: ed2fc2dd826fbba67cb8018979be437b215735fab90dcc49ad30b296f7005eed original: hackage: doclayout-0.3 -- completed: - hackage: emojis-0.1@sha256:3cd86b552ad71c118a7822128c97054b6cf22bc4ff5b8f7e3eb0b356202aeecd,1907 - pantry-tree: - size: 426 - sha256: 0af0e5f0ba2af10a2eda8b96b41ff77d2229d90682c1220723a13b9582c4a41b - original: - hackage: emojis-0.1 -- completed: - hackage: hslua-module-system-0.2.1@sha256:7c498e51df885be5fd9abe9b762372ff4f125002824d8e11a7d5832154a7a1c3,2216 - pantry-tree: - size: 508 - sha256: 19a1e580174d2e02da4942887b2330804e8ceeed1ff4fd178a1bec4663e474ea - original: - hackage: hslua-module-system-0.2.1 -- completed: - hackage: ipynb-0.1@sha256:5b5240a9793781da557f82891d49cea63d71c8c5d3500fa3eac9fd702046b520,1926 - pantry-tree: - size: 812 - sha256: df171745ba4d6625eb71167a37237776cd10929994b05578b040592e2d5d5579 - original: - hackage: ipynb-0.1 -- completed: - hackage: jira-wiki-markup-1.0.0@sha256:24484791e650c80c452348e2523decc9a410aa965f79c0734c1e257f93b25cd1,3576 - pantry-tree: - size: 1178 - sha256: 60c39181a59a497be6c754e1cbf03461d9c4950bd4c523ca1efe1bd11e6f6b4f - original: - hackage: jira-wiki-markup-1.0.0 -- completed: - hackage: HsYAML-0.2.1.0@sha256:e4677daeba57f7a1e9a709a1f3022fe937336c91513e893166bd1f023f530d68,5311 - pantry-tree: - size: 1340 - sha256: 21f61bf9cad31674126b106071dd9b852e408796aeffc90eec1792f784107eff - original: - hackage: HsYAML-0.2.1.0 -- completed: - hackage: cmark-gfm-0.2.1@sha256:f49c10f6f1f8f41cb5d47e69ad6593dc45d2b28a083bbe22926d9f5bebf479b5,5191 - pantry-tree: - size: 4555 - sha256: 309d25e57e2c6d43834accc1f3a0f79150b9646f412957488d100e9cf7c37100 - original: - hackage: cmark-gfm-0.2.1 - completed: hackage: doctemplates-0.8.1@sha256:be34c3210d9ebbba1c10100e30d8c3ba3b6c34653ec2ed15f09e5d05055aa37d,3111 pantry-tree: @@ -347,44 +228,9 @@ packages: sha256: 9d4d8e7a85166ffd951b02f87be540607b55084c04730932346072329adf4913 original: hackage: doctemplates-0.8.1 -- completed: - hackage: haddock-library-1.8.0@sha256:293544a80c3d817a021fec69c430e808914a9d86db0c6bd6e96a386607a66627,3850 - pantry-tree: - size: 3397 - sha256: 2fb23fd09565829807a0368011cd57ea13e9a79fa4c65a47810aaf9a528427c2 - original: - hackage: haddock-library-1.8.0 -- completed: - hackage: pandoc-types-1.20@sha256:8393b1a73b8a6a1f3feaeb3a6592c176461082c3e4d897f1b316b1a58dd84c39,3999 - pantry-tree: - size: 855 - sha256: cdaa66d381a21406434e7a733c9b9291a3bc44b623e7a9f97ef335283770f3fa - original: - hackage: pandoc-types-1.20 -- completed: - hackage: skylighting-0.8.3.2@sha256:8b8573cd8820129a4c00675f52606f0f4c04c65d2e631e9e0e3d793cefdb534c,9730 - pantry-tree: - size: 10380 - sha256: cfe063d17444f6e12a8884cab7b2ec76afba9925be04155af605931793eac1f3 - original: - hackage: skylighting-0.8.3.2 -- completed: - hackage: skylighting-core-0.8.3.2@sha256:1f7cb6c8bb9299a83c50ae1f4b00d3808e27e4401807c530c8c3df956ad26d23,8058 - pantry-tree: - size: 13279 - sha256: 1cc0d70bd3f066bf8382206721a1e3854b78fbd067ece3d76ddbfc1c4e73fd2b - original: - hackage: skylighting-core-0.8.3.2 -- completed: - hackage: texmath-0.12.0.1@sha256:f68e0d01b34f53552deb506ba0b53b5cbba1bc5d87cc0d3de1bb5662d00ca5db,6569 - pantry-tree: - size: 274222 - sha256: 7bcd4a5c93f645b84fc93285e4868d7a418c66408f115710a73ad5370df9edc2 - original: - hackage: texmath-0.12.0.1 snapshots: - completed: - size: 498180 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/13/21.yaml - sha256: eff2de19a6d4691ccbf6edc1fba858f1918683047dce0f09adede874bbd2a8f3 - original: lts-13.21 + size: 488576 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/15/0.yaml + sha256: e4b6a87b47ec1cf63a7f1a0884a3b276fce2b0d174a10e8753c4f618e7983568 + original: lts-15.0 diff --git a/templates/course-participants.hamlet b/templates/course-participants.hamlet index ff5847746..53460bdda 100644 --- a/templates/course-participants.hamlet +++ b/templates/course-participants.hamlet @@ -4,4 +4,4 @@ $# $# participantTable : widget table ^{participantTable} -_{MsgCourseMembersCountOf (fromIntegral numParticipants) (courseCapacity course)}. +_{MsgCourseMembersCountOf numParticipants (courseCapacity course)}. diff --git a/test/Database.hs b/test/Database.hs index c9a362047..976bf95b1 100755 --- a/test/Database.hs +++ b/test/Database.hs @@ -14,15 +14,10 @@ import Control.Monad.Logger import System.Console.GetOpt import System.Exit (exitWith, ExitCode(..)) -import System.IO (hPutStrLn, stderr) - -import System.FilePath (()) +import System.IO (hPutStrLn) import qualified Data.ByteString as BS -import Utils.Lens (review, view) -import Control.Monad.Random.Class (MonadRandom(..)) - import qualified Data.Set as Set import Database.Persist.Sql.Raw.QQ diff --git a/test/Handler/ProfileSpec.hs b/test/Handler/ProfileSpec.hs index da8609703..280db8528 100644 --- a/test/Handler/ProfileSpec.hs +++ b/test/Handler/ProfileSpec.hs @@ -18,7 +18,7 @@ spec = withApp $ do assertHeader "Location" $ encodeUtf8 loginText - either (fail . unpack) (\_ -> return ()) =<< followRedirect + either (throwM . userError . unpack) (\_ -> return ()) =<< followRedirect statusIs 200 it "asserts access to my-account for authenticated users" $ do diff --git a/test/Handler/Utils/SubmissionSpec.hs b/test/Handler/Utils/SubmissionSpec.hs index 3e05115dc..ff2c1c22b 100644 --- a/test/Handler/Utils/SubmissionSpec.hs +++ b/test/Handler/Utils/SubmissionSpec.hs @@ -1,3 +1,5 @@ +{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} + module Handler.Utils.SubmissionSpec where import qualified Yesod diff --git a/test/Model/TypesSpec.hs b/test/Model/TypesSpec.hs index 3feef17be..2ac485593 100644 --- a/test/Model/TypesSpec.hs +++ b/test/Model/TypesSpec.hs @@ -5,7 +5,6 @@ module Model.TypesSpec where import TestImport import Settings -import Control.Lens (review, preview) import Data.Aeson (Value) import qualified Data.Aeson as Aeson import qualified Data.Aeson.Types as Aeson @@ -23,8 +22,6 @@ import Text.Blaze.Renderer.Text import qualified Data.Set as Set -import Time.Types (WeekDay(..)) - import qualified Net.IP as IP import Web.PathPieces @@ -211,9 +208,6 @@ instance Arbitrary Html where arbitrary = (preEscapedToHtml :: String -> Html) . getPrintableString <$> arbitrary shrink = map preEscapedToHtml . shrink . renderMarkup -instance Arbitrary WeekDay where - arbitrary = oneof $ map pure [minBound..maxBound] - instance Arbitrary OccurrenceSchedule where arbitrary = genericArbitrary shrink = genericShrink diff --git a/test/ModelSpec.hs b/test/ModelSpec.hs index 654156578..67196ba0a 100644 --- a/test/ModelSpec.hs +++ b/test/ModelSpec.hs @@ -1,4 +1,5 @@ {-# LANGUAGE UndecidableInstances #-} +{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-} module ModelSpec where diff --git a/test/TestImport.hs b/test/TestImport.hs index 3c9b42427..123e67a24 100644 --- a/test/TestImport.hs +++ b/test/TestImport.hs @@ -37,7 +37,7 @@ import Test.QuickCheck.Classes.Binary as X import Test.QuickCheck.Classes.Csv as X import Data.Proxy as X import Data.UUID as X (UUID) -import System.IO as X (hPrint, hPutStrLn, stderr) +import System.IO as X (hPrint, hPutStrLn) import Jobs (handleJobs) import Numeric.Natural as X