-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMain.hs
More file actions
203 lines (179 loc) · 8.99 KB
/
Copy pathMain.hs
File metadata and controls
203 lines (179 loc) · 8.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
{-# LANGUAGE NoMonomorphismRestriction, OverloadedStrings,CPP, DeriveDataTypeable, FlexibleContexts, GeneralizedNewtypeDeriving,
MultiParamTypeClasses, ScopedTypeVariables, TemplateHaskell, TypeFamilies, RecordWildCards #-}
module Main where
import Auth
import Commands
import Control.Exception ( bracket )
import Control.Monad (msum,mapM_,forM_,forM)
import Control.Monad.Trans (lift, liftIO)
import Data.Acid ( AcidState, Query, Update, openLocalState )
import Data.Acid.Advanced ( query', update' )
import Data.Acid.Local ( createCheckpointAndClose )
import Data.SafeCopy ( base, deriveSafeCopy )
import Data.Tree
import DiagramWrapper
import Happstack.Server (addCookie, asContentType, BodyPolicy(..)
, Browsing(EnableBrowsing), CookieLife(Session)
, decodeBody, defaultBodyPolicy, dir, expireCookie
, Method(POST), methodM, mkCookie, nullConf
, ok, readCookieValue, Response, serveDirectory
, ServerPart, simpleHTTP, toResponse)
import Happstack.Server.RqData (RqData, checkRq, getDataFn, look, lookRead)
import KnuthBendixCompletion.Algorithm
import KnuthBendixCompletion.Datatypes
import KnuthBendixCompletion.Tests
import Parser
import ParserTests
import Persistance
import ResponseTemplates
import Text.Blaze as B
import Text.Blaze.Html4.Strict as B hiding (map)
import Text.Blaze.Html4.Strict.Attributes as B hiding (dir, label, title)
import System.Random
main :: IO ()
main =
do bracket (openLocalState initialAppStatus)
(createCheckpointAndClose)
(\acid ->
simpleHTTP nullConf (handlers acid))
myPolicy :: BodyPolicy
myPolicy = (defaultBodyPolicy "/tmp/" 0 1000 1000)
handlers :: AcidState AppStatus -> ServerPart Response
handlers acid =
do decodeBody myPolicy
msum [dir "login" $ logInUserResultPart
,dir "logout" $ logOutUserResultPart
,dir "app" $ dispatchPostCommand acid
,dir "list" $ listUsers acid
,dir "img" $ serveDirectory EnableBrowsing [] "img"
]
dispatchPostCommand :: AcidState AppStatus -> ServerPart Response
dispatchPostCommand acid =
do methodM POST
c <- getDataFn (look "command" `checkRq` eitherize)
case c of
(Left e) -> (ok $ toResponse $ show (unlines e))
(Right LogIn) -> (authenticate acid)
(Right LogOut) -> (deauthenticate acid)
(Right c) -> do hashValue::String <- readCookieValue "hash"
isLogged <- query' acid (CheckHashUser (SessionHash hashValue))
case isLogged of
UserIsNotLogged -> ok $ toResponse (show "No such user")
UserIsLogged -> generateResult acid c (SessionHash hashValue)
where
eitherize :: String -> Either String Command
eitherize "LogIn" = Right LogIn
eitherize "LogOut" = Right LogOut
eitherize "RunAlgorithm" = Right RunAlgorithm
eitherize "AddAxiom" = Right AddAxiom
eitherize "AddRule" = Right AddRule
eitherize "RemoveAxiom" = Right RemoveAxiom
eitherize "RemoveRule" = Right RemoveRule
eitherize "RemoveAllAxioms" = Right RemoveAllAxioms
eitherize "RemoveAllRules" = Right RemoveAllRules
eitherize "Reset" = Right Reset
eitherize r = Left r
generateResult :: AcidState AppStatus -> Command -> SessionHash -> ServerPart Response
generateResult acid c sh =
case c of
RunAlgorithm -> do result <- update' acid (UpdateAlgorithmStatusByKBC sh)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
AddAxiom -> do postedAxiom <- getDataFn (look "axiom" `checkRq` (convertError.parseAxiom))
case postedAxiom of
(Left error) -> (ok $ toResponse $ (show error))
(Right axiom) -> do result <- update' acid (UpdateAlgorithmStatusByAddingAxiom sh axiom)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
AddRule -> do postedRule <- getDataFn (look "rule" `checkRq` (convertError.parseReductionRule))
case postedRule of
(Left error) -> (ok $ toResponse $ (show error))
(Right rule) -> do result <- update' acid (UpdateAlgorithmStatusByAddingRule sh rule)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
RemoveRule -> do postedIndex <- getDataFn (lookRead "index")
case postedIndex of
(Left error) -> (ok $ toResponse $ (show error))
(Right index) -> do result <- update' acid (UpdateAlgorithmStatusByRemovingRule sh index)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
RemoveAxiom -> do postedIndex <- getDataFn (lookRead "index")
case postedIndex of
(Left error) -> (ok $ toResponse $ (show error))
(Right index) -> do result <- update' acid (UpdateAlgorithmStatusByRemovingAxiom sh index)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
RemoveAllAxioms ->do result <- update' acid (UpdateAlgorithmStatusByRemovingAxioms sh)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
RemoveAllRules ->do result <- update' acid (UpdateAlgorithmStatusByRemovingRules sh)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
Reset-> do result <- update' acid (UpdateAlgorithmStatusByDefaultReset sh)
case result of
Just r -> showStatus r
Nothing -> ok $ toResponse (show "Nothing")
authenticate :: AcidState AppStatus -> ServerPart Response
authenticate acid =
do methodM POST
l <- look "login"
p <- look "password"
x <- liftIO (getStdRandom (randomR (1,65536)))
result <- update' acid (LogInUser l p (SessionHash (l++show (x::Integer))))
case result of
SuccesfulLogIn sh -> do
addCookie Session (mkCookie "hash" (hash sh))
menuResultPart
NoSuchUser -> ok $ toResponse (show "No such user")
WrongPassword -> ok $ toResponse (show "Wrong password")
deauthenticate :: AcidState AppStatus -> ServerPart Response
deauthenticate acid =
do hashValue::String <- readCookieValue "hash"
result <- update' acid (LogOutUser (SessionHash hashValue))
case result of
SuccesfulLogOut -> do
expireCookie "hash"
ok $ toResponse (show "User logged out")
NoSuchSessionHash -> ok $ toResponse (show "No user was logged with this cookie "++(show (SessionHash hashValue)))
listUsers :: AcidState AppStatus -> ServerPart Response
listUsers acid =
do status <- query' acid PeekAppStatus
ok $ toResponse $ "peeked and saw: " ++ show (map (\u -> (login u, password u,session u)) (users status))
translateName :: String -> String
translateName name = "img/"++name++".png"
showStatus :: AlgorithmStatus -> ServerPart Response
showStatus (CanProceed as rs) =
do axiomsFilenames <- mapM generateAxiomAsImage (numberize as)
rulesFilenames <- mapM generateRuleAsImage (numberize rs)
canProceedTemplate axiomsFilenames rulesFilenames
showStatus (Finished rs) =
do rulesFilenames <- mapM generateRuleAsImage (numberize rs)
finishedTemplate rulesFilenames
showStatus (FailedOn failedAxiom as rs)=
do failedAxiomFile <- generateAxiomAsImage (failedAxiom,0)
axiomsFilenames <- mapM generateAxiomAsImage (numberize as)
rulesFilenames <- mapM generateRuleAsImage (numberize rs)
failedOnTemplate failedAxiomFile axiomsFilenames rulesFilenames
numberize xs = n xs 0
where
n [] _ = []
n (x:xs) acc = (x,acc): n xs (acc+1)
randomFilename =
do x <- liftIO (getStdRandom (randomR (1,65536)))
let filename = (translateName (show (x::Integer)))
return filename
generateAxiomAsImage (axiom,index) =
do filename <- randomFilename
liftIO $ (generateAxiomDiagram filename axiom)
return $ (filename,index)
generateRuleAsImage (rule,index) =
do filename <- randomFilename
liftIO $ generateReductionRuleDiagram filename rule
return $ (filename,index)