{-# LANGUAGE OverloadedStrings, QuasiQuotes, TemplateHaskell, TypeFamilies, ViewPatterns, LambdaCase #-} module Main (main) where import Yesod import Network.Wai.Handler.Warp import Data.Function ((&)) import Data.Functor ((<&>)) import qualified Data.ByteString as BS import Bangs import BangState import Config data Search = Search { bangState :: BangState } mkYesod "Search" [parseRoutes| / HomeR GET /bangs.json BangsR GET /submitBang SubmitR POST /search.xml OpenSearchR GET |] instance Yesod Search where makeSessionBackend _ = return Nothing getHomeR :: Handler String getHomeR = return "TODO" getBangsR :: Handler TypedContent getBangsR = do bangsAccessor <- lookupHeader "accept-encoding" >>= \case Just ae | "br" `BS.isInfixOf` ae -> do addHeader "content-encoding" "br" return getBangsBrotli _ -> do return getBangsJSON bs <- liftIO . bangsAccessor . bangState =<< getYesod return $ TypedContent typeJson $ toContent bs postSubmitR :: Handler String postSubmitR = return "TODO" getOpenSearchR :: Handler TypedContent getOpenSearchR = do url <- lookupGetParam "default" <&> \case Nothing -> baseUrl <> "/#{searchTerms}" Just b -> baseUrl <> "/#" <> b <> "#{searchTerms}" return $ TypedContent "application/opensearchdescription+xml" $ toContent $ makeOpenSearch url main :: IO () main = do s <- Search <$> initBangState sApp <- toWaiApp s -- includes middlewares let settings = defaultSettings -- currently, "*" seems to bind only to ipv4 while "*6" binds to both & setHost "*6" & setPort 20546 runSettings settings sApp