diff --git a/Session.hs b/Session.hs index ca95457..fe7c025 100644 --- a/Session.hs +++ b/Session.hs @@ -13,6 +13,17 @@ import qualified Network.Protocol.XMPP as XMPP import qualified Config import Util +cleanOld :: Config.Config -> XMPP.JID -> XMPP.XMPP () +cleanOld config source = do + old <- liftIO $ DB.query (Config.db config) + (s"SELECT target_muc, target_nick, source_nick FROM sessions WHERE version < ? AND source_muc = ?") + (Config.dbVersion config, bareTxt source) + forM_ old $ \(muc, nick, source_nick) -> + let Just target = XMPP.parseJID $ muc ++ s"/" ++ nick in + sendPresence config ((XMPP.emptyPresence XMPP.PresenceUnavailable) { + XMPP.presenceFrom = XMPP.parseJID $ bareTxt source ++ s"/" ++ source_nick + }) target + mkSession :: (MonadIO m) => Config.Config -> XMPP.PresenceType @@ -26,13 +37,16 @@ mkSession config typ source target (sourceMuc, sourceNick, targetMuc, targetNick) | otherwise = liftIO $ DB.execute (Config.db config) - (s"INSERT INTO sessions VALUES (?,?,?,?,?)") - (sourceMuc, sourceNick, targetMuc, targetNick, Config.dbVersion config) + (s"INSERT INTO sessions VALUES (?,?,?,?,?) ON CONFLICT(source_muc,source_nick,target_muc,target_nick) DO UPDATE SET version=?") + ( + sourceMuc, sourceNick, targetMuc, targetNick, + Config.dbVersion config, Config.dbVersion config + ) where - sourceMuc = bareTxt <$> source - sourceNick = XMPP.strResource <$> (XMPP.jidResource =<< source) + sourceMuc = fromMaybe mempty (bareTxt <$> source) + sourceNick = fromMaybe mempty (XMPP.strResource <$> (XMPP.jidResource =<< source)) targetMuc = bareTxt target - targetNick = XMPP.strResource <$> XMPP.jidResource target + targetNick = fromMaybe mempty (XMPP.strResource <$> XMPP.jidResource target) maybeAddNick :: XMPP.JID -> Text -> XMPP.JID maybeAddNick jid@XMPP.JID { XMPP.jidResource = Just _ } _ = jid @@ -94,7 +108,8 @@ sendGroupChat config message@XMPP.Message { XMPP.messagePayloads = payloads } target = do nickSwaps1 <- liftIO $ DB.query (Config.db config) (s"SELECT target_nick, source_nick FROM sessions WHERE source_muc=?") (DB.Only $ bareTxt target) - nickSwaps2 <- liftIO $ DB.query (Config.db config) (s"SELECT source_nick, target_nick FROM sessions WHERE target_muc=? AND source_muc IS NOT NULL") (DB.Only $ bareTxt target) + nickSwaps2 <- liftIO $ DB.query (Config.db config) (s"SELECT source_nick, target_nick FROM sessions WHERE target_muc=? AND source_muc <> ''") (DB.Only $ bareTxt target) + let nickSwap = replaceWords (nickSwaps1 ++ nickSwaps2) XMPP.putStanza $ message { XMPP.messageFrom = Just (proxyJid config from), XMPP.messageTo = Just target, @@ -103,8 +118,7 @@ sendGroupChat config message@XMPP.Message { [body] -> body { XML.elementNodes = [ XML.NodeContent $ XML.ContentText $ - replaceWords (nickSwaps1 ++ nickSwaps2) - (mconcat (XML.elementText body)) + nickSwap (mconcat (XML.elementText body)) ]} _ -> el ) payloads diff --git a/gateway.hs b/gateway.hs index 25f7aab..2e4aebb 100644 --- a/gateway.hs +++ b/gateway.hs @@ -40,7 +40,8 @@ handlePresence config presence@XMPP.Presence { | bareTxt to /= bareTxt (Config.bridgeJid config) = -- This is to one of our ghosts, so just ignore it return () - | hasMucCode 110 presence = return () -- ignore self presence + | hasMucCode 110 presence = -- done joining room, clean up old data + Session.cleanOld config from | Just resource <- XMPP.jidResource from, not (s"[x]" `T.isInfixOf` XMPP.strResource resource) = forM_ (targets config from) $ Session.sendPresence config presence