forked from naskya/firefish
refactor (backend-rs): check_word_mute
Co-authored-by: naskya <m@naskya.net>
This commit is contained in:
parent
a7fc8f22c1
commit
9cd3d474ae
1 changed files with 58 additions and 65 deletions
|
@ -1,10 +1,10 @@
|
||||||
use crate::database::JsDbConn;
|
use crate::database::JsDbConn;
|
||||||
use crate::model::entity::{drive_file, note};
|
use crate::model::entity::{drive_file, note};
|
||||||
|
use crate::prelude::*;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use sea_orm::prelude::*;
|
use sea_orm::prelude::*;
|
||||||
|
|
||||||
// FIXME: remove this type
|
|
||||||
#[napi_derive::napi(object)]
|
#[napi_derive::napi(object)]
|
||||||
pub struct NoteLike {
|
pub struct NoteLike {
|
||||||
pub file_ids: Vec<String>,
|
pub file_ids: Vec<String>,
|
||||||
|
@ -15,82 +15,76 @@ pub struct NoteLike {
|
||||||
pub reply_id: Option<String>,
|
pub reply_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn full_text(conn: &JsDbConn, note: NoteLike) -> String {
|
async fn all_texts(conn: &JsDbConn, note: NoteLike) -> napi::Result<Vec<String>> {
|
||||||
let mut to_return = format!(
|
let mut texts: Vec<String> = vec![];
|
||||||
"{}\n{}\n",
|
|
||||||
note.text.unwrap_or_default(),
|
if let Some(text) = note.text {
|
||||||
note.cw.unwrap_or_default(),
|
texts.push(text);
|
||||||
);
|
}
|
||||||
|
if let Some(cw) = note.cw {
|
||||||
|
texts.push(cw);
|
||||||
|
}
|
||||||
|
|
||||||
for file_id in note.file_ids {
|
for file_id in note.file_ids {
|
||||||
if let Some(alt_text) = drive_file::Entity::find_by_id(file_id)
|
if let Some(alt_text) = drive_file::Entity::find_by_id(file_id)
|
||||||
.one(conn.inner())
|
.one(conn.inner())
|
||||||
.await
|
.await
|
||||||
.expect("Failed to connect to the database")
|
.map_err(to_napi_error)?
|
||||||
.expect("file_id is invalid")
|
.ok_or_else(|| to_napi_error("file_id is invalid"))?
|
||||||
.comment
|
.comment
|
||||||
{
|
{
|
||||||
to_return.push_str(alt_text.as_str());
|
texts.push(alt_text);
|
||||||
to_return.push('\n');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if note.renote_id.is_some() {
|
if let Some(renote_id) = note.renote_id {
|
||||||
to_return.push_str(
|
if let Some(text) = note::Entity::find_by_id(renote_id)
|
||||||
note::Entity::find_by_id(note.renote_id.unwrap())
|
.one(conn.inner())
|
||||||
.one(conn.inner())
|
.await
|
||||||
.await
|
.map_err(to_napi_error)?
|
||||||
.expect("Failed to connect to the database")
|
.ok_or_else(|| to_napi_error("renote_id is invalid"))?
|
||||||
.expect("renote_id is invalid")
|
.text
|
||||||
.text
|
{
|
||||||
.unwrap_or_default()
|
texts.push(text);
|
||||||
.as_str(),
|
}
|
||||||
);
|
|
||||||
to_return.push('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if note.reply_id.is_some() {
|
if let Some(reply_id) = note.reply_id {
|
||||||
to_return.push_str(
|
if let Some(text) = note::Entity::find_by_id(reply_id)
|
||||||
note::Entity::find_by_id(note.reply_id.unwrap())
|
.one(conn.inner())
|
||||||
.one(conn.inner())
|
.await
|
||||||
.await
|
.map_err(to_napi_error)?
|
||||||
.expect("Failed to connect to the database")
|
.ok_or_else(|| to_napi_error("reply_id is invalid"))?
|
||||||
.expect("reply_id is invalid")
|
.text
|
||||||
.text
|
{
|
||||||
.unwrap_or_default()
|
texts.push(text);
|
||||||
.as_str(),
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
to_return.trim().to_owned()
|
Ok(texts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: remove this funtion
|
fn convert_regex(js_regex: &str) -> String {
|
||||||
fn convert_regex(js_regex: String) -> String {
|
|
||||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^/(.+)/(.*)$").unwrap());
|
static RE: Lazy<Regex> = 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(
|
fn check_word_mute_impl(
|
||||||
text: String,
|
texts: &[String],
|
||||||
muted_word_lists: Vec<Vec<String>>,
|
muted_word_lists: &[Vec<String>],
|
||||||
muted_patterns: Vec<String>,
|
muted_patterns: &[String],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if text.is_empty() {
|
muted_word_lists.iter().any(|muted_word_list| {
|
||||||
return false;
|
texts.iter().any(|text| {
|
||||||
}
|
let text_lower = text.to_lowercase();
|
||||||
|
muted_word_list
|
||||||
let text_lowercase = text.to_lowercase();
|
.iter()
|
||||||
|
.all(|muted_word| text_lower.contains(muted_word))
|
||||||
muted_word_lists.into_iter().any(|muted_word_list| {
|
})
|
||||||
muted_word_list
|
}) || muted_patterns.iter().any(|muted_pattern| {
|
||||||
.into_iter()
|
Regex::new(convert_regex(muted_pattern).as_str())
|
||||||
.all(|muted_word| text_lowercase.contains(&muted_word.to_lowercase()))
|
.map(|re| texts.iter().any(|text| re.is_match(text)))
|
||||||
}) || muted_patterns.into_iter().any(|muted_patten| {
|
.unwrap_or(false)
|
||||||
match Regex::new(convert_regex(muted_patten).as_str()) {
|
|
||||||
Ok(re) => re.is_match(&text),
|
|
||||||
Err(_) => false,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,15 +94,14 @@ pub async fn check_word_mute(
|
||||||
note: NoteLike,
|
note: NoteLike,
|
||||||
muted_word_lists: Vec<Vec<String>>,
|
muted_word_lists: Vec<Vec<String>>,
|
||||||
muted_patterns: Vec<String>,
|
muted_patterns: Vec<String>,
|
||||||
) -> bool {
|
) -> napi::Result<bool> {
|
||||||
if muted_word_lists.is_empty() && muted_patterns.is_empty() {
|
if muted_word_lists.is_empty() && muted_patterns.is_empty() {
|
||||||
false
|
Ok(false)
|
||||||
} else {
|
} else {
|
||||||
check_word_mute_impl(
|
Ok(check_word_mute_impl(
|
||||||
full_text(conn, note).await,
|
&all_texts(conn, note).await?,
|
||||||
muted_word_lists,
|
&muted_word_lists,
|
||||||
muted_patterns,
|
&muted_patterns,
|
||||||
)
|
))
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue