refactor(quark): port get/set_settings, get_unreads

#283
This commit is contained in:
Paul Makles
2024-04-07 18:10:11 +01:00
parent f6a565385e
commit 2de7598f8d
11 changed files with 69 additions and 68 deletions

View File

@@ -1,6 +1,26 @@
#[cfg(feature = "rocket")]
use rocket::FromForm;
use std::collections::HashMap;
/// HashMap of user settings
/// Each key is mapped to a tuple consisting of the
/// revision timestamp and serialised data (in JSON format)
pub type UserSettings = HashMap<String, (i64, String)>;
auto_derived!(
/// Options for fetching settings
pub struct OptionsFetchSettings {
/// Keys to fetch
pub keys: Vec<String>,
}
/// Additional options for inserting settings
#[cfg_attr(feature = "rocket", derive(FromForm))]
pub struct OptionsSetSettings {
/// Timestamp of settings change.
///
/// Used to avoid feedback loops.
pub timestamp: Option<i64>,
}
);

View File

@@ -28,7 +28,7 @@ pub struct DataOnboard {
/// This sets a new username, completes onboarding and allows a user to start using Revolt.
#[openapi(tag = "Onboarding")]
#[post("/complete", data = "<data>")]
pub async fn req(
pub async fn complete(
db: &State<Database>,
session: Session,
user: Option<User>,

View File

@@ -1,4 +1,6 @@
use revolt_quark::{authifier::models::Session, models::User};
use authifier::models::Session;
use revolt_database::User;
use rocket::serde::json::Json;
use serde::Serialize;
@@ -14,7 +16,7 @@ pub struct DataHello {
/// This will tell you whether the current account requires onboarding or whether you can continue to send requests as usual. You may skip calling this if you're restoring an existing session.
#[openapi(tag = "Onboarding")]
#[get("/hello")]
pub async fn req(_session: Session, user: Option<User>) -> Json<DataHello> {
pub async fn hello(_session: Session, user: Option<User>) -> Json<DataHello> {
Json(DataHello {
onboarding: user.is_none(),
})

View File

@@ -5,5 +5,5 @@ mod complete;
mod hello;
pub fn routes() -> (Vec<Route>, OpenApi) {
openapi_get_routes_spec![hello::req, complete::req]
openapi_get_routes_spec![hello::hello, complete::complete]
}

View File

@@ -5,5 +5,5 @@ mod subscribe;
mod unsubscribe;
pub fn routes() -> (Vec<Route>, OpenApi) {
openapi_get_routes_spec![subscribe::req, unsubscribe::req]
openapi_get_routes_spec![subscribe::subscribe, unsubscribe::unsubscribe]
}

View File

@@ -1,12 +1,10 @@
use revolt_quark::{
authifier::{
models::{Session, WebPushSubscription},
Authifier,
},
EmptyResponse, Error, Result,
use authifier::{
models::{Session, WebPushSubscription},
Authifier,
};
use revolt_result::{create_database_error, Result};
use rocket::{serde::json::Json, State};
use rocket_empty::EmptyResponse;
/// # Push Subscribe
///
@@ -15,7 +13,7 @@ use rocket::{serde::json::Json, State};
/// If an existing subscription exists on this session, it will be removed.
#[openapi(tag = "Web Push")]
#[post("/subscribe", data = "<data>")]
pub async fn req(
pub async fn subscribe(
authifier: &State<Authifier>,
mut session: Session,
data: Json<WebPushSubscription>,
@@ -25,8 +23,5 @@ pub async fn req(
.save(authifier)
.await
.map(|_| EmptyResponse)
.map_err(|_| Error::DatabaseError {
operation: "save",
with: "session",
})
.map_err(|_| create_database_error!("save", "session"))
}

View File

@@ -1,7 +1,7 @@
use revolt_quark::{
authifier::{models::Session, Authifier},
EmptyResponse, Error, Result,
};
use authifier::{models::Session, Authifier};
use revolt_result::{create_database_error, Result};
use rocket_empty::EmptyResponse;
use rocket::State;
@@ -10,14 +10,14 @@ use rocket::State;
/// Remove the Web Push subscription associated with the current session.
#[openapi(tag = "Web Push")]
#[post("/unsubscribe")]
pub async fn req(authifier: &State<Authifier>, mut session: Session) -> Result<EmptyResponse> {
pub async fn unsubscribe(
authifier: &State<Authifier>,
mut session: Session,
) -> Result<EmptyResponse> {
session.subscription = None;
session
.save(authifier)
.await
.map(|_| EmptyResponse)
.map_err(|_| Error::DatabaseError {
operation: "save",
with: "session",
})
.map_err(|_| create_database_error!("save", "session"))
}

View File

@@ -1,17 +1,8 @@
use revolt_quark::{
models::{User, UserSettings},
Db, Result,
};
use revolt_database::{Database, User};
use revolt_models::v0;
use revolt_result::Result;
use rocket::serde::json::Json;
use serde::{Deserialize, Serialize};
/// # Fetch Options
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct OptionsFetchSettings {
/// Keys to fetch
keys: Vec<String>,
}
use rocket::State;
/// # Fetch Settings
///
@@ -20,11 +11,11 @@ pub struct OptionsFetchSettings {
/// This will return an object with the requested keys, each value is a tuple of `(timestamp, value)`, the value is the previously uploaded data.
#[openapi(tag = "Sync")]
#[post("/settings/fetch", data = "<options>")]
pub async fn req(
db: &Db,
pub async fn fetch(
db: &State<Database>,
user: User,
options: Json<OptionsFetchSettings>,
) -> Result<Json<UserSettings>> {
options: Json<v0::OptionsFetchSettings>,
) -> Result<Json<v0::UserSettings>> {
db.fetch_user_settings(&user.id, &options.into_inner().keys)
.await
.map(Json)

View File

@@ -1,15 +1,17 @@
use revolt_quark::{
models::{ChannelUnread, User},
Db, Result,
};
use revolt_database::{Database, User};
use revolt_models::v0;
use revolt_result::Result;
use rocket::serde::json::Json;
use rocket::State;
/// # Fetch Unreads
///
/// Fetch information about unread state on channels.
#[openapi(tag = "Sync")]
#[get("/unreads")]
pub async fn req(db: &Db, user: User) -> Result<Json<Vec<ChannelUnread>>> {
db.fetch_unreads(&user.id).await.map(Json)
pub async fn unreads(db: &State<Database>, user: User) -> Result<Json<Vec<v0::ChannelUnread>>> {
db.fetch_unreads(&user.id)
.await
.map(|v| v.into_iter().map(|u| u.into()).collect())
.map(Json)
}

View File

@@ -6,5 +6,5 @@ mod get_unreads;
mod set_settings;
pub fn routes() -> (Vec<Route>, OpenApi) {
openapi_get_routes_spec![get_settings::req, set_settings::req, get_unreads::req]
openapi_get_routes_spec![get_settings::fetch, set_settings::set, get_unreads::unreads]
}

View File

@@ -1,33 +1,24 @@
use revolt_quark::models::User;
use revolt_quark::r#impl::UserSettingsImpl;
use revolt_quark::{Db, EmptyResponse, Result};
use revolt_database::{Database, User, UserSettingsImpl};
use revolt_models::v0;
use chrono::prelude::*;
use rocket::serde::json::Json;
use serde::{Deserialize, Serialize};
use revolt_result::Result;
use rocket::{serde::json::Json, State};
use rocket_empty::EmptyResponse;
use std::collections::HashMap;
type Data = HashMap<String, String>;
/// # Set Options
#[derive(FromForm, Serialize, Deserialize, JsonSchema)]
pub struct OptionsSetSettings {
/// Timestamp of settings change.
///
/// Used to avoid feedback loops.
timestamp: Option<i64>,
}
/// # Set Settings
///
/// Upload data to save to settings.
#[openapi(tag = "Sync")]
#[post("/settings/set?<options..>", data = "<data>")]
pub async fn req(
db: &Db,
pub async fn set(
db: &State<Database>,
user: User,
data: Json<Data>,
options: OptionsSetSettings,
options: v0::OptionsSetSettings,
) -> Result<EmptyResponse> {
let data = data.into_inner();
let current_time = Utc::now().timestamp_millis();