{-# options_ghc -XPatternSignatures -fno-monomorphism-restriction #-} module Controller where import Control.Monad import Control.Monad.Trans import Data.List import qualified Data.Map as M import qualified Data.Set as S import Data.Maybe import HAppS.Server import Misc import ControllerMisc import Text.StringTemplate import System.FilePath -- colorizing import System.Directory import Data.Char import qualified Language.Haskell.HsColour.HTML as HTML import Language.Haskell.HsColour.Colourise (readColourPrefs) -- state import StateStuff import ViewStuff import ControllerBasic import ControllerPostActions import ControllerGetActions import Debug.Trace --import Data.ByteString (pack,unpack) import Data.ByteString.Internal -- SPs: ServerParts -- main controller controller :: [ServerPartT IO Response] controller = {- debugFilter $ -} tutorial ++ simpleHandlers ++ [ myFavoriteAnimal ] ++ staticfiles ++ [ msgToSp "Quoth this server... 404." ] fileservedir d = dir d [ fileServe [] d ] tutorial :: [ServerPartT IO Response] tutorial = [ ServerPartT $ \rq -> do ts <- liftIO getTemplates mbUName <- liftIO . getmbLoggedInUser $ rq mbU <- case mbUName of Nothing -> return Nothing Just un -> query . GetUser $ un unServerPartT ( multi . tutorialCommon $ RenderGlobals ts mbU ) rq ] tutorialCommon :: RenderGlobals -> [ServerPartT IO Response] tutorialCommon rglobs = [ exactdir "/" [ ServerPartT $ \_ -> ( return . tutlayoutU rglobs [] ) "home" ] , dir "tutorial" [ dir "consultants" $ viewConsultants rglobs , dir "consultantswanted" $ viewConsultantsWanted rglobs , dir "jobs" [ methodSP GET . viewJobs $ rglobs] , dir "logout" [ (logoutPage rglobs)] , dir "changepassword" [ methodSP POST $ changePasswordSP rglobs ] , dir "editconsultantprofile" [ methodSP GET . viewEditConsultantProfile $ rglobs ] , dir "editconsultantprofile" [ methodSP POST . processformEditConsultantProfile $ rglobs ] , dir "editjob" [ methodSP GET . viewEditJobWD $ rglobs ] , dir "deletejob" [ methodSP GET . deleteJobWD $ rglobs ] , dir "editjob" [ methodSP POST . processformEditJob $ rglobs ] , dir "postnewjob" [ methodSP POST . processformNewJob $ rglobs ] , dir "myjobposts" [ methodSP GET . pageMyJobPosts $ rglobs ] , dir "viewprofile" [ methodSP GET . userProfile $ rglobs ] , dir "viewjob" [ methodSP GET . viewJob $ rglobs ] , dir "initializedummydata" [ spAddDummyData rglobs ] , dir "actions" $ [ dir "login" [ methodSP POST . loginPage $ rglobs ] , dir "newuser" [ methodSP POST . newUserPage $ rglobs ] ] , lastPathPartSp0 (\rq tmpl -> ( return . tutlayoutU rglobs []) tmpl ) ] ] viewConsultants :: RenderGlobals -> [ServerPartT IO Response] viewConsultants rglobs = [ ServerPartT $ \rq -> do consultants :: [String] <- return . map username =<< return . filter (consultant . consultantprofile) . S.toList =<< query AskDatastore let consultantlist = paintVMenu . map (\c -> simpleLink (templates rglobs) ("/tutorial/viewprofile?user="++c,c) ) $ consultants -- if not logged in, you get an invite to register as a consultant -- basically an incentive to register tmplattrs = maybe (def ++ [("registerAsConsultant","list yourself as a HAppS developer")]) (\_ -> def ) (mbUser rglobs) where def = [("consultantList", consultantlist)] return . tutlayoutU rglobs tmplattrs $ "consultants" ] viewConsultantsWanted :: RenderGlobals -> [ServerPartT IO Response] viewConsultantsWanted rglobs = [ ServerPartT $ \rq -> do consultantswanted :: [String] <- return . map username =<< return . filter (not . null . jobs) . S.toList =<< query AskDatastore let ulist = paintVMenu . map (\c -> simpleLink (templates rglobs) ("/tutorial/viewprofile?user="++c,c) ) $ consultantswanted -- an incentive to register tmplattrs = maybe (def ++ [("postJob","post a HAppS job")]) (\_ -> def ) (mbUser rglobs) where def = [("ulist", ulist)] return . tutlayoutU rglobs tmplattrs $ "consultantswanted" ] --logoutPage :: RenderGlobals -> ServerPartT IO Response logoutPage rglobs@(RenderGlobals ts mbU) = withRequest $ \rq -> do let mbSk = getMbSessKey rq newRGlobs <- maybe ( return rglobs ) ( \sk -> do update . DelSession $ sk return (RenderGlobals ts Nothing) ) mbSk ( return . tutlayoutU newRGlobs [] ) "home" spAddDummyData rglobs = do withRequest $ \rq -> (update InitializeDummyData) ( return . tutlayoutU rglobs [] ) "home" staticfiles = [ haskellFile [withRequest colorize] , fileservedir "src" , fileservedir "static" ] where -- Takes the request and tries to find a file from the current directory -- based on the request path. Colorizes the file as Haskell and returns the -- HTML. colorize rq = do currDir <- liftIO $ getCurrentDirectory let sep = [pathSeparator] -- eg '/' or '\' or whatever path = intercalate sep ([currDir ++ sep ] ++ rqPaths rq) file <- liftIO $ readFile path prefs <- liftIO $ readColourPrefs let color :: String color = HTML.hscolour prefs False False file return . toResponse . HtmlString $ color -- Detects if a request ends in a .hs. haskellFile = spsIf endsInHS where endsInHS rq = let url = rqURL rq extension = drop (length url - 3) url in extension == ".hs"