diff options
author | Teddy Wing | 2017-08-16 01:04:28 +0200 |
---|---|---|
committer | Teddy Wing | 2017-08-16 01:04:28 +0200 |
commit | a0d21d9aed3a38e98e622fbae5fcab3e91c5ddee (patch) | |
tree | 4142d51a8d443153a2e86dd460e40d0e897c0fd6 /src | |
parent | 5f157d66a001224fd623b63e92505aa058599942 (diff) | |
download | sorbot-a0d21d9aed3a38e98e622fbae5fcab3e91c5ddee.tar.bz2 |
Connect plugins to IRC
Instead of sending a hard-coded string message over IRC, now invoke our
plugin list.
Now, IRC messages get matched against our plugin list, and if any plugin
matches, its return string gets posted to the appropriate channel.
Move the database connection inside the plugin so that we can continue
to access it without having to pass in the DB connection. I didn't want
to connect to the database in the IRC code because it doesn't relate,
and I don't have a good enough grasp of monads to know if I can create
the connection in "Lib.hs" and "pass" it to the IRC message handler to
then pass it into the plugins.
Moving the database connection inside the plugins means that it no
longer takes a database connection as an argument.
The IRC message handler now has a lot of duplication, but it basically
works, which is super exciting! Took a _long_ time to figure out the
proper way to get the types to line up and get this compiling, but
really glad it's working now! The magic function turned out to be
`liftIO` to extract the `Either String String` out of its `IO` monad
wrapper to be fed to the `IRC.send` function.
Not a fan of the type conversion between `String` and `Data.Text`, so
we'll eventually have to convert our plugins to use `Data.Text`.
Diffstat (limited to 'src')
-rw-r--r-- | src/IRC.hs | 42 | ||||
-rw-r--r-- | src/Lib.hs | 2 | ||||
-rw-r--r-- | src/Plugin/Base.hs | 3 | ||||
-rw-r--r-- | src/Plugin/GitHubCommit.hs | 5 |
4 files changed, 45 insertions, 7 deletions
@@ -4,11 +4,15 @@ module IRC ( connectIRC ) where +import Control.Monad.IO.Class (liftIO) import qualified Data.ByteString as B import qualified Data.Text as T import qualified Network.IRC.Client as IRC +import Message +import Plugin (matchPlugin, performPlugin) + connectIRC :: B.ByteString -> Int -> T.Text -> IO () connectIRC host port nick = do conn <- IRC.connectWithTLS host port 1 @@ -26,8 +30,38 @@ handlePrivmsg = IRC.EventHandler , IRC._eventFunc = \evt -> dispatchEvent evt } where - dispatchEvent (IRC.Event _ (IRC.User nick) (IRC.Privmsg _ (Right msg))) = - IRC.send $ IRC.Privmsg nick (Right "test") + dispatchEvent (IRC.Event _ (IRC.User nick) (IRC.Privmsg _ (Right msg))) = do + -- IRC.send $ IRC.Privmsg nick (Right "test") + let message = Message + { text = T.unpack msg + , channel = T.unpack nick + , nick = T.unpack nick + } + Just plugin = matchPlugin message + -- rsp =<< performPlugin plugin message + -- IRC.send case performPlugin plugin message of + -- Left err -> IRC.Privmsg nick (Right (T.pack err)) + -- Right r -> IRC.Privmsg nick (Right (T.pack r)) + response <- liftIO $ performPlugin plugin message + IRC.send $ case response of + Left err -> IRC.Privmsg nick (Right (T.pack err)) + Right r -> IRC.Privmsg nick (Right (T.pack r)) dispatchEvent (IRC.Event - _ (IRC.Channel chan nick) (IRC.Privmsg _ (Right msg))) = - IRC.send $ IRC.Privmsg chan (Right "test") + _ (IRC.Channel chan nick) (IRC.Privmsg _ (Right msg))) = do + -- IRC.send $ IRC.Privmsg chan (Right "test") + let message = Message + { text = T.unpack msg + , channel = T.unpack chan + , nick = T.unpack nick + } + Just plugin = matchPlugin message + response <- liftIO $ performPlugin plugin message + IRC.send $ case response of + Left err -> IRC.Privmsg chan (Right (T.pack err)) + Right r -> IRC.Privmsg chan (Right (T.pack r)) + + -- let Just plugin = matchPlugin message + -- response <- performPlugin plugin message + -- putStrLn $ case response of + -- Left e -> e + -- Right r -> r @@ -20,7 +20,7 @@ someFunc = do -- } -- Just plugin = matchPlugin message -- dbConn <- open "db/sorbot_development.sqlite3" - -- response <- performPlugin plugin message dbConn + -- response <- performPlugin plugin message -- putStrLn $ case response of -- Left e -> e -- Right r -> r diff --git a/src/Plugin/Base.hs b/src/Plugin/Base.hs index fe3a0f8..4e63fdd 100644 --- a/src/Plugin/Base.hs +++ b/src/Plugin/Base.hs @@ -9,7 +9,8 @@ import Database.SQLite.Simple import Message -- TODO: Replace Connection with a type class -type PluginAction = Message -> Connection -> IO (Either String String) +-- type PluginAction = Message -> Connection -> IO (Either String String) +type PluginAction = Message -> IO (Either String String) data Plugin = Plugin { matchRegex :: String diff --git a/src/Plugin/GitHubCommit.hs b/src/Plugin/GitHubCommit.hs index 492fd30..9773690 100644 --- a/src/Plugin/GitHubCommit.hs +++ b/src/Plugin/GitHubCommit.hs @@ -17,13 +17,16 @@ gitHubCommit = Plugin } gitHubCommitAction :: PluginAction -gitHubCommitAction message dbConn = do +gitHubCommitAction message = do + dbConn <- open "db/sorbot_development.sqlite3" rs <- query dbConn "SELECT repo_url \ \ FROM plugin_github_commit_channel_repo_urls \ \ WHERE channel = ? \ \ LIMIT 1" (Only (M.channel message)) :: IO [RepoUrlRow] + close dbConn + return $ respond rs where respond [] = |