diff --git a/packages/backend-rs/src/util/check_word_mute.rs b/packages/backend-rs/src/util/check_word_mute.rs index 085383fc..865dc18c 100644 --- a/packages/backend-rs/src/util/check_word_mute.rs +++ b/packages/backend-rs/src/util/check_word_mute.rs @@ -1,10 +1,10 @@ use crate::database::JsDbConn; use crate::model::entity::{drive_file, note}; +use crate::prelude::*; use once_cell::sync::Lazy; use regex::Regex; use sea_orm::prelude::*; -// FIXME: remove this type #[napi_derive::napi(object)] pub struct NoteLike { pub file_ids: Vec, @@ -15,82 +15,76 @@ pub struct NoteLike { pub reply_id: Option, } -async fn full_text(conn: &JsDbConn, note: NoteLike) -> String { - let mut to_return = format!( - "{}\n{}\n", - note.text.unwrap_or_default(), - note.cw.unwrap_or_default(), - ); +async fn all_texts(conn: &JsDbConn, note: NoteLike) -> napi::Result> { + let mut texts: Vec = vec![]; + + if let Some(text) = note.text { + texts.push(text); + } + if let Some(cw) = note.cw { + texts.push(cw); + } for file_id in note.file_ids { if let Some(alt_text) = drive_file::Entity::find_by_id(file_id) .one(conn.inner()) .await - .expect("Failed to connect to the database") - .expect("file_id is invalid") + .map_err(to_napi_error)? + .ok_or_else(|| to_napi_error("file_id is invalid"))? .comment { - to_return.push_str(alt_text.as_str()); - to_return.push('\n'); + texts.push(alt_text); } } - if note.renote_id.is_some() { - to_return.push_str( - note::Entity::find_by_id(note.renote_id.unwrap()) - .one(conn.inner()) - .await - .expect("Failed to connect to the database") - .expect("renote_id is invalid") - .text - .unwrap_or_default() - .as_str(), - ); - to_return.push('\n'); + if let Some(renote_id) = note.renote_id { + if let Some(text) = note::Entity::find_by_id(renote_id) + .one(conn.inner()) + .await + .map_err(to_napi_error)? + .ok_or_else(|| to_napi_error("renote_id is invalid"))? + .text + { + texts.push(text); + } } - if note.reply_id.is_some() { - to_return.push_str( - note::Entity::find_by_id(note.reply_id.unwrap()) - .one(conn.inner()) - .await - .expect("Failed to connect to the database") - .expect("reply_id is invalid") - .text - .unwrap_or_default() - .as_str(), - ); + if let Some(reply_id) = note.reply_id { + if let Some(text) = note::Entity::find_by_id(reply_id) + .one(conn.inner()) + .await + .map_err(to_napi_error)? + .ok_or_else(|| to_napi_error("reply_id is invalid"))? + .text + { + texts.push(text); + } } - to_return.trim().to_owned() + Ok(texts) } -// FIXME: remove this funtion -fn convert_regex(js_regex: String) -> String { +fn convert_regex(js_regex: &str) -> String { static RE: Lazy = Lazy::new(|| Regex::new(r"^/(.+)/(.*)$").unwrap()); - RE.replace(&js_regex, "(?$2)$1").to_string() + RE.replace(js_regex, "(?$2)$1").to_string() } -async fn check_word_mute_impl( - text: String, - muted_word_lists: Vec>, - muted_patterns: Vec, +fn check_word_mute_impl( + texts: &[String], + muted_word_lists: &[Vec], + muted_patterns: &[String], ) -> bool { - if text.is_empty() { - return false; - } - - let text_lowercase = text.to_lowercase(); - - muted_word_lists.into_iter().any(|muted_word_list| { - muted_word_list - .into_iter() - .all(|muted_word| text_lowercase.contains(&muted_word.to_lowercase())) - }) || muted_patterns.into_iter().any(|muted_patten| { - match Regex::new(convert_regex(muted_patten).as_str()) { - Ok(re) => re.is_match(&text), - Err(_) => false, - } + muted_word_lists.iter().any(|muted_word_list| { + texts.iter().any(|text| { + let text_lower = text.to_lowercase(); + muted_word_list + .iter() + .all(|muted_word| text_lower.contains(muted_word)) + }) + }) || muted_patterns.iter().any(|muted_pattern| { + Regex::new(convert_regex(muted_pattern).as_str()) + .map(|re| texts.iter().any(|text| re.is_match(text))) + .unwrap_or(false) }) } @@ -100,15 +94,14 @@ pub async fn check_word_mute( note: NoteLike, muted_word_lists: Vec>, muted_patterns: Vec, -) -> bool { +) -> napi::Result { if muted_word_lists.is_empty() && muted_patterns.is_empty() { - false + Ok(false) } else { - check_word_mute_impl( - full_text(conn, note).await, - muted_word_lists, - muted_patterns, - ) - .await + Ok(check_word_mute_impl( + &all_texts(conn, note).await?, + &muted_word_lists, + &muted_patterns, + )) } }