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.

118 lines
4.2 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.ChannelId
  31. , groupRole :: D.RoleId
  32. , groupAde :: T.Text
  33. }
  34. deriving (Show, Eq, Read)
  35. hmToGroup :: H.HashMap T.Text Value -> Group
  36. hmToGroup hm = Group
  37. { groupChannel = fromInteger
  38. . fromRight (error "Cant read that as an int")
  39. . floatingOrInteger
  40. . valueNum "channel"
  41. . errorRequired "channel"
  42. $ H.lookup "channel" hm
  43. , groupRole = fromInteger
  44. . fromRight (error "Cant read that as an int")
  45. . floatingOrInteger
  46. . valueNum "role"
  47. . errorRequired "role"
  48. $ H.lookup "role" hm
  49. , groupAde = valueText "edturl"
  50. . errorRequired "edturl"
  51. $ H.lookup "edturl" hm
  52. }
  53. data Config = Config
  54. { configServer :: D.GuildId
  55. , configGroups :: Map.Map T.Text Group
  56. , configAutoEDTCronDay :: T.Text
  57. , configAutoEDTCronWeek :: T.Text
  58. }
  59. deriving (Show, Eq, Read)
  60. readConfig :: FilePath -> IO Config
  61. readConfig fp = do
  62. conf_yml <- decodeFileThrow fp :: IO Object
  63. -- print conf_yml
  64. return $ ymlToConf conf_yml
  65. ymlToConf :: Object -> Config
  66. ymlToConf v = Config { configServer = server
  67. , configGroups = groups
  68. , configAutoEDTCronDay = autoEdtCronDay
  69. , configAutoEDTCronWeek = autoEdtCronWeek
  70. }
  71. where
  72. server = fromInteger
  73. . fromRight (error "Cant read that as an int")
  74. . floatingOrInteger
  75. . valueNum "server"
  76. . errorRequired "server"
  77. $ H.lookup "server" v
  78. groups = parseGroups groupsObject
  79. groupsObject = H.lookup "groups" v
  80. parseGroups (Just (Object o)) =
  81. let groupList' :: H.HashMap T.Text Group
  82. groupList' = fmap
  83. ( hmToGroup
  84. . (\case
  85. Object u -> u
  86. _ -> error "groups are objects"
  87. )
  88. )
  89. o
  90. in Map.fromList $ H.toList groupList'
  91. parseGroups _ = error "Wrong format for groups"
  92. autoEdtCronDay =
  93. valueText "autoEdtCronDay" $ fromMaybe "0 15 * * 0-4" $ H.lookup
  94. "autoEdtCronDay"
  95. v
  96. autoEdtCronWeek =
  97. valueText "autoEdtCronWeek" $ fromMaybe "30 9 * * 0" $ H.lookup
  98. "autoEdtCronWeek"
  99. v
  100. errorRequired :: [Char] -> Maybe a -> a
  101. errorRequired name = fromMaybe (error $ "required field: " ++ name)
  102. valueText :: [Char] -> Value -> T.Text
  103. valueText _ (String t) = t
  104. valueText name _ = error $ name ++ " should be a string"
  105. valueNum :: [Char] -> Value -> Scientific
  106. valueNum _ (Number n) = n
  107. valueNum name _ = error $ name ++ " should be an integer"