mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 05:26:59 +00:00
feat(messages): implement fetch, query, search
This commit is contained in:
10
src/main.rs
10
src/main.rs
@@ -1,17 +1,9 @@
|
||||
#![feature(proc_macro_hygiene, decl_macro)]
|
||||
#![feature(async_closure)]
|
||||
#![feature(const_option)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rocket;
|
||||
#[macro_use]
|
||||
extern crate serde_json;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate impl_ops;
|
||||
#[macro_use]
|
||||
extern crate bitfield;
|
||||
extern crate ctrlc;
|
||||
|
||||
//pub mod database;
|
||||
@@ -84,7 +76,7 @@ async fn launch_web() {
|
||||
.to_cors()
|
||||
.expect("Failed to create CORS.");
|
||||
|
||||
let mut config = Config {
|
||||
let config = Config {
|
||||
email_verification: /*if *USE_EMAIL {
|
||||
EmailVerification::Enabled {
|
||||
smtp: SMTPSettings {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1,22 +1,15 @@
|
||||
use std::collections::HashSet;
|
||||
|
||||
use revolt_quark::{Error, Result};
|
||||
|
||||
use futures::{try_join, StreamExt};
|
||||
use mongodb::{
|
||||
bson::{doc, from_document},
|
||||
options::FindOptions,
|
||||
use revolt_quark::{
|
||||
models::{
|
||||
message::{BulkMessageResponse, MessageSort},
|
||||
User,
|
||||
},
|
||||
perms,
|
||||
Db, Error, Ref, Result,
|
||||
};
|
||||
use rocket::serde::json::Value;
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Serialize, Deserialize, FromFormField)]
|
||||
pub enum Sort {
|
||||
Latest,
|
||||
Oldest,
|
||||
}
|
||||
|
||||
#[derive(Validate, Serialize, Deserialize, FromForm)]
|
||||
pub struct Options {
|
||||
#[validate(range(min = 1, max = 100))]
|
||||
@@ -25,7 +18,7 @@ pub struct Options {
|
||||
before: Option<String>,
|
||||
#[validate(length(min = 26, max = 26))]
|
||||
after: Option<String>,
|
||||
sort: Option<Sort>,
|
||||
sort: Option<MessageSort>,
|
||||
// Specifying 'nearby' ignores 'before', 'after' and 'sort'.
|
||||
// It will also take half of limit rounded as the limits to each side.
|
||||
// It also fetches the message ID specified.
|
||||
@@ -36,8 +29,42 @@ pub struct Options {
|
||||
|
||||
#[get("/<target>/messages?<options..>")]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
db: &Db,
|
||||
user: User,
|
||||
target: Ref,
|
||||
options: Options,
|
||||
) -> Result<Value> {
|
||||
todo!()
|
||||
) -> Result<Json<BulkMessageResponse>> {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -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 mongodb::{
|
||||
bson::{doc, from_document},
|
||||
options::FindOptions,
|
||||
};
|
||||
use rocket::serde::json::{Json, Value};
|
||||
use rocket::serde::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
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)]
|
||||
pub struct Options {
|
||||
#[validate(length(min = 1, max = 64))]
|
||||
@@ -33,15 +15,40 @@ pub struct Options {
|
||||
before: Option<String>,
|
||||
#[validate(length(min = 26, max = 26))]
|
||||
after: Option<String>,
|
||||
#[serde(default = "Sort::default")]
|
||||
sort: Sort,
|
||||
#[serde(default = "MessageSort::default")]
|
||||
sort: MessageSort,
|
||||
include_users: Option<bool>,
|
||||
}
|
||||
|
||||
#[post("/<target>/search", data = "<options>")]
|
||||
pub async fn req(
|
||||
/*user: UserRef, target: Ref,*/ target: String,
|
||||
options: Json<Options>,
|
||||
) -> Result<Value> {
|
||||
todo!()
|
||||
pub async fn req(db: &Db, user: User, target: Ref, options: Json<Options>) -> Result<Json<BulkMessageResponse>> {
|
||||
let options = options.into_inner();
|
||||
options
|
||||
.validate()
|
||||
.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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user