68 lines
1.8 KiB
Rust
68 lines
1.8 KiB
Rust
use async_trait::async_trait;
|
|
use futures::StreamExt;
|
|
use tokio::select;
|
|
use irc::{client::Client, proto::Command};
|
|
use crate::linkmap::Linkmap;
|
|
use crate::message::Id;
|
|
use crate::{message::{Message, Sender, Receiver}, supervisor::{Task, TaskResult}};
|
|
use irc::proto::Message as IrcMessage;
|
|
|
|
pub use irc::client::prelude::Config as IrcConfig;
|
|
|
|
pub struct IrcTask {
|
|
config: IrcConfig,
|
|
channels: Linkmap<String>,
|
|
}
|
|
|
|
impl IrcTask {
|
|
pub fn new(config: IrcConfig, channels: Linkmap<String>) -> Self {
|
|
Self {
|
|
config, channels
|
|
}
|
|
}
|
|
|
|
async fn handle_bridge_msg(&self, id: Id, client: &mut Client, msg: Message) -> TaskResult {
|
|
for channel in self.channels.get_channels(&msg.link) {
|
|
if msg.origin.0 == id && &msg.origin.1 == channel {
|
|
continue
|
|
}
|
|
client.send_privmsg(channel, format!("<{}> {}", msg.author, msg.content))?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
async fn handle_irc_msg(&self, id: Id, tx: &mut Sender, msg: IrcMessage) -> TaskResult {
|
|
if let Command::PRIVMSG(channel, message) = &msg.command {
|
|
let Some(link) = self.channels.get_link(channel) else { return Ok(()) };
|
|
let Some(author) = msg.source_nickname() else { return Ok(()) };
|
|
tx.send(Message {
|
|
origin: (id, channel.to_owned()),
|
|
link: link.clone(),
|
|
author: author.to_owned(),
|
|
content: message.clone(),
|
|
})?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Task for IrcTask {
|
|
async fn start(&self, id: Id, mut tx: Sender, mut rx: Receiver) -> TaskResult {
|
|
let mut client = Client::from_config(self.config.clone()).await?;
|
|
client.identify()?;
|
|
|
|
let mut stream = client.stream()?;
|
|
|
|
loop {
|
|
select! {
|
|
bridge_msg = rx.recv() => self.handle_bridge_msg(id, &mut client, bridge_msg?).await?,
|
|
irc_msg = stream.next() => match irc_msg {
|
|
Some(msg) => self.handle_irc_msg(id, &mut tx, msg?).await?,
|
|
None => return Err("Lost connection to IRC server".into()),
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|