!
, - , - . WebM
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell, QuasiQuotes, FlexibleContexts #-}
module Main where
import Prelude
import Yesod
import Data.Text
import Yesod.Form
import System.Random
import Data.Maybe
main :: IO ()
main = warp 3000 Captcha
data Captcha = Captcha
instance Yesod Captcha
instance RenderMessage Captcha FormMessage where
renderMessage _ _ = defaultFormMessage
mkYesod "Captcha" [parseRoutes|
/ HomeR GET POST
|]
data MathEquation = Math {x :: Int, y :: Int, result :: Int, function :: Char}
maybeRead :: Read a => String -> Maybe a
maybeRead (reads -> [(x,"")]) = Just x
maybeRead _ = Nothing
maybeInt :: String -> Maybe Int
maybeInt = maybeRead
createMathEq :: IO (MathEquation)
createMathEq = do
a <- randomRIO (0 :: Int, 100 :: Int)
b <- randomRIO (0 :: Int, 100 :: Int)
f' <- randomRIO (0 :: Int, 2 :: Int)
let (f, fs) = case f' of
0 -> ((+),'+')
1 -> ((-),'-')
_ -> ((*),'*')
r = f a b
return $ Math a b r fs
randomMForm :: MathEquation -> Html -> MForm Handler (FormResult Int, Widget)
randomMForm (Math x y res fs) token = do
(iResult, iView) <- mreq intField "" Nothing
let widget = [whamlet|
^{token}
Should be: #{show res}
<input type=submit value="Submit">
<br>
|]
return (iResult, widget)
getHomeR :: Handler Html
getHomeR = do
equation <- liftIO $ createMathEq
setSession "captcha" (pack $ show $ result equation)
(widget, enctype) <-generateFormPost $ randomMForm equation
defaultLayout [whamlet|
<form method=post enctype=#{enctype}>
^{widget}
|]
postHomeR :: Handler Html
postHomeR = do
equation <- liftIO $ createMathEq
mText <- lookupSession "captcha"
((res,widget), enctype) <- runFormPost $ randomMForm equation
case (res, mText) of
(FormSuccess i, (Just captcha)) -> case ((Just i) == (maybeInt (unpack captcha))) of
True -> do
setSession "captcha" (pack $ show $ result equation)
defaultLayout [whamlet|
<p> You entered the right int: #{show i}
<a href=@{HomeR}> Get back!
|]
False -> do
setSession "captcha" (pack $ show $ result equation)
defaultLayout [whamlet|
<p> Error: Sorry, the input doesn't match
<form method=post enctype=#{enctype}>
^{widget}
<a href=@{HomeR}> Get back!
|]
(FormFailure (err:_), _) -> do
setSession "captcha" (pack $ show $ result equation)
defaultLayout [whamlet|
<p> Error: #{err}
<form method=post enctype=#{enctype}>
^{widget}
<a href=@{HomeR}> Get back!
|]
(_, _) -> do
setSession "captcha" (pack $ show $ result equation)
defaultLayout [whamlet|
<p> Total error!
<form method=post enctype=#{enctype}>
^{widget}
<a href=@{HomeR}> Get back!
|]