118 lines
4.9 KiB
Haskell
118 lines
4.9 KiB
Haskell
module Hsbot.Irc.Config
|
|
( IrcConfig(..)
|
|
, ircDefaultConfig
|
|
, getIrcConfig
|
|
) where
|
|
|
|
import qualified Data.ConfigFile as C
|
|
import Data.Either.Utils
|
|
import Network
|
|
import System.Exit
|
|
import System.Posix.Files
|
|
|
|
-- | Configuration data type
|
|
data IrcConfig = IrcConfig
|
|
{ ircConfigAddress :: String -- the server's address
|
|
, ircConfigPort :: PortID -- the server's port
|
|
, ircConfigChannels :: [String] -- the Channels to join on start
|
|
, ircConfigNickname :: String -- the hsbot's nickname
|
|
, ircConfigPassword :: String -- the hsbot's password, optional
|
|
, ircConfigRealname :: String -- the hsbot's real name, optional
|
|
, ircConfigCommandPrefix :: Char -- the prefix the ircbot will recognize as commands
|
|
, ircConfigPlugins :: [String] -- the ircPlugins to load
|
|
}
|
|
|
|
instance Show IrcConfig where
|
|
show (IrcConfig address port channels nickname password realname commandPrefix plugins) = unlines $
|
|
concat [ "Address: ", address ] :
|
|
concat [ "Port: ", case port of
|
|
PortNumber num -> show num
|
|
Service s -> show s
|
|
UnixSocket u -> show u ] :
|
|
concat [ "Channels: ", show channels ] :
|
|
concat [ "Nickname: ", nickname ] :
|
|
concat [ "Password: ", password ] :
|
|
concat [ "Realname: ", realname ] :
|
|
concat [ "CommandPrefix: ", show commandPrefix ] :
|
|
[ "Plugins: ", show plugins ]
|
|
|
|
-- | User configuration
|
|
ircDefaultConfig :: IrcConfig
|
|
ircDefaultConfig = IrcConfig
|
|
{ ircConfigAddress = "localhost"
|
|
, ircConfigPort = PortNumber 6667
|
|
, ircConfigChannels = ["#hsbot"]
|
|
, ircConfigNickname = "hsbot"
|
|
, ircConfigPassword = ""
|
|
, ircConfigRealname = "The One True bot, with it's haskell soul."
|
|
, ircConfigCommandPrefix = '@'
|
|
, ircConfigPlugins = ["Ping"]
|
|
}
|
|
|
|
-- | config file retrieving
|
|
getIrcConfig :: Maybe String -> IO (IrcConfig)
|
|
getIrcConfig maybePath =
|
|
case maybePath of
|
|
Just path -> do
|
|
doesFileExists <- fileExist path
|
|
case doesFileExists of
|
|
True -> do
|
|
fileStatus <- getFileStatus path
|
|
case isRegularFile $ fileStatus of
|
|
True -> compileIrcConfig ircDefaultConfig path
|
|
False -> do
|
|
putStrLn "Invalid configuration file path."
|
|
exitWith $ ExitFailure 1
|
|
False -> do
|
|
putStrLn "The specified configuration file does not exists."
|
|
exitWith $ ExitFailure 1
|
|
Nothing -> return ircDefaultConfig -- TODO : try defaults like $HOME/.hsbotrc, /etc/hsbotrc or /usr/local/etc/hsbotrc
|
|
|
|
-- | config file parsing
|
|
compileIrcConfig :: IrcConfig -> String -> IO (IrcConfig)
|
|
compileIrcConfig ircConfig path = do
|
|
val <- C.readfile C.emptyCP path
|
|
let cp = forceEither val
|
|
let address = case C.get cp "IRC" "address" of
|
|
Right this -> this
|
|
Left _ -> ircConfigAddress ircConfig
|
|
let port = case C.get cp "IRC" "port" of
|
|
Right this -> PortNumber $ fromIntegral (read this :: Int) -- TODO error handling
|
|
Left _ -> ircConfigPort ircConfig
|
|
let channels = case C.get cp "IRC" "channels" of
|
|
Right this -> map (lstrip ' ') (split this ',')
|
|
Left _ -> ircConfigChannels ircConfig
|
|
let nickname = case C.get cp "IRC" "nickname" of
|
|
Right this -> this
|
|
Left _ -> ircConfigNickname ircConfig
|
|
let password = case C.get cp "IRC" "password" of
|
|
Right this -> this
|
|
Left _ -> ircConfigPassword ircConfig
|
|
let realname = case C.get cp "IRC" "realname" of
|
|
Right this -> this
|
|
Left _ -> ircConfigRealname ircConfig
|
|
let commandPrefix = case C.get cp "IRC" "commandPrefix" of
|
|
Right this -> head this -- TODO error handling
|
|
Left _ -> ircConfigCommandPrefix ircConfig
|
|
let plugins = case C.get cp "IRC" "plugins" of
|
|
Right this -> map (lstrip ' ') (split this ',')
|
|
Left _ -> ircConfigPlugins ircConfig
|
|
return ircConfig { ircConfigAddress = address
|
|
, ircConfigPort = port
|
|
, ircConfigChannels = channels
|
|
, ircConfigNickname = nickname
|
|
, ircConfigPassword = password
|
|
, ircConfigRealname = realname
|
|
, ircConfigCommandPrefix = commandPrefix
|
|
, ircConfigPlugins = plugins }
|
|
where
|
|
split :: String -> Char -> [String]
|
|
split [] _ = [""]
|
|
split (c:cs) delim
|
|
| c == delim = "" : rest
|
|
| otherwise = (c : head rest) : tail rest
|
|
where rest = split cs delim
|
|
lstrip :: Char -> String -> String
|
|
lstrip x (c:cs) = if (x == c) then (lstrip x cs) else c:(lstrip x cs)
|
|
lstrip _ [] = []
|
|
|