hask-irc/Network/IRC/Protocol.hs

63 lines
3.0 KiB
Haskell
Raw Normal View History

2014-05-25 01:09:31 +05:30
module Network.IRC.Protocol (MessageParser, msgFromLine, lineFromCommand) where
2014-05-04 02:57:43 +05:30
2014-05-10 21:45:16 +05:30
import ClassyPrelude
import Data.List ((!!))
2014-05-23 02:45:45 +05:30
import Data.Text (split, strip)
2014-05-04 02:57:43 +05:30
import Network.IRC.Types
2014-05-25 01:09:31 +05:30
type MessageParser = BotConfig -> UTCTime -> Text -> Message
msgFromLine :: MessageParser
2014-05-04 04:28:44 +05:30
msgFromLine (BotConfig { .. }) time line
2014-05-25 01:09:31 +05:30
| "PING :" `isPrefixOf` line = Message time line $ PingMsg (drop 6 line)
2014-05-04 02:57:43 +05:30
| otherwise = case command of
2014-05-25 01:09:31 +05:30
"PONG" -> Message time line $ PongMsg message
"JOIN" -> Message time line $ JoinMsg user
"QUIT" -> Message time line $ QuitMsg user quitMessage
"PART" -> Message time line $ PartMsg user message
"KICK" -> Message time line $ KickMsg user kicked kickReason
2014-05-04 02:57:43 +05:30
"MODE" -> if source == botNick
2014-05-25 01:09:31 +05:30
then Message time line $ ModeMsg Self target message []
else Message time line $ ModeMsg user target mode modeArgs
"NICK" -> Message time line $ NickMsg user (drop 1 target)
"353" -> Message time line $ NamesMsg namesNicks
"433" -> Message time line NickInUseMsg
"PRIVMSG" | target /= channel -> Message time line $ PrivMsg user message
| isActionMsg -> Message time line $ ActionMsg user (initDef . drop 8 $ message)
| otherwise -> Message time line $ ChannelMsg user message
_ -> Message time line $ OtherMsg source command target message
2014-05-04 02:57:43 +05:30
where
isSpc = (== ' ')
isNotSpc = not . isSpc
splits = split isSpc line
source = drop 1 . takeWhile isNotSpc $ line
target = splits !! 2
command = splits !! 1
2014-05-23 02:45:45 +05:30
message = strip . drop 1 . unwords . drop 3 $ splits
quitMessage = strip . drop 1 . unwords . drop 2 $ splits
user = uncurry User . break (== '!') $ source
mode = splits !! 3
modeArgs = drop 4 splits
kicked = splits !! 3
kickReason = drop 1 . unwords . drop 4 $ splits
2014-05-25 01:09:31 +05:30
nickPrefixes = "~&@%+" :: String
namesNicks = map stripNickPrefix . words . drop 1 . unwords . drop 5 $ splits
stripNickPrefix = pack . dropWhile (`elem` nickPrefixes) . unpack
2014-05-04 02:57:43 +05:30
2014-05-20 02:40:08 +05:30
isActionMsg = "\SOH" `isPrefixOf` message && "ACTION" `isPrefixOf` drop 1 message
lineFromCommand :: BotConfig -> Command -> Maybe Text
lineFromCommand BotConfig { .. } command = case command of
PongCmd { .. } -> Just $ "PONG :" ++ rmsg
PingCmd { .. } -> Just $ "PING :" ++ rmsg
NickCmd -> Just $ "NICK " ++ botNick
UserCmd -> Just $ "USER " ++ botNick ++ " 0 * :" ++ botNick
JoinCmd -> Just $ "JOIN " ++ channel
QuitCmd -> Just "QUIT"
ChannelMsgReply { .. } -> Just $ "PRIVMSG " ++ channel ++ " :" ++ rmsg
2014-05-22 03:23:57 +05:30
PrivMsgReply (User { .. }) rmsg -> Just $ "PRIVMSG " ++ userNick ++ " :" ++ rmsg
2014-05-20 02:40:08 +05:30
NamesCmd -> Just $ "NAMES " ++ channel
_ -> Nothing