[Heavy WIP] Initial commit
commit
670b296628
|
@ -0,0 +1 @@
|
||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "phoebe"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode = "1.3.3"
|
||||||
|
discord_message_format = { git = "https://git.lavender.software/charlotte/discord-message-format.git" }
|
||||||
|
matrix-sdk = { git = "https://github.com/matrix-org/matrix-rust-sdk.git" }
|
||||||
|
serde = { version = "1.0.127", features = ["derive"] }
|
||||||
|
serenity = "0.10.8"
|
||||||
|
sled = "0.34.6"
|
||||||
|
tokio = { version = "1.8.0", features = ["full"] }
|
||||||
|
tracing = "0.1.26"
|
|
@ -0,0 +1,43 @@
|
||||||
|
use super::{MessageContent, Styled};
|
||||||
|
use discord_message_format::DiscordComponent;
|
||||||
|
|
||||||
|
impl<'a> From<&DiscordComponent<'a>> for Styled {
|
||||||
|
fn from(discord: &DiscordComponent<'a>) -> Self {
|
||||||
|
match discord {
|
||||||
|
DiscordComponent::Plain(text) => Self::Plain(text.to_string()),
|
||||||
|
DiscordComponent::Literal(char) => Self::Plain(char.to_string()),
|
||||||
|
DiscordComponent::Link(link) => Self::Link {
|
||||||
|
target: link.to_string(),
|
||||||
|
text: vec![Self::Plain(link.to_string())],
|
||||||
|
},
|
||||||
|
|
||||||
|
DiscordComponent::Bold(content) => Self::Bold(convert_discord(content)),
|
||||||
|
DiscordComponent::Italic(content) => Self::Italic(convert_discord(content)),
|
||||||
|
DiscordComponent::Strikethrough(content) => {
|
||||||
|
Self::Strikethrough(convert_discord(content))
|
||||||
|
}
|
||||||
|
DiscordComponent::Underline(content) => Self::Underline(convert_discord(content)),
|
||||||
|
|
||||||
|
DiscordComponent::Code(code) => Self::Code(code.to_string()),
|
||||||
|
DiscordComponent::CodeBlock { lang, source } => Self::CodeBlock {
|
||||||
|
lang: lang.map(|s| s.to_string()),
|
||||||
|
source: source.to_string(),
|
||||||
|
},
|
||||||
|
|
||||||
|
DiscordComponent::Spoiler(content) => Self::Spoiler {
|
||||||
|
reason: None,
|
||||||
|
content: convert_discord(content),
|
||||||
|
},
|
||||||
|
|
||||||
|
DiscordComponent::LineBreak => Self::HardBreak,
|
||||||
|
DiscordComponent::Quote(content) => Self::BlockQuote(convert_discord(content)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn convert_discord(discord_message: &[DiscordComponent<'_>]) -> MessageContent {
|
||||||
|
discord_message
|
||||||
|
.iter()
|
||||||
|
.map(Styled::from)
|
||||||
|
.collect::<MessageContent>()
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
mod convert_discord;
|
||||||
|
|
||||||
|
pub type MessageContent = Vec<Styled>;
|
||||||
|
|
||||||
|
pub enum Styled {
|
||||||
|
Plain(String),
|
||||||
|
Link {
|
||||||
|
target: String,
|
||||||
|
text: MessageContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
Italic(MessageContent),
|
||||||
|
Bold(MessageContent),
|
||||||
|
Strikethrough(MessageContent),
|
||||||
|
Underline(MessageContent),
|
||||||
|
|
||||||
|
Code(String),
|
||||||
|
CodeBlock {
|
||||||
|
lang: Option<String>,
|
||||||
|
source: String,
|
||||||
|
},
|
||||||
|
|
||||||
|
Spoiler {
|
||||||
|
reason: Option<String>,
|
||||||
|
content: MessageContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
HardBreak,
|
||||||
|
BlockQuote(MessageContent),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub use convert_discord::convert_discord;
|
|
@ -0,0 +1,32 @@
|
||||||
|
use serenity::{async_trait, model::prelude::*, prelude::*};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
use crate::{ast, MessageReference};
|
||||||
|
|
||||||
|
impl From<&Message> for MessageReference {
|
||||||
|
fn from(message: &Message) -> Self {
|
||||||
|
Self::Discord(message.channel_id.0, message.id.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Some way to emit messages for matrix,
|
||||||
|
// and some way to receive messages from matrix.
|
||||||
|
struct DiscordSide {}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl EventHandler for DiscordSide {
|
||||||
|
async fn ready(&self, _ctx: Context, _ready: Ready) {
|
||||||
|
info!("Discord side: Ready");
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn message(&self, ctx: Context, message: Message) {
|
||||||
|
let _message_ref = MessageReference::from(&message);
|
||||||
|
// TODO: Store this message ref & associations in the DB
|
||||||
|
|
||||||
|
let content = discord_message_format::parse(&message.content);
|
||||||
|
let content = ast::convert_discord(&content);
|
||||||
|
|
||||||
|
// TODO: Broadcast the message to other platforms
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
mod ast;
|
||||||
|
mod discord;
|
||||||
|
mod matrix;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub enum MessageReference {
|
||||||
|
Discord(u64, u64),
|
||||||
|
Matrix(String, String),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
use matrix_sdk::{
|
||||||
|
async_trait,
|
||||||
|
room::Room,
|
||||||
|
ruma::{
|
||||||
|
api::client::r0::room::get_room_event,
|
||||||
|
events::{
|
||||||
|
room::message::{MessageEventContent, MessageFormat, MessageType},
|
||||||
|
AnyMessageEvent, AnyRoomEvent, SyncMessageEvent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
EventHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::MessageReference;
|
||||||
|
|
||||||
|
impl From<(&Room, &SyncMessageEvent<MessageEventContent>)> for MessageReference {
|
||||||
|
fn from((room, event): (&Room, &SyncMessageEvent<MessageEventContent>)) -> Self {
|
||||||
|
let room_string = room.room_id().as_str().to_string();
|
||||||
|
let event_string = event.event_id.as_str().to_string();
|
||||||
|
|
||||||
|
Self::Matrix(room_string, event_string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MatrixHandler;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl EventHandler for MatrixHandler {
|
||||||
|
async fn on_room_message(&self, room: Room, event: &SyncMessageEvent<MessageEventContent>) {
|
||||||
|
let event_id = &event.event_id;
|
||||||
|
|
||||||
|
if let Room::Joined(room) = room {
|
||||||
|
let event = room
|
||||||
|
.event(get_room_event::Request::new(room.room_id(), event_id))
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.event
|
||||||
|
.deserialize()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(message)) = event {
|
||||||
|
if let MessageEventContent {
|
||||||
|
msgtype: MessageType::Text(text_content),
|
||||||
|
..
|
||||||
|
} = &message.content
|
||||||
|
{
|
||||||
|
if let Some(html_body) = text_content
|
||||||
|
.formatted
|
||||||
|
.as_ref()
|
||||||
|
.filter(|f| f.format == MessageFormat::Html)
|
||||||
|
.map(|f| &f.body)
|
||||||
|
{
|
||||||
|
// TODO: Parse the html_body into the AST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue