diff --git a/config/personalised-sheet-files-collate b/config/personalised-sheet-files-collate new file mode 100644 index 000000000..a068bc5a1 --- /dev/null +++ b/config/personalised-sheet-files-collate @@ -0,0 +1,21 @@ +$# Syntax: +$# - Leere zeilen werden ignoriert +$# - Zeilen, die mit '$#' beginnen, werden ignoriert +$# - Verbleibende Zeilen werden jeweils als `Glob`-Pattern kompiliert + +$# Ignoriere rekursiv alle Ordner __MACOSX und ihren Inhalt +**/__MACOSX +**/__MACOSX/* +**/__MACOSX/**/* + +$# Ignoriere rekursiv alle Dateien .DS_Store (Mac OS) +**/.DS_Store + +$# Ignoriere VI-Style-Backup-Files +**/*~ +$# Ignoriere Emacs-Style-Backup-Files +**/.#*# + +$# Ignoriere exportierte meta-informationen.yaml +**/meta-informationen_*.yaml +**/meta-information_*.yaml \ No newline at end of file diff --git a/messages/uniworx/en-eu.msg b/messages/uniworx/en-eu.msg index 192c8a8d6..5ab56356b 100644 --- a/messages/uniworx/en-eu.msg +++ b/messages/uniworx/en-eu.msg @@ -2668,6 +2668,8 @@ SubmissionDoneAlways: Always CorrUploadSubmissionDoneMode: Rating finished CorrUploadSubmissionDoneModeTip: Should uploaded corrections be marked as finished? The rating is only visible to the submittors and considered for any exam bonuses if it is finished. +PersonalisedSheetFilesMetaFilename uid: meta-information_#{toPathPiece uid}.yaml + AdminCrontabNotGenerated: Crontab not (yet) generated CronMatchAsap: ASAP CronMatchNone: Never diff --git a/src/Handler/Sheet/PersonalisedFiles.hs b/src/Handler/Sheet/PersonalisedFiles.hs index 4ff2c00e4..5c5885df8 100644 --- a/src/Handler/Sheet/PersonalisedFiles.hs +++ b/src/Handler/Sheet/PersonalisedFiles.hs @@ -44,6 +44,7 @@ import Text.Unidecode (unidecode) import Data.Char (isAlphaNum) import qualified System.FilePath as FilePath (joinPath) +import System.FilePath.Glob import Control.Monad.Trans.State.Strict (StateT, runStateT) import qualified Control.Monad.State as State @@ -101,10 +102,14 @@ resolvePersonalisedSheetFiles fpL isDir cid sid = do Just (uid, sfType, fPath) -> PersonalisedSheetFileResidual sid uid sfType <$ (fpL .= fPath) Nothing -> do isDirectory <- State.gets isDir + fPath <- use fpL if | isDirectory -> lift $ throwE PSFUnresolvedDirectory + | lstPtn : _ <- Map.keys $ Map.filter (`match'` fPath) personalisedSheetFilesCollatable + -> lift . throwE $ PSFUnresolvedCollatable lstPtn | otherwise -> lift $ throwE PSFUnresolved + where match' = matchWith $ matchDefault { matchDotsImplicitly = True } sinkPersonalisedSheetFiles :: forall m. diff --git a/src/Handler/Utils/Submission/TH.hs b/src/Handler/Utils/Submission/TH.hs deleted file mode 100644 index 14504b6cf..000000000 --- a/src/Handler/Utils/Submission/TH.hs +++ /dev/null @@ -1,31 +0,0 @@ -{-# OPTIONS_GHC -fno-warn-orphans #-} - -module Handler.Utils.Submission.TH - ( patternFile - ) where - -import ClassyPrelude.Yesod -import Language.Haskell.TH -import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..)) - -import System.FilePath.Glob - -import qualified Data.Text as Text -import qualified Data.Text.IO as Text - -deriving instance Lift CompOptions - --- $(patternFile compDefault file) :: [System.FilePath.Glob.Pattern] -patternFile :: CompOptions -> FilePath -> ExpQ -patternFile opts file = do - qAddDependentFile file - patternStrings <- runIO $ filter (not . isComment) . Text.lines <$> Text.readFile file - listE $ map (\(Text.unpack -> pat) -> [|compileWith opts pat|]) patternStrings - -isComment :: Text -> Bool -isComment line = or - [ commentSymbol `Text.isPrefixOf` Text.stripStart line - , Text.null $ Text.strip line - ] - where - commentSymbol = "$#" diff --git a/src/Settings.hs b/src/Settings.hs index 39b31d630..e5d22fb26 100644 --- a/src/Settings.hs +++ b/src/Settings.hs @@ -61,7 +61,7 @@ import qualified System.FilePath as FilePath import Jose.Jwt (JwtEncoding(..)) import System.FilePath.Glob -import Handler.Utils.Submission.TH +import System.FilePath.Glob.TH import qualified Web.ServerSession.Core as ServerSession @@ -543,7 +543,10 @@ widgetFileSettings = def submissionBlacklist :: [Pattern] -submissionBlacklist = $(patternFile compDefault "config/submission-blacklist") +submissionBlacklist = $$(patternFile compDefault "config/submission-blacklist") + +personalisedSheetFilesCollatable :: Map Text Pattern +personalisedSheetFilesCollatable = $$(patternFile' compDefault "config/personalised-sheet-files-collate") -- The rest of this file contains settings which rarely need changing by a -- user. diff --git a/src/System/FilePath/Glob/TH.hs b/src/System/FilePath/Glob/TH.hs new file mode 100644 index 000000000..6df102254 --- /dev/null +++ b/src/System/FilePath/Glob/TH.hs @@ -0,0 +1,35 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} + +module System.FilePath.Glob.TH + ( patternFile, patternFile' + ) where + +import ClassyPrelude.Yesod +import Language.Haskell.TH +import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..), unsafeTExpCoerce) + +import System.FilePath.Glob + +import qualified Data.Text as Text +import qualified Data.Text.IO as Text + +import qualified Data.Map.Strict as Map + +deriving instance Lift CompOptions + +patternFile' :: CompOptions -> FilePath -> TExpQ (Map Text Pattern) +patternFile' opts file = do + qAddDependentFile file + patternStrings <- runIO $ filter (not . isComment) . Text.lines <$> Text.readFile file + unsafeTExpCoerce . appE [e|Map.fromList|] . listE $ map (\pat'@(Text.unpack -> pat) -> [e|(pat', compileWith opts pat)|]) patternStrings + +patternFile :: CompOptions -> FilePath -> TExpQ [Pattern] +patternFile opts file = [||Map.elems $$(patternFile' opts file)||] + +isComment :: Text -> Bool +isComment line = or + [ commentSymbol `Text.isPrefixOf` Text.stripStart line + , Text.null $ Text.strip line + ] + where + commentSymbol = "$#"