2014-08-09 18:33:22 +00:00
|
|
|
module Foundation where
|
|
|
|
|
|
|
|
import Prelude
|
|
|
|
import Yesod
|
|
|
|
import Yesod.Static
|
2014-08-12 12:37:31 +00:00
|
|
|
-- import Yesod.Auth
|
|
|
|
-- import Yesod.Auth.BrowserId
|
2014-08-09 18:33:22 +00:00
|
|
|
import Yesod.Default.Config
|
|
|
|
import Yesod.Default.Util (addStaticContentExternal)
|
|
|
|
import Network.HTTP.Client.Conduit (Manager, HasHttpManager (getHttpManager))
|
|
|
|
import qualified Settings
|
|
|
|
import Settings.Development (development)
|
|
|
|
import qualified Database.Persist
|
|
|
|
import Database.Persist.Sql (SqlPersistT)
|
|
|
|
import Settings.StaticFiles
|
|
|
|
import Settings (widgetFile, Extra (..))
|
2014-08-12 16:14:59 +00:00
|
|
|
import Model
|
2014-08-09 18:33:22 +00:00
|
|
|
import Text.Jasmine (minifym)
|
|
|
|
import Text.Hamlet (hamletFile)
|
|
|
|
import Yesod.Core.Types (Logger)
|
2014-08-12 16:14:59 +00:00
|
|
|
-- costom imports
|
2014-08-12 21:45:33 +00:00
|
|
|
import Data.Text
|
2014-08-15 11:24:14 +00:00
|
|
|
import Helper
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- | The site argument for your application. This can be a good place to
|
|
|
|
-- keep settings and values requiring initialization before your application
|
|
|
|
-- starts running, such as database connections. Every handler will have
|
|
|
|
-- access to the data present here.
|
|
|
|
data App = App
|
|
|
|
{ settings :: AppConfig DefaultEnv Extra
|
|
|
|
, getStatic :: Static -- ^ Settings for static file serving.
|
|
|
|
, connPool :: Database.Persist.PersistConfigPool Settings.PersistConf -- ^ Database connection pool.
|
|
|
|
, httpManager :: Manager
|
|
|
|
, persistConfig :: Settings.PersistConf
|
|
|
|
, appLogger :: Logger
|
|
|
|
}
|
|
|
|
|
|
|
|
instance HasHttpManager App where
|
|
|
|
getHttpManager = httpManager
|
|
|
|
|
|
|
|
-- Set up i18n messages. See the message folder.
|
|
|
|
mkMessage "App" "messages" "en"
|
|
|
|
|
|
|
|
-- This is where we define all of the routes in our application. For a full
|
|
|
|
-- explanation of the syntax, please see:
|
|
|
|
-- http://www.yesodweb.com/book/routing-and-handlers
|
|
|
|
--
|
|
|
|
-- Note that this is really half the story; in Application.hs, mkYesodDispatch
|
|
|
|
-- generates the rest of the code. Please see the linked documentation for an
|
|
|
|
-- explanation for this split.
|
|
|
|
mkYesodData "App" $(parseRoutesFile "config/routes")
|
|
|
|
|
|
|
|
type Form x = Html -> MForm (HandlerT App IO) (FormResult x, Widget)
|
|
|
|
|
|
|
|
-- Please see the documentation for the Yesod typeclass. There are a number
|
|
|
|
-- of settings which can be configured by overriding methods here.
|
|
|
|
instance Yesod App where
|
|
|
|
approot = ApprootMaster $ appRoot . settings
|
|
|
|
|
2014-09-03 22:19:07 +00:00
|
|
|
-- change maximum content length
|
|
|
|
maximumContentLength _ _ = Just $ 1024 ^ 5
|
|
|
|
|
2014-08-09 18:33:22 +00:00
|
|
|
-- Store session data on the client in encrypted cookies,
|
|
|
|
-- default session idle timeout is 120 minutes
|
|
|
|
makeSessionBackend _ = fmap Just $ defaultClientSessionBackend
|
|
|
|
120 -- timeout in minutes
|
|
|
|
"config/client_session_key.aes"
|
|
|
|
|
|
|
|
defaultLayout widget = do
|
|
|
|
master <- getYesod
|
|
|
|
mmsg <- getMessage
|
2014-08-13 20:30:48 +00:00
|
|
|
msu <- lookupSession "userId"
|
2014-08-15 13:41:25 +00:00
|
|
|
username <- case msu of
|
|
|
|
Just a -> do
|
|
|
|
uId <- return $ getUserIdFromText a
|
|
|
|
user <- runDB $ getJust uId
|
|
|
|
return $ userName user
|
2014-08-17 20:59:55 +00:00
|
|
|
Nothing -> do
|
2014-08-15 13:41:25 +00:00
|
|
|
return ("" :: Text)
|
2014-08-26 02:36:21 +00:00
|
|
|
slug <- case msu of
|
|
|
|
Just a -> do
|
|
|
|
uId <- return $ getUserIdFromText a
|
|
|
|
user <- runDB $ getJust uId
|
|
|
|
return $ userSlug user
|
|
|
|
Nothing -> do
|
|
|
|
return ("" :: Text)
|
2014-08-15 13:41:25 +00:00
|
|
|
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- We break up the default layout into two components:
|
|
|
|
-- default-layout is the contents of the body tag, and
|
|
|
|
-- default-layout-wrapper is the entire page. Since the final
|
|
|
|
-- value passed to hamletToRepHtml cannot be a widget, this allows
|
|
|
|
-- you to use normal widget features in default-layout.
|
|
|
|
|
|
|
|
pc <- widgetToPageContent $ do
|
|
|
|
$(combineStylesheets 'StaticR
|
|
|
|
[ css_normalize_css
|
|
|
|
, css_bootstrap_css
|
|
|
|
])
|
|
|
|
$(widgetFile "default-layout")
|
|
|
|
giveUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
|
|
|
|
|
|
|
|
-- This is done to provide an optimization for serving static files from
|
|
|
|
-- a separate domain. Please see the staticRoot setting in Settings.hs
|
|
|
|
urlRenderOverride y (StaticR s) =
|
|
|
|
Just $ uncurry (joinPath y (Settings.staticRoot $ settings y)) $ renderRoute s
|
|
|
|
urlRenderOverride _ _ = Nothing
|
|
|
|
|
|
|
|
-- The page to be redirected to when authentication is required.
|
2014-08-12 12:37:31 +00:00
|
|
|
-- authRoute _ = Just $ AuthR LoginR
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- This function creates static content files in the static folder
|
|
|
|
-- and names them based on a hash of their content. This allows
|
|
|
|
-- expiration dates to be set far in the future without worry of
|
|
|
|
-- users receiving stale content.
|
|
|
|
addStaticContent =
|
|
|
|
addStaticContentExternal minifym genFileName Settings.staticDir (StaticR . flip StaticRoute [])
|
|
|
|
where
|
|
|
|
-- Generate a unique filename based on the content itself
|
|
|
|
genFileName lbs
|
|
|
|
| development = "autogen-" ++ base64md5 lbs
|
|
|
|
| otherwise = base64md5 lbs
|
|
|
|
|
|
|
|
-- Place Javascript at bottom of the body tag so the rest of the page loads first
|
|
|
|
jsLoader _ = BottomOfBody
|
|
|
|
|
|
|
|
-- What messages should be logged. The following includes all messages when
|
|
|
|
-- in development, and warnings and errors in production.
|
|
|
|
shouldLog _ _source level =
|
|
|
|
development || level == LevelWarn || level == LevelError
|
|
|
|
|
|
|
|
makeLogger = return . appLogger
|
|
|
|
|
|
|
|
-- How to run database actions.
|
|
|
|
instance YesodPersist App where
|
|
|
|
type YesodPersistBackend App = SqlPersistT
|
|
|
|
runDB = defaultRunDB persistConfig connPool
|
|
|
|
instance YesodPersistRunner App where
|
|
|
|
getDBRunner = defaultGetDBRunner connPool
|
|
|
|
|
2014-08-12 12:37:31 +00:00
|
|
|
-- instance YesodAuth App where
|
|
|
|
-- type AuthId App = UserId
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- Where to send a user after successful login
|
2014-08-12 12:37:31 +00:00
|
|
|
-- loginDest _ = HomeR
|
2014-08-09 18:33:22 +00:00
|
|
|
-- Where to send a user after logout
|
2014-08-12 12:37:31 +00:00
|
|
|
-- logoutDest _ = HomeR
|
|
|
|
|
|
|
|
-- getAuthId creds = runDB $ do
|
|
|
|
-- x <- getBy $ UniqueUser $ credsIdent creds
|
|
|
|
-- case x of
|
|
|
|
-- Just (Entity uid _) -> return $ Just uid
|
|
|
|
-- Nothing -> do
|
|
|
|
-- fmap Just $ insert User
|
|
|
|
-- { userIdent = credsIdent creds
|
|
|
|
-- , userPassword = Nothing
|
|
|
|
-- }
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- You can add other plugins like BrowserID, email or OAuth here
|
2014-08-12 12:37:31 +00:00
|
|
|
-- authPlugins _ = [authBrowserId def]
|
2014-08-09 18:33:22 +00:00
|
|
|
|
2014-08-12 12:37:31 +00:00
|
|
|
-- authHttpManager = httpManager
|
2014-08-09 18:33:22 +00:00
|
|
|
|
|
|
|
-- This instance is required to use forms. You can modify renderMessage to
|
|
|
|
-- achieve customized and internationalized form validation messages.
|
|
|
|
instance RenderMessage App FormMessage where
|
|
|
|
renderMessage _ _ = defaultFormMessage
|
|
|
|
|
|
|
|
-- | Get the 'Extra' value, used to hold data from the settings.yml file.
|
|
|
|
getExtra :: Handler Extra
|
|
|
|
getExtra = fmap (appExtra . settings) getYesod
|
|
|
|
|
|
|
|
-- Note: previous versions of the scaffolding included a deliver function to
|
|
|
|
-- send emails. Unfortunately, there are too many different options for us to
|
|
|
|
-- give a reasonable default. Instead, the information is available on the
|
|
|
|
-- wiki:
|
|
|
|
--
|
|
|
|
-- https://github.com/yesodweb/yesod/wiki/Sending-email
|