147 lines
4.3 KiB
Rust
147 lines
4.3 KiB
Rust
use crate::model::processing::user::{UserBorrowedData, UserModel};
|
|
use crate::model::processing::PackError;
|
|
use crate::model::PackingContext;
|
|
use crate::service::MagnetarService;
|
|
use crate::web::auth::{AuthenticatedUser, MaybeUser};
|
|
use crate::web::{ApiError, ArgumentOutOfRange, ObjectNotFound};
|
|
use axum::extract::{Path, Query, State};
|
|
use axum::Json;
|
|
use futures::StreamExt;
|
|
use futures_util::TryStreamExt;
|
|
use itertools::Itertools;
|
|
use magnetar_common::util::lenient_parse_tag_decode;
|
|
use magnetar_sdk::endpoints::user::{
|
|
GetFollowRequestsSelf, GetFollowersById, GetFollowersSelf, GetFollowingById, GetFollowingSelf,
|
|
GetManyUsersById, GetUserByAcct, GetUserById, GetUserSelf, ManyUsersByIdReq,
|
|
};
|
|
use magnetar_sdk::endpoints::{Req, Res};
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
|
|
pub async fn handle_user_info_self(
|
|
Query(req): Query<Req<GetUserSelf>>,
|
|
State(service): State<Arc<MagnetarService>>,
|
|
AuthenticatedUser(user): AuthenticatedUser,
|
|
) -> Result<Json<Res<GetUserSelf>>, ApiError> {
|
|
let ctx = PackingContext::new(service, Some(user.clone())).await?;
|
|
let user = UserModel
|
|
.self_full_from_base(
|
|
&ctx,
|
|
&UserBorrowedData {
|
|
user: user.as_ref(),
|
|
avatar: None,
|
|
banner: None,
|
|
},
|
|
&req,
|
|
)
|
|
.await?;
|
|
Ok(Json(user))
|
|
}
|
|
|
|
pub async fn handle_user_info(
|
|
Path(id): Path<String>,
|
|
Query(req): Query<Req<GetUserById>>,
|
|
State(service): State<Arc<MagnetarService>>,
|
|
MaybeUser(self_user): MaybeUser,
|
|
) -> Result<Json<Res<GetUserById>>, ApiError> {
|
|
let ctx = PackingContext::new(service.clone(), self_user).await?;
|
|
let user_model = service
|
|
.db
|
|
.get_user_by_id(&id)
|
|
.await?
|
|
.ok_or(ObjectNotFound(id))?;
|
|
|
|
let user = UserModel
|
|
.foreign_full_from_base(
|
|
&ctx,
|
|
&UserBorrowedData {
|
|
user: &user_model,
|
|
avatar: None,
|
|
banner: None,
|
|
},
|
|
&req,
|
|
)
|
|
.await?;
|
|
Ok(Json(user))
|
|
}
|
|
|
|
pub async fn handle_user_info_by_acct(
|
|
Path(tag_str): Path<String>,
|
|
Query(req): Query<Req<GetUserByAcct>>,
|
|
State(service): State<Arc<MagnetarService>>,
|
|
MaybeUser(self_user): MaybeUser,
|
|
) -> Result<Json<Res<GetUserByAcct>>, ApiError> {
|
|
let mut tag = lenient_parse_tag_decode(&tag_str)?;
|
|
if matches!(&tag.host, Some(host) if host == &service.config.networking.host) {
|
|
tag.host = None;
|
|
}
|
|
|
|
let ctx = PackingContext::new(service.clone(), self_user).await?;
|
|
let user_model = service
|
|
.db
|
|
.get_user_by_tag(&tag.name, tag.host.as_deref())
|
|
.await?
|
|
.ok_or(ObjectNotFound(tag_str))?;
|
|
|
|
let user = UserModel
|
|
.foreign_full_from_base(
|
|
&ctx,
|
|
&UserBorrowedData {
|
|
user: &user_model,
|
|
avatar: None,
|
|
banner: None,
|
|
},
|
|
&req,
|
|
)
|
|
.await?;
|
|
Ok(Json(user))
|
|
}
|
|
|
|
pub async fn handle_user_by_id_many(
|
|
Query(ManyUsersByIdReq { id }): Query<Req<GetManyUsersById>>,
|
|
State(service): State<Arc<MagnetarService>>,
|
|
MaybeUser(user): MaybeUser,
|
|
) -> Result<Json<Res<GetManyUsersById>>, ApiError> {
|
|
if id.len() >= 100 {
|
|
return Err(ArgumentOutOfRange(stringify!(id).to_string()).into());
|
|
}
|
|
|
|
let users = service
|
|
.db
|
|
.get_many_users_by_id(&id.iter().cloned().sorted().dedup().collect::<Vec<_>>())
|
|
.await?;
|
|
|
|
let ctx = PackingContext::new(service, user.clone()).await?;
|
|
let user_model = UserModel;
|
|
|
|
let user_data = users
|
|
.iter()
|
|
.map(|user| UserBorrowedData {
|
|
user,
|
|
avatar: None,
|
|
banner: None,
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let futures = user_data
|
|
.iter()
|
|
.map(|user| user_model.base_from_existing(&ctx, user))
|
|
.collect::<Vec<_>>();
|
|
|
|
let users_proc = futures::stream::iter(futures)
|
|
.buffered(20)
|
|
.err_into::<PackError>()
|
|
.try_collect::<Vec<_>>()
|
|
.await?
|
|
.into_iter()
|
|
.map(|u| (u.id.0.id.clone(), u))
|
|
.collect::<HashMap<_, _>>();
|
|
|
|
let users_ordered = id
|
|
.iter()
|
|
.map(|ident| users_proc.get(ident).cloned())
|
|
.collect::<Vec<_>>();
|
|
|
|
Ok(Json(users_ordered))
|
|
}
|