feat(messages): implement fetch, query, search

This commit is contained in:
Paul Makles
2022-02-10 12:53:26 +00:00
parent a6cec559b1
commit a4cbbfea51
4 changed files with 85 additions and 56 deletions

View File

@@ -1,17 +1,9 @@
#![feature(proc_macro_hygiene, decl_macro)]
#![feature(async_closure)]
#![feature(const_option)]
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
#[macro_use] #[macro_use]
extern crate serde_json; extern crate serde_json;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
#[macro_use]
extern crate impl_ops;
#[macro_use]
extern crate bitfield;
extern crate ctrlc; extern crate ctrlc;
//pub mod database; //pub mod database;
@@ -84,7 +76,7 @@ async fn launch_web() {
.to_cors() .to_cors()
.expect("Failed to create CORS."); .expect("Failed to create CORS.");
let mut config = Config { let config = Config {
email_verification: /*if *USE_EMAIL { email_verification: /*if *USE_EMAIL {
EmailVerification::Enabled { EmailVerification::Enabled {
smtp: SMTPSettings { smtp: SMTPSettings {

View File

@@ -1,4 +1,7 @@
use revolt_quark::{models::{User, Message}, perms, Db, Error, Ref, Result}; use revolt_quark::{
models::{Message, User},
perms, Db, Error, Ref, Result,
};
use rocket::serde::json::Json; use rocket::serde::json::Json;

View File

@@ -1,22 +1,15 @@
use std::collections::HashSet; use revolt_quark::{
models::{
use revolt_quark::{Error, Result}; message::{BulkMessageResponse, MessageSort},
User,
use futures::{try_join, StreamExt}; },
use mongodb::{ perms,
bson::{doc, from_document}, Db, Error, Ref, Result,
options::FindOptions,
}; };
use rocket::serde::json::Value; use rocket::serde::json::Json;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
#[derive(Serialize, Deserialize, FromFormField)]
pub enum Sort {
Latest,
Oldest,
}
#[derive(Validate, Serialize, Deserialize, FromForm)] #[derive(Validate, Serialize, Deserialize, FromForm)]
pub struct Options { pub struct Options {
#[validate(range(min = 1, max = 100))] #[validate(range(min = 1, max = 100))]
@@ -25,7 +18,7 @@ pub struct Options {
before: Option<String>, before: Option<String>,
#[validate(length(min = 26, max = 26))] #[validate(length(min = 26, max = 26))]
after: Option<String>, after: Option<String>,
sort: Option<Sort>, sort: Option<MessageSort>,
// Specifying 'nearby' ignores 'before', 'after' and 'sort'. // Specifying 'nearby' ignores 'before', 'after' and 'sort'.
// It will also take half of limit rounded as the limits to each side. // It will also take half of limit rounded as the limits to each side.
// It also fetches the message ID specified. // It also fetches the message ID specified.
@@ -36,8 +29,42 @@ pub struct Options {
#[get("/<target>/messages?<options..>")] #[get("/<target>/messages?<options..>")]
pub async fn req( pub async fn req(
/*user: UserRef, target: Ref,*/ target: String, db: &Db,
user: User,
target: Ref,
options: Options, options: Options,
) -> Result<Value> { ) -> Result<Json<BulkMessageResponse>> {
todo!() options
.validate()
.map_err(|error| Error::FailedValidation { error })?;
if let Some(MessageSort::Relevance) = options.sort {
return Err(Error::InvalidOperation);
}
let channel = target.as_channel(db).await?;
if !perms(&user)
.channel(&channel)
.calc_channel(db)
.await
.get_view()
{
return Err(Error::NotFound);
}
let Options {
limit,
before,
after,
sort,
nearby,
include_users,
..
} = options;
let messages = db
.fetch_messages(channel.id(), limit, before, after, sort, nearby)
.await?;
BulkMessageResponse::transform(db, &channel, messages, include_users).await.map(Json)
} }

View File

@@ -1,27 +1,9 @@
use revolt_quark::Result; use revolt_quark::{models::{User, message::{MessageSort, BulkMessageResponse}}, Ref, Error, Result, Db, perms};
use futures::StreamExt; use rocket::serde::json::Json;
use mongodb::{
bson::{doc, from_document},
options::FindOptions,
};
use rocket::serde::json::{Json, Value};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use validator::Validate; use validator::Validate;
#[derive(Serialize, Deserialize, FromFormField)]
pub enum Sort {
Relevance,
Latest,
Oldest,
}
impl Default for Sort {
fn default() -> Sort {
Sort::Relevance
}
}
#[derive(Validate, Serialize, Deserialize, FromForm)] #[derive(Validate, Serialize, Deserialize, FromForm)]
pub struct Options { pub struct Options {
#[validate(length(min = 1, max = 64))] #[validate(length(min = 1, max = 64))]
@@ -33,15 +15,40 @@ pub struct Options {
before: Option<String>, before: Option<String>,
#[validate(length(min = 26, max = 26))] #[validate(length(min = 26, max = 26))]
after: Option<String>, after: Option<String>,
#[serde(default = "Sort::default")] #[serde(default = "MessageSort::default")]
sort: Sort, sort: MessageSort,
include_users: Option<bool>, include_users: Option<bool>,
} }
#[post("/<target>/search", data = "<options>")] #[post("/<target>/search", data = "<options>")]
pub async fn req( pub async fn req(db: &Db, user: User, target: Ref, options: Json<Options>) -> Result<Json<BulkMessageResponse>> {
/*user: UserRef, target: Ref,*/ target: String, let options = options.into_inner();
options: Json<Options>, options
) -> Result<Value> { .validate()
todo!() .map_err(|error| Error::FailedValidation { error })?;
let channel = target.as_channel(db).await?;
if !perms(&user)
.channel(&channel)
.calc_channel(db)
.await
.get_view()
{
return Err(Error::NotFound);
}
let Options {
query,
limit,
before,
after,
sort,
include_users
} = options;
let messages = db
.search_messages(channel.id(), &query, limit, before, after, sort)
.await?;
BulkMessageResponse::transform(db, &channel, messages, include_users).await.map(Json)
} }