aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2017-08-16 01:04:28 +0200
committerTeddy Wing2017-08-16 01:04:28 +0200
commita0d21d9aed3a38e98e622fbae5fcab3e91c5ddee (patch)
tree4142d51a8d443153a2e86dd460e40d0e897c0fd6 /src
parent5f157d66a001224fd623b63e92505aa058599942 (diff)
downloadsorbot-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.hs42
-rw-r--r--src/Lib.hs2
-rw-r--r--src/Plugin/Base.hs3
-rw-r--r--src/Plugin/GitHubCommit.hs5
4 files changed, 45 insertions, 7 deletions
diff --git a/src/IRC.hs b/src/IRC.hs
index 127439d..bb153d2 100644
--- a/src/IRC.hs
+++ b/src/IRC.hs
@@ -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
diff --git a/src/Lib.hs b/src/Lib.hs
index f72729e..b23bf78 100644
--- a/src/Lib.hs
+++ b/src/Lib.hs
@@ -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 [] =