Browse Source

调整热度算法 & 举报自动发洞

master
hole-thu 3 years ago
parent
commit
fcc8ee3b15
  1. 4
      src/api/attention.rs
  2. 2
      src/api/comment.rs
  3. 6
      src/api/mod.rs
  4. 42
      src/api/operation.rs
  5. 2
      src/api/systemlog.rs
  6. 2
      src/main.rs
  7. 4
      src/rds_models.rs

4
src/api/attention.rs

@ -25,7 +25,7 @@ pub async fn attention_post(
rconn: RdsConn, rconn: RdsConn,
) -> JsonAPI { ) -> JsonAPI {
// 临时用户不允许手动关注 // 临时用户不允许手动关注
user.id.ok_or_else(|| YouAreTmp)?; user.id.ok_or(YouAreTmp)?;
let mut p = Post::get(&db, &rconn, ai.pid).await?; let mut p = Post::get(&db, &rconn, ai.pid).await?;
p.check_permission(&user, "r")?; p.check_permission(&user, "r")?;
@ -35,7 +35,7 @@ pub async fn attention_post(
if att.has(ai.pid).await? != switch_to { if att.has(ai.pid).await? != switch_to {
if switch_to { if switch_to {
att.add(ai.pid).await?; att.add(ai.pid).await?;
delta = 1; delta = (p.n_attentions < 3 * p.n_comments) as i32;
} else { } else {
att.remove(ai.pid).await?; att.remove(ai.pid).await?;
delta = -1; delta = -1;

2
src/api/comment.rs

@ -146,7 +146,7 @@ pub async fn add_comment(
at_delta = 1; at_delta = 1;
att.add(p.id).await?; att.add(p.id).await?;
} else { } else {
hs_delta = 1; hs_delta = (p.n_comments < 3 * p.n_attentions) as i32;
at_delta = 0; at_delta = 0;
} }

6
src/api/mod.rs

@ -115,6 +115,7 @@ pub enum PolicyError {
NotAllowed, NotAllowed,
TitleUsed, TitleUsed,
YouAreTmp, YouAreTmp,
NoReason,
} }
#[derive(Debug)] #[derive(Debug)]
@ -138,7 +139,8 @@ impl<'r> Responder<'r, 'static> for APIError {
PolicyError::IsDeleted => "内容被删除", PolicyError::IsDeleted => "内容被删除",
PolicyError::NotAllowed => "不允许的操作", PolicyError::NotAllowed => "不允许的操作",
PolicyError::TitleUsed => "头衔已被使用", PolicyError::TitleUsed => "头衔已被使用",
PolicyError::YouAreTmp => "临时用户只可发布内容和进入单个洞" PolicyError::YouAreTmp => "临时用户只可发布内容和进入单个洞",
PolicyError::NoReason => "未填写理由",
} }
}) })
.respond_to(req), .respond_to(req),
@ -219,7 +221,7 @@ impl UGC for Post {
self.is_deleted self.is_deleted
} }
fn extra_delete_condition(&self) -> bool { fn extra_delete_condition(&self) -> bool {
self.n_comments == 0 self.n_comments == 0 && !self.content.starts_with("[系统自动代发]\n")
} }
async fn do_set_deleted(&mut self, db: &Db) -> API<()> { async fn do_set_deleted(&mut self, db: &Db) -> API<()> {
update!(*self, posts, db, { is_deleted, to true }); update!(*self, posts, db, { is_deleted, to true });

42
src/api/operation.rs

@ -89,29 +89,49 @@ pub struct ReportInput {
#[post("/report", data = "<ri>")] #[post("/report", data = "<ri>")]
pub async fn report(ri: Form<ReportInput>, user: CurrentUser, db: Db, rconn: RdsConn) -> JsonAPI { pub async fn report(ri: Form<ReportInput>, user: CurrentUser, db: Db, rconn: RdsConn) -> JsonAPI {
// 临时用户不允许举报 // 临时用户不允许举报
user.id.ok_or_else(|| NotAllowed)?; user.id.ok_or(NotAllowed)?;
// 被拉黑30次不允许举报
(BlockCounter::get_count(&rconn, &user.namehash)
.await?
.unwrap_or(0)
< 30)
.then(|| ())
.ok_or(NotAllowed)?;
(!ri.reason.is_empty()).then(|| ()).ok_or(NoReason)?;
let mut p = Post::get(&db, &rconn, ri.pid).await?; let mut p = Post::get(&db, &rconn, ri.pid).await?;
update!(p, posts, &db, { is_reported, to true }); update!(p, posts, &db, { is_reported, to true });
p.refresh_cache(&rconn, false).await; p.refresh_cache(&rconn, false).await;
Systemlog { Systemlog {
user_hash: user.namehash, user_hash: user.namehash.to_string(),
action_type: LogType::Report, action_type: LogType::Report,
target: format!( target: format!("#{}", ri.pid),
"#{} {}",
ri.pid,
if ri.reason.starts_with("评论区") {
"评论区"
} else {
""
}
),
detail: ri.reason.clone(), detail: ri.reason.clone(),
time: Local::now(), time: Local::now(),
} }
.create(&rconn) .create(&rconn)
.await?; .await?;
// 自动发布一条洞
let p = Post::create(
&db,
NewPost {
content: format!("[系统自动代发]\n我举报了 #{}\n理由: {}", &p.id, &ri.reason),
cw: "举报".to_string(),
author_hash: user.namehash.to_string(),
author_title: String::default(),
is_tmp: false,
n_attentions: 1,
allow_search: true,
},
)
.await?;
Attention::init(&user.namehash, &rconn).add(p.id).await?;
p.refresh_cache(&rconn, true).await;
code0!() code0!()
} }

2
src/api/systemlog.rs

@ -19,7 +19,7 @@ pub async fn get_systemlog(user: CurrentUser, rh: &State<RandomHasher>, rconn: R
"type": log.action_type, "type": log.action_type,
"user": look!(log.user_hash), "user": look!(log.user_hash),
"timestamp": log.time.timestamp(), "timestamp": log.time.timestamp(),
"detail": format!("{}\n{}", &log.target, if user.is_admin || !log.action_type.contains_ugc() { &log.detail } else { "" }) "detail": format!("{}\n{}", &log.target, &log.detail),
}) })
).collect::<Vec<Value>>(), ).collect::<Vec<Value>>(),
})) }))

2
src/main.rs

@ -46,7 +46,7 @@ async fn main() -> Result<(), rocket::Error> {
clear_outdate_redis_data(&rconn.clone()).await; clear_outdate_redis_data(&rconn.clone()).await;
tokio::spawn(async move { tokio::spawn(async move {
loop { loop {
sleep(Duration::from_secs(4 * 60 * 60)).await; sleep(Duration::from_secs(3 * 60 * 60)).await;
models::Post::annealing(establish_connection(), &rconn).await; models::Post::annealing(establish_connection(), &rconn).await;
} }
}); });

4
src/rds_models.rs

@ -104,6 +104,7 @@ pub enum LogType {
Ban, Ban,
} }
/*
impl LogType { impl LogType {
pub fn contains_ugc(&self) -> bool { pub fn contains_ugc(&self) -> bool {
match self { match self {
@ -112,6 +113,7 @@ impl LogType {
} }
} }
} }
*/
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
#[serde(crate = "rocket::serde")] #[serde(crate = "rocket::serde")]
@ -238,7 +240,7 @@ impl AutoBlockRank {
pub async fn get(rconn: &RdsConn, namehash: &str) -> RedisResult<u8> { pub async fn get(rconn: &RdsConn, namehash: &str) -> RedisResult<u8> {
let rank: Option<u8> = rconn.clone().hget(KEY_AUTO_BLOCK_RANK, namehash).await?; let rank: Option<u8> = rconn.clone().hget(KEY_AUTO_BLOCK_RANK, namehash).await?;
Ok(rank.unwrap_or(2)) Ok(rank.unwrap_or(4))
} }
pub async fn clear(rconn: &RdsConn) -> RedisResult<()> { pub async fn clear(rconn: &RdsConn) -> RedisResult<()> {

Loading…
Cancel
Save