Compare commits
No commits in common. "74f2ef88981cc0a00db02531ad49f79486d81a6b" and "2f60bbc643b44327a806c7abf437f96e85821c5e" have entirely different histories.
74f2ef8898
...
2f60bbc643
|
@ -2,7 +2,6 @@
|
||||||
#![type_length_limit = "7605144"]
|
#![type_length_limit = "7605144"]
|
||||||
use futures::try_join;
|
use futures::try_join;
|
||||||
use log::error;
|
use log::error;
|
||||||
use matrix_sdk::Client;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use tenebrous_dicebot::bot::DiceBot;
|
use tenebrous_dicebot::bot::DiceBot;
|
||||||
|
@ -16,13 +15,12 @@ use tracing_subscriber::filter::EnvFilter;
|
||||||
/// Attempt to create config object and ddatabase connection pool from
|
/// Attempt to create config object and ddatabase connection pool from
|
||||||
/// the given config path. An error is returned if config creation or
|
/// the given config path. An error is returned if config creation or
|
||||||
/// database pool creation fails for some reason.
|
/// database pool creation fails for some reason.
|
||||||
async fn init(config_path: &str) -> Result<(Arc<Config>, Database, Client), BotError> {
|
async fn init(config_path: &str) -> Result<(Arc<Config>, Database), BotError> {
|
||||||
let cfg = read_config(config_path)?;
|
let cfg = read_config(config_path)?;
|
||||||
let cfg = Arc::new(cfg);
|
let cfg = Arc::new(cfg);
|
||||||
let sqlite_path = format!("{}/dicebot.sqlite", cfg.database_path());
|
let sqlite_path = format!("{}/dicebot.sqlite", cfg.database_path());
|
||||||
let db = Database::new(&sqlite_path).await?;
|
let db = Database::new(&sqlite_path).await?;
|
||||||
let client = tenebrous_dicebot::matrix::create_client(&cfg)?;
|
Ok((cfg, db))
|
||||||
Ok((cfg, db, client))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -49,9 +47,9 @@ async fn run() -> Result<(), BotError> {
|
||||||
.next()
|
.next()
|
||||||
.expect("Need a config as an argument");
|
.expect("Need a config as an argument");
|
||||||
|
|
||||||
let (cfg, db, client) = init(&config_path).await?;
|
let (cfg, db) = init(&config_path).await?;
|
||||||
let grpc = rpc::serve_grpc(&cfg, &db, &client);
|
let grpc = rpc::serve_grpc(&cfg, &db);
|
||||||
let bot = run_bot(&cfg, &db, &client);
|
let bot = run_bot(&cfg, &db);
|
||||||
|
|
||||||
match try_join!(bot, grpc) {
|
match try_join!(bot, grpc) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
@ -61,10 +59,10 @@ async fn run() -> Result<(), BotError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_bot(cfg: &Arc<Config>, db: &Database, client: &Client) -> Result<(), BotError> {
|
async fn run_bot(cfg: &Arc<Config>, db: &Database) -> Result<(), BotError> {
|
||||||
let state = Arc::new(RwLock::new(DiceBotState::new(&cfg)));
|
let state = Arc::new(RwLock::new(DiceBotState::new(&cfg)));
|
||||||
|
|
||||||
match DiceBot::new(cfg, &state, db, client) {
|
match DiceBot::new(cfg, &state, db) {
|
||||||
Ok(bot) => bot.run().await?,
|
Ok(bot) => bot.run().await?,
|
||||||
Err(e) => println!("Error connecting: {:?}", e),
|
Err(e) => println!("Error connecting: {:?}", e),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,25 +1,18 @@
|
||||||
|
use tenebrous_rpc::protos::dicebot::dicebot_client::DicebotClient;
|
||||||
use tenebrous_rpc::protos::dicebot::UserIdRequest;
|
use tenebrous_rpc::protos::dicebot::UserIdRequest;
|
||||||
use tenebrous_rpc::protos::dicebot::{dicebot_client::DicebotClient, GetVariableRequest};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut client = DicebotClient::connect("http://0.0.0.0:9090").await?;
|
let mut client = DicebotClient::connect("http://0.0.0.0:9090").await?;
|
||||||
|
|
||||||
// let request = tonic::Request::new(GetVariableRequest {
|
|
||||||
// user_id: "@projectmoon:agnos.is".into(),
|
|
||||||
// room_id: "!agICWvldGfuCywUVUM:agnos.is".into(),
|
|
||||||
// variable_name: "stuff".into(),
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let response = client.get_variable(request).await?.into_inner();
|
|
||||||
|
|
||||||
let request = tonic::Request::new(UserIdRequest {
|
let request = tonic::Request::new(UserIdRequest {
|
||||||
user_id: "@projectmoon:agnos.is".into(),
|
user_id: "Tonic".into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = client.rooms_for_user(request).await?.into_inner();
|
let response = client.rooms_for_user(request).await?.into_inner();
|
||||||
// println!("RESPONSE={:?}", response);
|
|
||||||
// println!("User friendly response is: {:?}", response.value);
|
println!("RESPONSE={:?}", response);
|
||||||
println!("Rooms: {:?}", response.rooms);
|
println!("User friendly response is: {:?}", response.room_ids);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,22 @@ pub struct DiceBot {
|
||||||
db: Database,
|
db: Database,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cache_dir() -> Result<PathBuf, BotError> {
|
||||||
|
let mut dir = dirs::cache_dir().ok_or(BotError::NoCacheDirectoryError)?;
|
||||||
|
dir.push("matrix-dicebot");
|
||||||
|
Ok(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates the matrix client.
|
||||||
|
fn create_client(config: &Config) -> Result<Client, BotError> {
|
||||||
|
let cache_dir = cache_dir()?;
|
||||||
|
//let store = JsonStore::open(&cache_dir)?;
|
||||||
|
let client_config = ClientConfig::new().store_path(cache_dir);
|
||||||
|
let homeserver_url = Url::parse(&config.matrix_homeserver())?;
|
||||||
|
|
||||||
|
Ok(Client::new_with_config(homeserver_url, client_config)?)
|
||||||
|
}
|
||||||
|
|
||||||
impl DiceBot {
|
impl DiceBot {
|
||||||
/// Create a new dicebot with the given configuration and state
|
/// Create a new dicebot with the given configuration and state
|
||||||
/// actor. This function returns a Result because it is possible
|
/// actor. This function returns a Result because it is possible
|
||||||
|
@ -44,10 +60,9 @@ impl DiceBot {
|
||||||
config: &Arc<Config>,
|
config: &Arc<Config>,
|
||||||
state: &Arc<RwLock<DiceBotState>>,
|
state: &Arc<RwLock<DiceBotState>>,
|
||||||
db: &Database,
|
db: &Database,
|
||||||
client: &Client,
|
|
||||||
) -> Result<Self, BotError> {
|
) -> Result<Self, BotError> {
|
||||||
Ok(DiceBot {
|
Ok(DiceBot {
|
||||||
client: client.clone(),
|
client: create_client(&config)?,
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
state: state.clone(),
|
state: state.clone(),
|
||||||
db: db.clone(),
|
db: db.clone(),
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use futures::stream::{self, StreamExt, TryStreamExt};
|
use futures::stream::{self, StreamExt, TryStreamExt};
|
||||||
use log::error;
|
use log::error;
|
||||||
use matrix_sdk::{events::room::message::NoticeMessageEventContent, room::Joined, ClientConfig};
|
use matrix_sdk::{events::room::message::NoticeMessageEventContent, room::Joined};
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
events::room::message::{InReplyTo, Relation},
|
events::room::message::{InReplyTo, Relation},
|
||||||
events::room::message::{MessageEventContent, MessageType},
|
events::room::message::{MessageEventContent, MessageType},
|
||||||
|
@ -11,15 +9,6 @@ use matrix_sdk::{
|
||||||
Error as MatrixError,
|
Error as MatrixError,
|
||||||
};
|
};
|
||||||
use matrix_sdk::{identifiers::RoomId, identifiers::UserId, Client};
|
use matrix_sdk::{identifiers::RoomId, identifiers::UserId, Client};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
use crate::{config::Config, error::BotError};
|
|
||||||
|
|
||||||
fn cache_dir() -> Result<PathBuf, BotError> {
|
|
||||||
let mut dir = dirs::cache_dir().ok_or(BotError::NoCacheDirectoryError)?;
|
|
||||||
dir.push("matrix-dicebot");
|
|
||||||
Ok(dir)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts more detailed error messages out of a matrix SDK error.
|
/// Extracts more detailed error messages out of a matrix SDK error.
|
||||||
fn extract_error_message(error: MatrixError) -> String {
|
fn extract_error_message(error: MatrixError) -> String {
|
||||||
|
@ -31,15 +20,6 @@ fn extract_error_message(error: MatrixError) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the matrix client.
|
|
||||||
pub fn create_client(config: &Config) -> Result<Client, BotError> {
|
|
||||||
let cache_dir = cache_dir()?;
|
|
||||||
let client_config = ClientConfig::new().store_path(cache_dir);
|
|
||||||
let homeserver_url = Url::parse(&config.matrix_homeserver())?;
|
|
||||||
|
|
||||||
Ok(Client::new_with_config(homeserver_url, client_config)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieve a list of users in a given room.
|
/// Retrieve a list of users in a given room.
|
||||||
pub async fn get_users_in_room(
|
pub async fn get_users_in_room(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
|
|
|
@ -1,38 +1,19 @@
|
||||||
use crate::db::{errors::DataError, Variables};
|
|
||||||
use crate::error::BotError;
|
|
||||||
use crate::matrix;
|
|
||||||
use crate::{config::Config, db::sqlite::Database};
|
|
||||||
use futures::stream;
|
|
||||||
use futures::{StreamExt, TryFutureExt, TryStreamExt};
|
|
||||||
use log::info;
|
|
||||||
use matrix_sdk::{identifiers::UserId, Client};
|
|
||||||
use std::convert::TryFrom;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::error::BotError;
|
||||||
|
use crate::{config::Config, db::sqlite::Database};
|
||||||
|
use log::info;
|
||||||
use tenebrous_rpc::protos::dicebot::{
|
use tenebrous_rpc::protos::dicebot::{
|
||||||
dicebot_server::{Dicebot, DicebotServer},
|
dicebot_server::{Dicebot, DicebotServer},
|
||||||
rooms_list_reply::Room,
|
|
||||||
GetAllVariablesReply, GetAllVariablesRequest, RoomsListReply, SetVariableReply,
|
GetAllVariablesReply, GetAllVariablesRequest, RoomsListReply, SetVariableReply,
|
||||||
SetVariableRequest, UserIdRequest,
|
SetVariableRequest, UserIdRequest,
|
||||||
};
|
};
|
||||||
use tenebrous_rpc::protos::dicebot::{GetVariableReply, GetVariableRequest};
|
use tenebrous_rpc::protos::dicebot::{GetVariableReply, GetVariableRequest};
|
||||||
use tonic::{transport::Server, Code, Request, Response, Status};
|
use tonic::{transport::Server, Request, Response, Status};
|
||||||
|
|
||||||
impl From<BotError> for Status {
|
|
||||||
fn from(error: BotError) -> Status {
|
|
||||||
Status::new(Code::Internal, error.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DataError> for Status {
|
|
||||||
fn from(error: DataError) -> Status {
|
|
||||||
Status::new(Code::Internal, error.to_string())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DicebotRpcService {
|
pub struct DicebotRpcService {
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
db: Database,
|
db: Database,
|
||||||
client: Client,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
|
@ -41,17 +22,6 @@ impl Dicebot for DicebotRpcService {
|
||||||
&self,
|
&self,
|
||||||
request: Request<SetVariableRequest>,
|
request: Request<SetVariableRequest>,
|
||||||
) -> Result<Response<SetVariableReply>, Status> {
|
) -> Result<Response<SetVariableReply>, Status> {
|
||||||
let SetVariableRequest {
|
|
||||||
user_id,
|
|
||||||
room_id,
|
|
||||||
variable_name,
|
|
||||||
value,
|
|
||||||
} = request.into_inner();
|
|
||||||
|
|
||||||
self.db
|
|
||||||
.set_user_variable(&user_id, &room_id, &variable_name, value)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(Response::new(SetVariableReply { success: true }))
|
Ok(Response::new(SetVariableReply { success: true }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,76 +29,35 @@ impl Dicebot for DicebotRpcService {
|
||||||
&self,
|
&self,
|
||||||
request: Request<GetVariableRequest>,
|
request: Request<GetVariableRequest>,
|
||||||
) -> Result<Response<GetVariableReply>, Status> {
|
) -> Result<Response<GetVariableReply>, Status> {
|
||||||
let request = request.into_inner();
|
Ok(Response::new(GetVariableReply { value: 1 }))
|
||||||
let value = self
|
|
||||||
.db
|
|
||||||
.get_user_variable(&request.user_id, &request.room_id, &request.variable_name)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(Response::new(GetVariableReply { value }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_all_variables(
|
async fn get_all_variables(
|
||||||
&self,
|
&self,
|
||||||
request: Request<GetAllVariablesRequest>,
|
request: Request<GetAllVariablesRequest>,
|
||||||
) -> Result<Response<GetAllVariablesReply>, Status> {
|
) -> Result<Response<GetAllVariablesReply>, Status> {
|
||||||
let request = request.into_inner();
|
Ok(Response::new(GetAllVariablesReply {
|
||||||
let variables = self
|
variables: std::collections::HashMap::new(),
|
||||||
.db
|
}))
|
||||||
.get_user_variables(&request.user_id, &request.room_id)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(Response::new(GetAllVariablesReply { variables }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn rooms_for_user(
|
async fn rooms_for_user(
|
||||||
&self,
|
&self,
|
||||||
request: Request<UserIdRequest>,
|
request: Request<UserIdRequest>,
|
||||||
) -> Result<Response<RoomsListReply>, Status> {
|
) -> Result<Response<RoomsListReply>, Status> {
|
||||||
let UserIdRequest { user_id } = request.into_inner();
|
Ok(Response::new(RoomsListReply {
|
||||||
let user_id = UserId::try_from(user_id).map_err(BotError::from)?;
|
room_ids: Vec::new(),
|
||||||
|
}))
|
||||||
let rooms_for_user = matrix::get_rooms_for_user(&self.client, &user_id)
|
|
||||||
.err_into::<BotError>()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut rooms: Vec<Room> = stream::iter(rooms_for_user)
|
|
||||||
.filter_map(|room| async move {
|
|
||||||
let rooms = room.display_name().await.map(|room_name| Room {
|
|
||||||
room_id: room.room_id().to_string(),
|
|
||||||
display_name: room_name,
|
|
||||||
});
|
|
||||||
|
|
||||||
Some(rooms)
|
|
||||||
})
|
|
||||||
.err_into::<BotError>()
|
|
||||||
.try_collect()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let sort = |r1: &Room, r2: &Room| {
|
|
||||||
r1.display_name
|
|
||||||
.to_lowercase()
|
|
||||||
.cmp(&r2.display_name.to_lowercase())
|
|
||||||
};
|
|
||||||
|
|
||||||
rooms.sort_by(sort);
|
|
||||||
|
|
||||||
Ok(Response::new(RoomsListReply { rooms }))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn serve_grpc(
|
pub async fn serve_grpc(config: &Arc<Config>, db: &Database) -> Result<(), BotError> {
|
||||||
config: &Arc<Config>,
|
|
||||||
db: &Database,
|
|
||||||
client: &Client,
|
|
||||||
) -> Result<(), BotError> {
|
|
||||||
match config.rpc_addr() {
|
match config.rpc_addr() {
|
||||||
Some(addr) => {
|
Some(addr) => {
|
||||||
let addr = addr.parse()?;
|
let addr = addr.parse()?;
|
||||||
let rpc_service = DicebotRpcService {
|
let rpc_service = DicebotRpcService {
|
||||||
db: db.clone(),
|
db: db.clone(),
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
client: client.clone(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Serving Dicebot gRPC service on {}", addr);
|
info!("Serving Dicebot gRPC service on {}", addr);
|
||||||
|
|
|
@ -43,10 +43,5 @@ message UserIdRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
message RoomsListReply {
|
message RoomsListReply {
|
||||||
message Room {
|
repeated string room_ids = 1;
|
||||||
string room_id = 1;
|
|
||||||
string display_name = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
repeated Room rooms = 1;
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue