From f5b0dbdbacf2aa19ca9f9716db3cb7a311184bcc Mon Sep 17 00:00:00 2001 From: hole-thu Date: Sun, 27 Mar 2022 02:52:13 +0800 Subject: [PATCH] feat: set and user custom title --- src/api/comment.rs | 9 +++++++-- src/api/mod.rs | 2 ++ src/api/operation.rs | 21 ++++++++++++++++++--- src/api/post.rs | 14 ++++++++++---- src/main.rs | 2 ++ src/rds_models.rs | 26 ++++++++++++++++++++++++++ 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/src/api/comment.rs b/src/api/comment.rs index 306e241..a7531ae 100644 --- a/src/api/comment.rs +++ b/src/api/comment.rs @@ -16,7 +16,7 @@ use std::collections::HashMap; #[derive(FromForm)] pub struct CommentInput { pid: i32, - #[field(validate = len(1..4097))] + #[field(validate = len(1..12289))] text: String, use_title: Option, } @@ -118,7 +118,12 @@ pub async fn add_comment( NewComment { content: ci.text.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(), post_id: ci.pid, }, diff --git a/src/api/mod.rs b/src/api/mod.rs index a0d3aa0..94db3a7 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -84,6 +84,7 @@ pub enum PolicyError { IsReported, IsDeleted, NotAllowed, + TitleUsed, } #[derive(Debug)] @@ -112,6 +113,7 @@ impl<'r> Responder<'r, 'static> for APIError { PolicyError::IsReported => "内容被举报,处理中", PolicyError::IsDeleted => "内容被删除", PolicyError::NotAllowed => "不允许的操作", + PolicyError::TitleUsed => "头衔已被使用", } }) .respond_to(req), diff --git a/src/api/operation.rs b/src/api/operation.rs index b06fd97..48f7fe7 100644 --- a/src/api/operation.rs +++ b/src/api/operation.rs @@ -47,7 +47,7 @@ pub async fn delete(di: Form, user: CurrentUser, db: Db, rconn: Rds (p.author_hash.clone(), p) } - _ => { Err(NotAllowed) }?, + _ => Err(NotAllowed)?, }; if user.is_admin && !user.namehash.eq(&author_hash) { @@ -128,11 +128,11 @@ pub async fn block(bi: Form, user: CurrentUser, db: Db, rconn: RdsCo let nh_to_block = match bi.content_type.as_str() { "post" => Post::get(&db, &rconn, 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) { - { Err(NotAllowed) }?; + Err(NotAllowed)?; } blk.add(&nh_to_block).await?; @@ -150,3 +150,18 @@ pub async fn block(bi: Form, user: CurrentUser, db: Db, rconn: RdsCo }, })) } + +#[derive(FromForm)] +pub struct TitleInput { + #[field(validate = len(1..31))] + title: String, +} + +#[post("/title", data = "")] +pub async fn set_title(ti: Form, user: CurrentUser, rconn: RdsConn) -> JsonAPI { + if CustomTitle::set(&rconn, &user.namehash, &ti.title).await? { + code0!() + } else { + Err(TitleUsed)? + } +} diff --git a/src/api/post.rs b/src/api/post.rs index 5eda4f7..a3f35d4 100644 --- a/src/api/post.rs +++ b/src/api/post.rs @@ -14,9 +14,9 @@ use rocket::serde::{json::json, Serialize}; #[derive(FromForm)] pub struct PostInput { - #[field(validate = len(1..4097))] + #[field(validate = len(1..12289))] text: String, - #[field(validate = len(0..33))] + #[field(validate = len(0..97))] cw: String, allow_search: Option, use_title: Option, @@ -52,7 +52,7 @@ pub struct PostOutput { #[derive(FromForm)] pub struct CwInput { pid: i32, - #[field(validate = len(0..33))] + #[field(validate = len(0..97))] cw: String, } @@ -145,6 +145,7 @@ pub async fn get_list( Ok(json!({ "data": ps_data, "count": ps_data.len(), + "custom_title": CustomTitle::get(&rconn, &user.namehash).await?, "code": 0 })) } @@ -162,7 +163,12 @@ pub async fn publish_post( content: poi.text.to_string(), cw: poi.cw.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(), n_attentions: 1, allow_search: poi.allow_search.is_some(), diff --git a/src/main.rs b/src/main.rs index b06fb32..dac0d70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,6 +66,7 @@ async fn main() -> Result<(), rocket::Error> { api::systemlog::get_systemlog, api::operation::delete, api::operation::report, + api::operation::set_title, api::operation::block, ], ) @@ -96,4 +97,5 @@ fn init_database() { async fn clear_outdate_redis_data(rconn: &RdsConn) { rds_models::BannedUsers::clear(&rconn).await.unwrap(); + rds_models::CustomTitle::clear(&rconn).await.unwrap(); } diff --git a/src/rds_models.rs b/src/rds_models.rs index 6c1035c..8f958be 100644 --- a/src/rds_models.rs +++ b/src/rds_models.rs @@ -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_BLOCKED_COUNTER: &str = "hole_v2:blocked_counter"; const KEY_DANGEROUS_USERS: &str = "hole_thu:dangerous_users"; //兼容一下旧版 +const KEY_CUSTOM_TITLE: &str = "hole_v2:title"; const SYSTEMLOG_MAX_LEN: isize = 1000; 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 { + 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> { + 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;