irc-fun-client 0.3.0.0 → 0.4.0.0
raw patch · 5 files changed
+119/−20 lines, 5 files
Files
- NEWS +24/−0
- irc-fun-client.cabal +2/−2
- src/Network/IRC/Fun/Client/Commands.hs +7/−9
- src/Network/IRC/Fun/Client/Events.hs +25/−1
- src/Network/IRC/Fun/Client/IO.hs +61/−8
NEWS view
@@ -3,6 +3,30 @@ +irc-fun-client 0.4.0.0 -- 2015-12-16+====================================++General, build and documentation changes:++* (None)++New APIs, features and enhancements:++* Prefix `Connection` record field names with `conn` to avoid collisions+* Add IRC receiving function variants for debugging++Bug fixes:++* (None)++Dependency changes:++* (None)+++++ irc-fun-client 0.3.0.0 -- 2015-10-17 ====================================
irc-fun-client.cabal view
@@ -1,5 +1,5 @@ name: irc-fun-client-version: 0.3.0.0+version: 0.4.0.0 synopsis: Another library for writing IRC clients. description: This is an IRC client library that uses @irc-fun-messages@ library package@@ -20,7 +20,7 @@ source-repository head type: darcs- location: http://dev.rel4tion.org/fr33domlover/irc-fun-client+ location: http://hub.darcs.net/fr33domlover/irc-fun-client library exposed-modules: Network.IRC.Fun.Client
src/Network/IRC/Fun/Client/Commands.hs view
@@ -33,7 +33,7 @@ where import Control.Monad (unless)-import Data.Maybe (isNothing)+import Data.Maybe (fromMaybe, isNothing) import Network.IRC.Fun.Messages import Network.IRC.Fun.Messages.Types import Network.IRC.Fun.Client.IO@@ -47,13 +47,11 @@ -> Bool -- ^ Whether you want to see wallops (mode @+w@) -> IO () ircLogin h conn i w = do- let pass = password conn- pass' = case pass of- Just p -> p- Nothing -> ""- unless (isNothing pass) $ hPutIrc h $ PassMessage pass'- hPutIrc h $ UserMessage (nick conn) i w (nick conn)- hPutIrc h $ NickMessage $ nick conn+ let pass = fromMaybe "" $ connPassword conn+ nick = connNick conn+ unless (null pass) $ hPutIrc h $ PassMessage pass+ hPutIrc h $ UserMessage nick i w nick+ hPutIrc h $ NickMessage nick -- | IRC servers send PING messages at regular intervals to test the presence -- of an active client, at least if no other activity is detected on the@@ -131,7 +129,7 @@ ircSendToChannel h chan msg = hPutIrc h $ PrivMsgMessage (ChannelTarget chan) msg --- | Send a /me message to an IRC channel.+-- | Send a \/me message to an IRC channel. ircActToChannel :: Handle -- ^ Handle to the open socket -> String -- ^ The channel name -> String -- ^ The message to send
src/Network/IRC/Fun/Client/Events.hs view
@@ -22,13 +22,15 @@ , Privilege (..) , detectEvents , hGetIrcEventsOnce+ , hGetIrcEventsOnce' , hGetIrcEvents+ , hGetIrcEvents' ) where import Control.Monad (unless) import Data.Maybe (fromMaybe, isNothing)-import Network.IRC.Fun.Client.IO (Handle, hGetIrcOnce)+import Network.IRC.Fun.Client.IO (Handle, hGetIrcOnce, hGetIrcOnce') import Network.IRC.Fun.Messages import Network.IRC.Fun.Messages.Types @@ -177,7 +179,29 @@ Nothing -> Nothing Just spec -> either (const Nothing) Just $ detectEvents spec +-- | A variant of 'hGetIrcEventsOnce' which returns 'Left' an error message if+-- parsing or detection fails.+hGetIrcEventsOnce' :: Handle -> IO (Either String [Event])+hGetIrcEventsOnce' h = do+ res <- hGetIrcOnce' h+ return $ case res of+ Left s -> Left s+ Right spec -> detectEvents spec+ -- | Receive the next valid (successfully parsed and detected) series of IRC -- events. hGetIrcEvents :: Handle -> IO [Event] hGetIrcEvents h = hGetIrcEventsOnce h >>= maybe (hGetIrcEvents h) return++-- | A variant of 'hGetIrcEvents' which returns a list of error messages for+-- received IRC lines whose parsing/event detection failed.+hGetIrcEvents' :: Handle -> IO ([String], [Event])+hGetIrcEvents' h = do+ (l, m) <- f []+ return (reverse l, m)+ where+ f errs = do+ res <- hGetIrcEventsOnce' h+ case res of+ Left s -> f $ s : errs+ Right es -> return (errs, es)
src/Network/IRC/Fun/Client/IO.hs view
@@ -23,13 +23,18 @@ , hPutIrc , hGetIrcRaw , hGetIrcGenericOnce+ , hGetIrcGenericOnce' , hGetIrcGeneric+ , hGetIrcGeneric' , hGetIrcOnce+ , hGetIrcOnce' , hGetIrc+ , hGetIrc' ) where import Control.Exception (bracketOnError)+import Control.Monad (liftM) import Data.Maybe (fromMaybe) import Network.IRC.Fun.Messages import Network.IRC.Fun.Messages.Types@@ -39,15 +44,15 @@ -- | Details of the connection to IRC. data Connection = Connection { -- | IRC Server address, e.g. @"irc.freenode.net"@- server :: String+ connServer :: String -- | IRC server port, @6667@ should be a safe default- , port :: Int+ , connPort :: Int -- | Whether to make an encrypted connection via TLS (not implemented)- , tls :: Bool+ , connTls :: Bool -- | IRC nickname for the bot, e.g. @"funbot"@- , nick :: String+ , connNick :: String -- | Connection password, use if the nickname is registered- , password :: Maybe String+ , connPassword :: Maybe String } deriving (Eq, Show) @@ -61,8 +66,8 @@ , addrFlags = [AI_ADDRCONFIG] } addrs <- getAddrInfo (Just hints)- (Just $ server conn)- (Just $ show $ port conn)+ (Just $ connServer conn)+ (Just $ show $ connPort conn) let addr = head addrs bracketOnError (socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))@@ -104,19 +109,67 @@ -- | Receive an IRC message in generic form from the server. If parsing the -- message read from the server fails, 'Nothing' is returned. hGetIrcGenericOnce :: Handle -> IO (Maybe GenericMessage)-hGetIrcGenericOnce h = hGetIrcRaw h >>= return . parseMessage+hGetIrcGenericOnce h = liftM parseMessage $ hGetIrcRaw h +-- | A variant of 'hGetIrcGenericOnce' which returns 'Left' the message if+-- parsing fails.+hGetIrcGenericOnce' :: Handle -> IO (Either String GenericMessage)+hGetIrcGenericOnce' h = do+ line <- hGetIrcRaw h+ return $ case parseMessage line of+ Just msg -> Right msg+ Nothing -> Left line+ -- | Receive the next valid (successfully parsed) IRC message in generic form -- from the server. hGetIrcGeneric :: Handle -> IO GenericMessage hGetIrcGeneric h = hGetIrcGenericOnce h >>= maybe (hGetIrcGeneric h) return +-- | A variant of 'hGetIrcGeneric' which also returns a list of erronous IRC+-- lines received.+hGetIrcGeneric' :: Handle -> IO ([String], GenericMessage)+hGetIrcGeneric' h = do+ (l, gm) <- f []+ return (reverse l, gm)+ where+ f errs = do+ res <- hGetIrcGenericOnce' h+ case res of+ Left s -> f $ s : errs+ Right gm -> return (errs, gm)+ -- | Receive an IRC message from the server. If parsing the message read from -- the server fails, 'Nothing' is returned. hGetIrcOnce :: Handle -> IO (Maybe (Either SpecificReply SpecificMessage)) hGetIrcOnce h = hGetIrcGenericOnce h >>= return . maybe Nothing ((either (const Nothing) Just) . analyze) +-- | A variant of 'hGetIrcOnce' which returns 'Left' some information if+-- parsing/analysis fails.+hGetIrcOnce' :: Handle+ -> IO (Either String (Either SpecificReply SpecificMessage))+hGetIrcOnce' h = do+ res <- hGetIrcGenericOnce' h+ return $ case res of+ Left s -> Left s+ Right gm ->+ case analyze gm of+ Left err -> Left $ err ++ " : " ++ show gm+ Right spec -> Right spec+ -- | Receive the next valid (successfully parsed) IRC message from the server. hGetIrc :: Handle -> IO (Either SpecificReply SpecificMessage) hGetIrc h = hGetIrcOnce h >>= maybe (hGetIrc h) return++-- | A variant of 'hGetIrc' which also returns a list of error messages for+-- IRC lines whose parsing failed.+hGetIrc' :: Handle -> IO ([String], Either SpecificReply SpecificMessage)+hGetIrc' h = do+ (l, m) <- f []+ return (reverse l, m)+ where+ f errs = do+ res <- hGetIrcOnce' h+ case res of+ Left s -> f $ s : errs+ Right m -> return (errs, m)