aboutsummaryrefslogtreecommitdiff
path: root/lib/Config.hs
blob: 88206f19ce52b9965cff423c044f710758e71fa7 (plain)
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
{-# LANGUAGE ApplicativeDo     #-}
{-# LANGUAGE OverloadedLists   #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes       #-}
{-# LANGUAGE RecordWildCards   #-}

module Config (UffdConfig(..), ServerConfig(..), LoggingConfig(..)) where
import           Conftrack
import           Conftrack.Value          (ConfigValue (..))
import           Data.ByteString          (ByteString)
import           Data.Function            ((&))
import           Data.Functor             ((<&>))
import           Data.String              (IsString (..))
import           Data.Text                (Text)
import qualified Data.Text                as T
import           Data.Text.Encoding       (decodeUtf8)
import           GHC.Generics             (Generic)
import qualified Network.Wai.Handler.Warp as Warp
import           System.OsPath            (OsPath, encodeUtf, osp)
import           URI.ByteString

data UffdConfig = UffdConfig
  { uffdConfigUrl          :: URIRef Absolute
  , uffdConfigClientSecret :: Text
  , uffdConfigClientName   :: Text
  , uffdConfigEnable       :: Bool
  } deriving (Generic, Show)

data ServerConfig = ServerConfig
  { serverConfigWarp         :: Warp.Settings
  , serverConfigDbString     :: ByteString
  , serverConfigGtfs         :: OsPath
  , serverConfigAssets       :: OsPath
  , serverConfigZoneinfoPath :: OsPath
  , serverConfigDebugMode    :: Bool
  , serverConfigLogin        :: Maybe UffdConfig
  , serverConfigLogging      :: LoggingConfig
  } deriving (Generic)

data LoggingConfig = LoggingConfig
  { loggingConfigNtfyToken :: Maybe Text
  , loggingConfigNtfyTopic :: Text
  , loggingConfigHostname  :: Text
  } deriving (Generic)

instance ConfigValue (URIRef Absolute) where
  fromConfig val@(ConfigString text) =
    case parseURI strictURIParserOptions text of
      Right uri -> Right uri
      Left err  -> Left $ ParseError (T.pack $ show err)
  fromConfig val = Left (TypeMismatch "URI" val)

  prettyValue uri = decodeUtf8 (serializeURIRef' uri)

instance Config UffdConfig where
  readConfig = do
    uffdConfigUrl <- readRequiredValue [key|url|]
    uffdConfigClientName <- readRequiredValue [key|clientName|]
    uffdConfigClientSecret <- readRequiredValue [key|clientSecret|]
    uffdConfigEnable <- readRequiredValue [key|enable|]
    pure UffdConfig {..}

instance Config LoggingConfig where
  readConfig = LoggingConfig
    <$> readOptionalValue [key|ntfyToken|]
    <*> readValue "tracktrain" [key|ntfyTopic|]
    <*> readValue "tracktrain" [key|name|]

instance Config Warp.Settings where
  readConfig = do
    port <- readOptionalValue [key|port|]
    host <- readOptionalValue [key|host|]
    timeout <- readOptionalValue [key|timeout|]
    fdCacheDuration <- readOptionalValue [key|fdCacheDuration|]
    fileInfoCacheDuration <- readOptionalValue [key|fileInfoCacheDuration|]
    noParsePath <- readOptionalValue [key|noParsePath|]
    serverName <- readOptionalValue [key|serverName|]
    maximumBodyFlush <- readOptionalValue [key|maximumBodyFlush|]
    gracefulShutdownTimeout <- readOptionalValue [key|gracefulShutdownTimeout|]
    altSvc <- readOptionalValue [key|altSvc|]

    pure $ Warp.defaultSettings
     & doIf port Warp.setPort
     & doIf host Warp.setHost
     & doIf timeout Warp.setTimeout
     & doIf fdCacheDuration Warp.setFdCacheDuration
     & doIf fileInfoCacheDuration Warp.setFileInfoCacheDuration
     & doIf noParsePath Warp.setNoParsePath
     & doIf serverName Warp.setServerName
     & doIf maximumBodyFlush Warp.setMaximumBodyFlush
     & doIf gracefulShutdownTimeout Warp.setGracefulShutdownTimeout
     & doIf altSvc Warp.setAltSvc

    where doIf Nothing _  = id
          doIf (Just a) f = f a

instance ConfigValue Warp.HostPreference where
  fromConfig (ConfigString buf) = Right $ fromString (T.unpack (decodeUtf8 buf))
  fromConfig val                = Left (TypeMismatch "HostPreference" val)

instance Config ServerConfig where
  readConfig = ServerConfig
    <$> readNested [key|warp|]
    <*> readValue "" [key|dbstring|]
    <*> readValue [osp|./gtfs.zip|] [key|gtfs|]
    <*> readValue [osp|./assets|] [key|assets|]
    <*> readValue [osp|/etc/zoneinfo/|] [key|zoneinfopath|]
    <*> readValue False [key|debugmode|]
    <*> readNestedOptional [key|login|]
    <*> readNested [key|logging|]