feat: set and user custom title
This commit is contained in:
@@ -16,7 +16,7 @@ use std::collections::HashMap;
|
|||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
pub struct CommentInput {
|
pub struct CommentInput {
|
||||||
pid: i32,
|
pid: i32,
|
||||||
#[field(validate = len(1..4097))]
|
#[field(validate = len(1..12289))]
|
||||||
text: String,
|
text: String,
|
||||||
use_title: Option<i8>,
|
use_title: Option<i8>,
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,12 @@ pub async fn add_comment(
|
|||||||
NewComment {
|
NewComment {
|
||||||
content: ci.text.to_string(),
|
content: ci.text.to_string(),
|
||||||
author_hash: user.namehash.to_string(),
|
author_hash: user.namehash.to_string(),
|
||||||
author_title: "".to_string(),
|
author_title: (if ci.use_title.is_some() {
|
||||||
|
CustomTitle::get(&rconn, &user.namehash).await?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
is_tmp: user.id.is_none(),
|
is_tmp: user.id.is_none(),
|
||||||
post_id: ci.pid,
|
post_id: ci.pid,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ pub enum PolicyError {
|
|||||||
IsReported,
|
IsReported,
|
||||||
IsDeleted,
|
IsDeleted,
|
||||||
NotAllowed,
|
NotAllowed,
|
||||||
|
TitleUsed,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -112,6 +113,7 @@ impl<'r> Responder<'r, 'static> for APIError {
|
|||||||
PolicyError::IsReported => "内容被举报,处理中",
|
PolicyError::IsReported => "内容被举报,处理中",
|
||||||
PolicyError::IsDeleted => "内容被删除",
|
PolicyError::IsDeleted => "内容被删除",
|
||||||
PolicyError::NotAllowed => "不允许的操作",
|
PolicyError::NotAllowed => "不允许的操作",
|
||||||
|
PolicyError::TitleUsed => "头衔已被使用",
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.respond_to(req),
|
.respond_to(req),
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ pub async fn delete(di: Form<DeleteInput>, user: CurrentUser, db: Db, rconn: Rds
|
|||||||
|
|
||||||
(p.author_hash.clone(), p)
|
(p.author_hash.clone(), p)
|
||||||
}
|
}
|
||||||
_ => { Err(NotAllowed) }?,
|
_ => Err(NotAllowed)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
if user.is_admin && !user.namehash.eq(&author_hash) {
|
if user.is_admin && !user.namehash.eq(&author_hash) {
|
||||||
@@ -128,11 +128,11 @@ pub async fn block(bi: Form<BlockInput>, user: CurrentUser, db: Db, rconn: RdsCo
|
|||||||
let nh_to_block = match bi.content_type.as_str() {
|
let nh_to_block = match bi.content_type.as_str() {
|
||||||
"post" => Post::get(&db, &rconn, bi.id).await?.author_hash,
|
"post" => Post::get(&db, &rconn, bi.id).await?.author_hash,
|
||||||
"comment" => Comment::get(&db, bi.id).await?.author_hash,
|
"comment" => Comment::get(&db, bi.id).await?.author_hash,
|
||||||
_ => { Err(NotAllowed) }?,
|
_ => Err(NotAllowed)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
if nh_to_block.eq(&user.namehash) {
|
if nh_to_block.eq(&user.namehash) {
|
||||||
{ Err(NotAllowed) }?;
|
Err(NotAllowed)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
blk.add(&nh_to_block).await?;
|
blk.add(&nh_to_block).await?;
|
||||||
@@ -150,3 +150,18 @@ pub async fn block(bi: Form<BlockInput>, user: CurrentUser, db: Db, rconn: RdsCo
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
pub struct TitleInput {
|
||||||
|
#[field(validate = len(1..31))]
|
||||||
|
title: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/title", data = "<ti>")]
|
||||||
|
pub async fn set_title(ti: Form<TitleInput>, user: CurrentUser, rconn: RdsConn) -> JsonAPI {
|
||||||
|
if CustomTitle::set(&rconn, &user.namehash, &ti.title).await? {
|
||||||
|
code0!()
|
||||||
|
} else {
|
||||||
|
Err(TitleUsed)?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ use rocket::serde::{json::json, Serialize};
|
|||||||
|
|
||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
pub struct PostInput {
|
pub struct PostInput {
|
||||||
#[field(validate = len(1..4097))]
|
#[field(validate = len(1..12289))]
|
||||||
text: String,
|
text: String,
|
||||||
#[field(validate = len(0..33))]
|
#[field(validate = len(0..97))]
|
||||||
cw: String,
|
cw: String,
|
||||||
allow_search: Option<i8>,
|
allow_search: Option<i8>,
|
||||||
use_title: Option<i8>,
|
use_title: Option<i8>,
|
||||||
@@ -52,7 +52,7 @@ pub struct PostOutput {
|
|||||||
#[derive(FromForm)]
|
#[derive(FromForm)]
|
||||||
pub struct CwInput {
|
pub struct CwInput {
|
||||||
pid: i32,
|
pid: i32,
|
||||||
#[field(validate = len(0..33))]
|
#[field(validate = len(0..97))]
|
||||||
cw: String,
|
cw: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +145,7 @@ pub async fn get_list(
|
|||||||
Ok(json!({
|
Ok(json!({
|
||||||
"data": ps_data,
|
"data": ps_data,
|
||||||
"count": ps_data.len(),
|
"count": ps_data.len(),
|
||||||
|
"custom_title": CustomTitle::get(&rconn, &user.namehash).await?,
|
||||||
"code": 0
|
"code": 0
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -162,7 +163,12 @@ pub async fn publish_post(
|
|||||||
content: poi.text.to_string(),
|
content: poi.text.to_string(),
|
||||||
cw: poi.cw.to_string(),
|
cw: poi.cw.to_string(),
|
||||||
author_hash: user.namehash.to_string(),
|
author_hash: user.namehash.to_string(),
|
||||||
author_title: "".to_string(),
|
author_title: (if poi.use_title.is_some() {
|
||||||
|
CustomTitle::get(&rconn, &user.namehash).await?
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.unwrap_or_default(),
|
||||||
is_tmp: user.id.is_none(),
|
is_tmp: user.id.is_none(),
|
||||||
n_attentions: 1,
|
n_attentions: 1,
|
||||||
allow_search: poi.allow_search.is_some(),
|
allow_search: poi.allow_search.is_some(),
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ async fn main() -> Result<(), rocket::Error> {
|
|||||||
api::systemlog::get_systemlog,
|
api::systemlog::get_systemlog,
|
||||||
api::operation::delete,
|
api::operation::delete,
|
||||||
api::operation::report,
|
api::operation::report,
|
||||||
|
api::operation::set_title,
|
||||||
api::operation::block,
|
api::operation::block,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@@ -96,4 +97,5 @@ fn init_database() {
|
|||||||
|
|
||||||
async fn clear_outdate_redis_data(rconn: &RdsConn) {
|
async fn clear_outdate_redis_data(rconn: &RdsConn) {
|
||||||
rds_models::BannedUsers::clear(&rconn).await.unwrap();
|
rds_models::BannedUsers::clear(&rconn).await.unwrap();
|
||||||
|
rds_models::CustomTitle::clear(&rconn).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ const KEY_SYSTEMLOG: &str = "hole_v2:systemlog_list";
|
|||||||
const KEY_BANNED_USERS: &str = "hole_v2:banned_user_hash_list";
|
const KEY_BANNED_USERS: &str = "hole_v2:banned_user_hash_list";
|
||||||
const KEY_BLOCKED_COUNTER: &str = "hole_v2:blocked_counter";
|
const KEY_BLOCKED_COUNTER: &str = "hole_v2:blocked_counter";
|
||||||
const KEY_DANGEROUS_USERS: &str = "hole_thu:dangerous_users"; //兼容一下旧版
|
const KEY_DANGEROUS_USERS: &str = "hole_thu:dangerous_users"; //兼容一下旧版
|
||||||
|
const KEY_CUSTOM_TITLE: &str = "hole_v2:title";
|
||||||
|
|
||||||
const SYSTEMLOG_MAX_LEN: isize = 1000;
|
const SYSTEMLOG_MAX_LEN: isize = 1000;
|
||||||
pub const BLOCK_THRESHOLD: i32 = 10;
|
pub const BLOCK_THRESHOLD: i32 = 10;
|
||||||
@@ -183,4 +184,29 @@ impl DangerousUser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CustomTitle;
|
||||||
|
|
||||||
|
impl CustomTitle {
|
||||||
|
// return false if title exits
|
||||||
|
pub async fn set(rconn: &RdsConn, namehash: &str, title: &str) -> RedisResult<bool> {
|
||||||
|
let mut rconn = rconn.clone();
|
||||||
|
if rconn.hexists(KEY_CUSTOM_TITLE, title).await? {
|
||||||
|
Ok(false)
|
||||||
|
} else {
|
||||||
|
rconn.hset(KEY_CUSTOM_TITLE, namehash, title).await?;
|
||||||
|
rconn.hset(KEY_CUSTOM_TITLE, title, namehash).await?;
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get(rconn: &RdsConn, namehash: &str) -> RedisResult<Option<String>> {
|
||||||
|
rconn.clone().hget(KEY_CUSTOM_TITLE, namehash).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn clear(rconn: &RdsConn) -> RedisResult<()> {
|
||||||
|
rconn.clone().del(KEY_CUSTOM_TITLE).await
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) use init;
|
pub(crate) use init;
|
||||||
|
|||||||
Reference in New Issue
Block a user