Return existing in SPseudonymR

This commit is contained in:
Gregor Kleen 2018-10-15 08:44:12 +02:00
parent 4266683b15
commit 8e28c397fd
4 changed files with 46 additions and 7 deletions

2
routes
View File

@ -80,7 +80,7 @@
/correction CorrectionR GET POST !corrector !ownerANDisReadANDrated
!/#SubmissionFileType/*FilePath SubDownloadR GET !owner
/correctors SCorrR GET POST
/pseudonym SPseudonymR POST !registeredANDcorrector-submissions
/pseudonym SPseudonymR GET POST !registeredANDcorrector-submissions
!/#SheetFileType/*FilePath SFileR GET !timeANDregistered !timeANDmaterials !corrector

View File

@ -49,6 +49,8 @@ import Control.Monad.Writer (MonadWriter(..), execWriterT)
-- import qualified Data.List as List
import Control.Monad.Trans.Except (ExceptT(..), runExceptT, mapExceptT, throwE)
import Network.Mime
import Data.Set (Set)
@ -346,22 +348,28 @@ getSShowR tid ssh csh shn = do
$(widgetFile "sheetShow")
postSPseudonymR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler TypedContent
getSPseudonymR = postSPseudonymR
postSPseudonymR tid ssh csh shn = do
uid <- requireAuthId
shId <- runDB $ fetchSheetId tid ssh csh shn
let
genPseudonym = do
inserted <- runDB . setSerializable $ do
inserted <- runExceptT . mapExceptT (runDB . setSerializable) $ do
candidate <- liftIO getRandom
fmap (const candidate) <$> insertUnique (SheetPseudonym shId candidate uid)
existing <- lift . getBy $ UniqueSheetPseudonymUser shId uid
case existing of
Just (Entity _ SheetPseudonym{sheetPseudonymPseudonym}) -> throwE sheetPseudonymPseudonym
Nothing
-> lift $ fmap (const candidate) <$> insertUnique (SheetPseudonym shId candidate uid)
case inserted of
Nothing -> genPseudonym
Just ps -> return ps
Right Nothing -> genPseudonym
Right (Just ps) -> return ps
Left ps -> return ps
ps <- genPseudonym
let ps' = Text.unwords . map CI.original $ review pseudonymWords ps
selectRep $ do
provideRep $ return ps'
provideRep . return $ Aeson.String ps'
provideJson ps
provideRep (redirect $ CSheetR tid ssh csh shn SShowR :: Handler Html)

View File

@ -13,6 +13,7 @@ import Yesod.Auth as Import
import Yesod.Core.Types as Import (loggerSet)
import Yesod.Default.Config2 as Import
import Utils as Import
import Yesod.Core.Json as Import (provideJson)
import Data.Fixed as Import

View File

@ -9,6 +9,7 @@
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE MultiWayIf #-}
{-- # LANGUAGE ExistentialQuantification #-} -- for DA type
{-# OPTIONS_GHC -fno-warn-orphans #-} -- for instance PathPiece (CI Text)
@ -541,7 +542,14 @@ newtype Pseudonym = Pseudonym Word24
instance PersistField Pseudonym where
toPersistValue p = toPersistValue (fromIntegral p :: Word32)
fromPersistValue = fmap (fromIntegral :: Word32 -> Pseudonym) . fromPersistValue
fromPersistValue v = do
w <- fromPersistValue v :: Either Text Word32
if
| 0 <= w
, w <= fromIntegral (maxBound :: Pseudonym)
-> return $ fromIntegral w
| otherwise
-> Left "Pseudonym out of range"
instance PersistFieldSql Pseudonym where
sqlType _ = SqlInt32
@ -550,6 +558,28 @@ instance Random Pseudonym where
randomR (max minBound -> lo, min maxBound -> hi) gen = over _1 (fromIntegral :: Word32 -> Pseudonym) $ randomR (fromIntegral lo, fromIntegral hi) gen
random = randomR (minBound, maxBound)
instance FromJSON Pseudonym where
parseJSON v@(Aeson.Number _) = do
w <- parseJSON v :: Aeson.Parser Word32
if
| 0 <= w
, w <= fromIntegral (maxBound :: Pseudonym)
-> return $ fromIntegral w
| otherwise
-> fail "Pseudonym out auf range"
parseJSON (Aeson.String (map CI.mk . Text.words -> ws))
= case preview pseudonymWords ws of
Just p -> return p
Nothing -> fail "Could not parse pseudonym"
parseJSON v = flip (Aeson.withArray "Pseudonym") v $ \ws -> do
ws' <- toList . map CI.mk <$> mapM parseJSON ws
case preview pseudonymWords ws' of
Just p -> return p
Nothing -> fail "Could not parse pseudonym words"
instance ToJSON Pseudonym where
toJSON = toJSON . (review pseudonymWords :: Pseudonym -> [CI Text])
pseudonymWordlist :: [CI Text]
pseudonymWordlist = $(wordlist "config/wordlist.txt")