content: -- When I wrote the first version of Vocabulink, many functions passed around a
  -- database connection. Next, I understood how to use monad transformers and
  -- rolled in a Reader. But everything ended up in a monad, so now I'm taking a
  -- simpler (if potentially unsafe) approach.
  
  module Vocabulink.Env ( E
                        , compileYear, staticManifest
                        , withVerifiedMember, withLoggedInMember
                        ) where
  
  import Vocabulink.Member
  import Vocabulink.Utils
  
  import Database.PostgreSQL.Typed (PGConnection)
  import Language.Haskell.TH.Syntax (runIO, Exp(..), Lit(..))
  import System.Environment (getEnv)
  
  type E a = (?db::PGConnection, ?static::FilePath, ?tokenKey::String, ?member::Maybe Member, ?sendmail::FilePath, ?referrer::(Maybe String)) => a
  
  compileYear :: Int
  compileYear = $((LitE . IntegerL) `liftM` runIO currentYear)
  
  staticManifest :: [(FilePath, String)]
  staticManifest = $(runIO (do man <- manifest =<< getEnv "MANIFEST"
                               return $ ListE $ map (\ [checksum, path] ->
                                                      TupE [ LitE $ StringL path
                                                           , LitE $ StringL checksum ]) man))
  
  -- | Only perform the given action if the user is authenticated and has
  -- verified their email address. This provides a ``logged out default'' of
  -- redirecting the client to the login page.
  withVerifiedMember :: E ((Member -> a) -> a)
  withVerifiedMember f =
    case ?member of
      Nothing -> error "Please log in."
      Just m  -> case memberEmail m of
                   Nothing -> error "Please verify your email address."
                   Just _  -> f m
  
  withLoggedInMember :: E ((Member -> a) -> a)
  withLoggedInMember f =
    case ?member of
      Nothing -> error "Please log in."
      Just m  -> f m
  