You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
4.1 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# LANGUAGE LambdaCase #-}
  3. module Conf
  4. ( Group(..)
  5. , Config(..)
  6. , readConfig
  7. ) where
  8. import Control.Monad ( mzero )
  9. import qualified Data.HashMap.Strict as H
  10. import qualified Data.Map.Strict as Map
  11. import Data.Maybe ( fromMaybe )
  12. import qualified Data.Text as T
  13. import Data.Yaml ( (.:)
  14. , FromJSON
  15. , Object
  16. , Parser
  17. , Value(Number, Object, String)
  18. , decodeFileThrow
  19. , parseJSON
  20. , parseMaybe
  21. , withObject
  22. )
  23. import qualified Discord.Types as D
  24. import Data.Either ( fromRight )
  25. import Data.Scientific ( Scientific
  26. , floatingOrInteger
  27. )
  28. import Data.Word ( Word64 )
  29. data Group = Group
  30. { groupChannel :: D.Snowflake
  31. , groupRole :: D.Snowflake
  32. , groupAde :: T.Text
  33. }
  34. deriving (Show, Eq, Read)
  35. hmToGroup :: H.HashMap T.Text Value -> Group
  36. hmToGroup hm = Group
  37. { groupChannel = scitosno
  38. . valueNum "channel"
  39. . errorRequired "channel"
  40. $ H.lookup "channel" hm
  41. , groupRole = scitosno . valueNum "role" . errorRequired "role" $ H.lookup
  42. "role"
  43. hm
  44. , groupAde = valueText "edturl" . errorRequired "edturl" $ H.lookup
  45. "edturl"
  46. hm
  47. }
  48. data Config = Config
  49. { configServer :: D.Snowflake
  50. , configGroups :: Map.Map T.Text Group
  51. , configAutoEDTCronDay :: T.Text
  52. , configAutoEDTCronWeek :: T.Text
  53. }
  54. deriving (Show, Eq, Read)
  55. readConfig :: FilePath -> IO Config
  56. readConfig fp = do
  57. conf_yml <- decodeFileThrow fp :: IO Object
  58. -- print conf_yml
  59. return $ ymlToConf conf_yml
  60. ymlToConf :: Object -> Config
  61. ymlToConf v = Config { configServer = server
  62. , configGroups = groups
  63. , configAutoEDTCronDay = autoEdtCronDay
  64. , configAutoEDTCronWeek = autoEdtCronWeek
  65. }
  66. where
  67. server' = errorRequired "server" $ H.lookup "server" v
  68. server = scitosno $ valueNum "server" server'
  69. groups = parseGroups groupsObject
  70. groupsObject = H.lookup "groups" v
  71. parseGroups (Just (Object o)) =
  72. let groupList' :: H.HashMap T.Text Group
  73. groupList' = fmap
  74. ( hmToGroup
  75. . (\case
  76. Object u -> u
  77. _ -> error "groups are objects"
  78. )
  79. )
  80. o
  81. in Map.fromList $ H.toList groupList'
  82. parseGroups _ = error "Wrong format for groups"
  83. autoEdtCronDay =
  84. valueText "autoEdtCronDay" $ fromMaybe "0 15 * * 0-4" $ H.lookup
  85. "autoEdtCronDay"
  86. v
  87. autoEdtCronWeek =
  88. valueText "autoEdtCronWeek" $ fromMaybe "30 9 * * 0" $ H.lookup
  89. "autoEdtCronWeek"
  90. v
  91. errorRequired :: [Char] -> Maybe a -> a
  92. errorRequired name = fromMaybe (error $ "required field: " ++ name)
  93. valueText :: [Char] -> Value -> T.Text
  94. valueText _ (String t) = t
  95. valueText name _ = error $ name ++ " should be a string"
  96. valueNum :: [Char] -> Value -> Scientific
  97. valueNum _ (Number n) = n
  98. valueNum name _ = error $ name ++ " should be an integer"
  99. scitosno :: Scientific -> D.Snowflake
  100. scitosno =
  101. D.Snowflake
  102. . (fromInteger :: Integer -> Word64)
  103. . fromRight (error "Cant read that as an int")
  104. . floatingOrInteger