[Heavy WIP] Initial commit
This commit is contained in:
commit
670b296628
9 changed files with 3214 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
3013
Cargo.lock
generated
Normal file
3013
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -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"
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# phoebe
|
||||
|
||||
bridgers
|
43
src/ast/convert_discord.rs
Normal file
43
src/ast/convert_discord.rs
Normal file
|
@ -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>()
|
||||
}
|
32
src/ast/mod.rs
Normal file
32
src/ast/mod.rs
Normal file
|
@ -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;
|
32
src/discord.rs
Normal file
32
src/discord.rs
Normal file
|
@ -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
|
||||
}
|
||||
}
|
15
src/main.rs
Normal file
15
src/main.rs
Normal file
|
@ -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!");
|
||||
}
|
59
src/matrix.rs
Normal file
59
src/matrix.rs
Normal file
|
@ -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 a new issue