hask-irc/Network/IRC/Handlers.hs

93 lines
3.6 KiB
Haskell
Raw Normal View History

2014-05-13 00:00:33 +05:30
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
2014-05-04 02:57:43 +05:30
module Network.IRC.Handlers (coreMsgHandlerNames, mkMsgHandler) where
2014-05-22 20:59:02 +05:30
import qualified Network.IRC.Handlers.MessageLogger as Logger
import qualified Network.IRC.Handlers.SongSearch as SongSearch
import qualified Network.IRC.Handlers.Auth as Auth
2014-05-23 02:45:45 +05:30
import qualified Network.IRC.Handlers.NickTracker as NickTracker
2014-05-04 02:57:43 +05:30
2014-05-10 21:45:16 +05:30
import ClassyPrelude
2014-05-21 11:20:53 +05:30
import Control.Concurrent.Lifted (Chan)
import Control.Monad.Reader (ask)
import Data.Convertible (convert)
import Data.Time (addUTCTime)
2014-05-04 02:57:43 +05:30
import Network.IRC.Types
2014-05-22 20:59:02 +05:30
import Network.IRC.Util
2014-05-04 02:57:43 +05:30
coreMsgHandlerNames :: [Text]
2014-05-22 20:59:02 +05:30
coreMsgHandlerNames = ["pingpong", "messagelogger", "help"]
2014-05-21 00:06:37 +05:30
mkMsgHandler :: BotConfig -> Chan SomeEvent -> MsgHandlerName -> IO (Maybe MsgHandler)
mkMsgHandler _ _ "greeter" = return . Just $ newMsgHandler { onMessage = greeter }
mkMsgHandler _ _ "welcomer" = return . Just $ newMsgHandler { onMessage = welcomer }
mkMsgHandler _ _ "pingpong" = do
state <- getCurrentTime >>= newIORef
2014-05-21 00:06:37 +05:30
return . Just $ newMsgHandler { onMessage = pingPong state }
2014-05-22 20:59:02 +05:30
mkMsgHandler _ _ "help" =
2014-05-23 02:45:45 +05:30
return . Just $ newMsgHandler { onMessage = help,
onHelp = return $ singletonMap "!help" helpMsg }
2014-05-22 20:59:02 +05:30
where
helpMsg = "Get help. !help or !help <command>"
2014-05-21 00:06:37 +05:30
mkMsgHandler botConfig eventChan name =
2014-05-23 02:45:45 +05:30
flip (`foldM` Nothing) [ Logger.mkMsgHandler
, SongSearch.mkMsgHandler
, Auth.mkMsgHandler
, NickTracker.mkMsgHandler ]
$ \acc h -> case acc of
Just _ -> return acc
Nothing -> h botConfig eventChan name
2014-05-04 02:57:43 +05:30
pingPong :: MonadMsgHandler m => IORef UTCTime -> Message -> m (Maybe Command)
pingPong state PingMsg { .. } = do
liftIO $ atomicWriteIORef state msgTime
return . Just $ PongCmd msg
pingPong state PongMsg { .. } = do
liftIO $ atomicWriteIORef state msgTime
return Nothing
pingPong state IdleMsg { .. } | even (convert msgTime :: Int) = do
BotConfig { .. } <- ask
let limit = fromIntegral $ botTimeout `div` 2
liftIO $ do
lastComm <- readIORef state
if addUTCTime limit lastComm < msgTime
then return . Just . PingCmd . pack . formatTime defaultTimeLocale "%s" $ msgTime
else return Nothing
pingPong _ _ = return Nothing
greeter :: MonadMsgHandler m => Message -> m (Maybe Command)
2014-05-23 02:45:45 +05:30
greeter ChannelMsg { .. } =
return . map (ChannelMsgReply . (++ " ") . (++ userNick user)) . find (== clean msg) $ greetings
2014-05-04 02:57:43 +05:30
where
2014-05-23 02:45:45 +05:30
greetings = [ "hi", "hello", "hey", "sup", "bye"
, "good morning", "good evening", "good night" ]
greeter _ = return Nothing
welcomer :: MonadMsgHandler m => Message -> m (Maybe Command)
welcomer JoinMsg { .. } = do
BotConfig { .. } <- ask
if userNick user /= botNick
then return . Just . ChannelMsgReply $ "welcome back " ++ userNick user
else return Nothing
2014-05-04 02:57:43 +05:30
welcomer _ = return Nothing
2014-05-22 20:59:02 +05:30
help :: MonadMsgHandler m => Message -> m (Maybe Command)
help ChannelMsg { .. }
| "!help" == clean msg = do
BotConfig { .. } <- ask
let commands = concatMap mapKeys . mapValues $ msgHandlerInfo
return . Just . ChannelMsgReply $ "I know these commands: " ++ unwords commands
| "!help" `isPrefixOf` msg = do
BotConfig { .. } <- ask
let command = clean . unwords . drop 1 . words $ msg
let mHelp = find ((== command) . fst) . concatMap mapToList . mapValues $ msgHandlerInfo
return . Just . ChannelMsgReply $ maybe ("No such command found: " ++ command) snd mHelp
help _ = return Nothing