diff --git a/Cargo.lock b/Cargo.lock index 842ac0d876162f1944ad35d4dc502e973f52233c..04236fb07936007e2f800ec52e4a1ac57ef8b6ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1907,7 +1907,7 @@ dependencies = [ [[package]] name = "revolt" -version = "0.2.7" +version = "0.2.8" dependencies = [ "bcrypt", "bitfield", diff --git a/Cargo.toml b/Cargo.toml index 0a7a76a1c45b9c71747639aa0ffd82675a78fa29..207a9c84a1e493262fe9f1fea6fc370e272e5050 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt" -version = "0.2.7" +version = "0.2.8" authors = ["Paul Makles <paulmakles@gmail.com>"] edition = "2018" diff --git a/src/database/channel.rs b/src/database/channel.rs index 6bad1b817e1dd38bfa56dff8d79273d32e10d569..21f4f85b9715d7837cf0824798ee5b0308b611ec 100644 --- a/src/database/channel.rs +++ b/src/database/channel.rs @@ -77,7 +77,7 @@ pub fn fetch_channel(id: &str) -> Result<Option<Channel>, String> { } } -pub fn fetch_channels(ids: &Vec<String>) -> Result<Option<Vec<Channel>>, String> { +pub fn fetch_channels(ids: &Vec<String>) -> Result<Vec<Channel>, String> { let mut missing = vec![]; let mut channels = vec![]; @@ -98,7 +98,7 @@ pub fn fetch_channels(ids: &Vec<String>) -> Result<Option<Vec<Channel>>, String> } if missing.len() == 0 { - return Ok(Some(channels)); + return Ok(channels); } let col = get_collection("channels"); @@ -117,7 +117,7 @@ pub fn fetch_channels(ids: &Vec<String>) -> Result<Option<Vec<Channel>>, String> } } - Ok(Some(channels)) + Ok(channels) } else { Err("Failed to fetch channel from database.".to_string()) } diff --git a/src/database/guild.rs b/src/database/guild.rs index 73a2698c0ac72cc949571637e447a6a72686e5cf..0ba3f6bb70222f95e6247a93be7340f9e794fe35 100644 --- a/src/database/guild.rs +++ b/src/database/guild.rs @@ -42,7 +42,7 @@ pub struct Guild { pub description: String, pub owner: String, - // ? FIXME: ADD: pub channels: Vec<Channel>, + pub channels: Vec<String>, pub invites: Vec<Invite>, pub bans: Vec<Ban>, diff --git a/src/database/migrations/scripts.rs b/src/database/migrations/scripts.rs index 72291af6e30bff192d2866ace91263472b720b74..c2041ea3babc4501d1b1f1cfc888c9f46771c5b8 100644 --- a/src/database/migrations/scripts.rs +++ b/src/database/migrations/scripts.rs @@ -2,6 +2,7 @@ use super::super::get_collection; use serde::{Serialize, Deserialize}; use mongodb::bson::{Bson, from_bson, doc}; +use mongodb::options::FindOptions; use log::info; #[derive(Serialize, Deserialize)] @@ -10,7 +11,7 @@ struct MigrationInfo { revision: i32 } -pub const LATEST_REVISION: i32 = 1; +pub const LATEST_REVISION: i32 = 2; pub fn migrate_database() { let migrations = get_collection("migrations"); @@ -48,6 +49,60 @@ pub fn run_migrations(revision: i32) -> i32 { info!("Running migration [revision 0]: Test migration system."); } + if revision <= 1 { + info!("Running migration [revision 1]: Add channels to guild object."); + + let col = get_collection("guilds"); + let guilds = col.find( + None, + FindOptions::builder() + .projection(doc! { "_id": 1 }) + .build() + ) + .expect("Failed to fetch guilds."); + + let result = get_collection("channels").find( + doc! { + "type": 2 + }, + FindOptions::builder() + .projection(doc! { "_id": 1, "guild": 1 }) + .build() + ).expect("Failed to fetch channels."); + + let mut channels = vec![]; + for doc in result { + let channel = doc.expect("Failed to fetch channel."); + let id = channel.get_str("_id").expect("Failed to get channel id.").to_string(); + let gid = channel.get_str("guild").expect("Failed to get guild id.").to_string(); + + channels.push(( id, gid )); + } + + for doc in guilds { + let guild = doc.expect("Failed to fetch guild."); + let id = guild.get_str("_id").expect("Failed to get guild id."); + + let list: Vec<String> = channels + .iter() + .filter(|x| x.1 == id) + .map(|x| x.0.clone()) + .collect(); + + col.update_one( + doc! { + "_id": id + }, + doc! { + "$set": { + "channels": list + } + }, + None + ).expect("Failed to update guild."); + } + } + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION } diff --git a/src/database/mod.rs b/src/database/mod.rs index 0c5c5348d4e5ee32618bac6b61289cd53e4f3f90..d473952e1207697a94627a73f12a3aa07e3519e0 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -1,4 +1,3 @@ -use mongodb::bson::doc; use mongodb::sync::{Client, Collection, Database}; use std::env; diff --git a/src/routes/channel.rs b/src/routes/channel.rs index 5d79050e4a96e4b1395a66fb0c085f03ff829dde..cfa631eebecbe1300ea0ef36bc74bf0f44f1a00e 100644 --- a/src/routes/channel.rs +++ b/src/routes/channel.rs @@ -138,11 +138,6 @@ pub fn channel(user: User, target: Channel) -> Option<Response> { "recipients": target.recipients, }))), 1 => { - /*if let Some(info) = target.fetch_data(doc! { - "name": 1, - "description": 1, - "owner": 1, - }) {*/ Some(Response::Success(json!({ "id": target.id, "type": target.channel_type, @@ -152,15 +147,8 @@ pub fn channel(user: User, target: Channel) -> Option<Response> { "owner": target.owner, "description": target.description, }))) - /*} else { - None - }*/ } 2 => { - /*if let Some(info) = target.fetch_data(doc! { - "name": 1, - "description": 1, - }) {*/ Some(Response::Success(json!({ "id": target.id, "type": target.channel_type, @@ -168,9 +156,6 @@ pub fn channel(user: User, target: Channel) -> Option<Response> { "name": target.name, "description": target.description, }))) - /*} else { - None - }*/ } _ => unreachable!(), } @@ -447,7 +432,8 @@ pub fn delete(user: User, target: Channel) -> Option<Response> { "$pull": { "invites": { "channel": &target.id - } + }, + "channels": &target.id } }, None, diff --git a/src/routes/guild.rs b/src/routes/guild.rs index 72d703100770ea444451c6ac98f2d89a88a6fdf3..517a36548a39be98f084b654d868f1bb03b0712c 100644 --- a/src/routes/guild.rs +++ b/src/routes/guild.rs @@ -2,7 +2,7 @@ use super::channel::ChannelType; use super::Response; use crate::database::guild::{fetch_member as get_member, get_invite, Guild, MemberKey}; use crate::database::{ - self, channel::fetch_channel, channel::Channel, Permission, PermissionCalculator, user::User + self, channel::{fetch_channel, fetch_channels}, channel::Channel, Permission, PermissionCalculator, user::User }; use crate::notifications::{ self, @@ -10,7 +10,7 @@ use crate::notifications::{ }; use crate::util::gen_token; -use mongodb::bson::{doc, from_bson, Bson}; +use mongodb::bson::{doc, Bson}; use mongodb::options::{FindOneOptions, FindOptions}; use rocket::request::Form; use rocket_contrib::json::Json; @@ -95,26 +95,15 @@ pub fn my_guilds(user: User) -> Response { pub fn guild(user: User, target: Guild) -> Option<Response> { with_permissions!(user, target); - let col = database::get_collection("channels"); - match col.find( - doc! { - "type": 2, - "guild": &target.id, - }, - None, - ) { + match fetch_channels(&target.channels) { Ok(results) => { let mut channels = vec![]; for item in results { - if let Ok(entry) = item { - if let Ok(channel) = from_bson(Bson::Document(entry)) as Result<Channel, _> { - channels.push(json!({ - "id": channel.id, - "name": channel.name, - "description": channel.description, - })); - } - } + channels.push(json!({ + "id": item.id, + "name": item.name, + "description": item.description, + })); } Some(Response::Success(json!({ @@ -127,7 +116,7 @@ pub fn guild(user: User, target: Guild) -> Option<Response> { } Err(_) => Some(Response::InternalServerError( json!({ "error": "Failed to fetch channels." }), - )), + )) } } @@ -305,20 +294,39 @@ pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> O ) .is_ok() { - notifications::send_message_threaded( - None, - target.id.clone(), - Notification::guild_channel_create(ChannelCreate { - id: target.id.clone(), - channel: id.clone(), - name: name.clone(), - description: description.clone(), - }), - ); - - Some(Response::Success(json!({ "id": &id }))) + if database::get_collection("guilds") + .update_one( + doc! { + "_id": &target.id + }, + doc! { + "$addToSet": { + "channels": &id + } + }, + None + ) + .is_ok() + { + notifications::send_message_threaded( + None, + target.id.clone(), + Notification::guild_channel_create(ChannelCreate { + id: target.id.clone(), + channel: id.clone(), + name: name.clone(), + description: description.clone(), + }), + ); + + Some(Response::Success(json!({ "id": &id }))) + } else { + Some(Response::InternalServerError( + json!({ "error": "Couldn't save channel list." }), + )) + } } else { - Some(Response::BadRequest( + Some(Response::InternalServerError( json!({ "error": "Couldn't create channel." }), )) } diff --git a/src/routes/root.rs b/src/routes/root.rs index bb9fa55a09863451928a2225028ac31240c615b5..269cb55eeb5c69ec2327c110193ee850a83061fa 100644 --- a/src/routes/root.rs +++ b/src/routes/root.rs @@ -6,11 +6,11 @@ use mongodb::bson::doc; #[get("/")] pub fn root() -> Response { Response::Success(json!({ - "revolt": "0.2.7", + "revolt": "0.2.8", "version": { "major": 0, "minor": 2, - "patch": 7 + "patch": 8 } })) }