use crate::config::TimelineSetting;
use crate::config::CONFIG;
use crate::streamer::Timeline;
use kanaria::string::UCSStr;
use megalodon::entities::{Status, StatusVisibility};
use regex::Regex;
pub fn filter(message: Status, tl: &Timeline) -> (bool, String) {
let config = CONFIG.get().unwrap();
let filter = &config.filter;
if message.reblog.is_some() {
return (false, "The message is the repeat".to_owned());
}
if matches!(tl, &Timeline::Home) && matches!(message.visibility, StatusVisibility::Public) {
match config.timelines {
TimelineSetting { public: true, .. } => {
return (
false,
"The message arrived at both Home and Public Timeline".to_owned(),
)
}
TimelineSetting { local: true, .. } => {
if !message.account.acct.contains('@') {
return (
false,
"The message arrived at both Home and Local Timeline".to_owned(),
);
}
}
_ => {}
};
}
if !filter.user_include.is_empty() && !filter.user_include.contains(&message.account.acct) {
return (false, "The author is not in user_include".to_owned());
}
if filter.user_exclude.contains(&message.account.acct) {
return (false, "The author is in user_exclude".to_owned());
}
let (content, include, exclude) = if filter.case_sensitive {
(
message.content,
filter.include.clone(),
filter.exclude.clone(),
)
} else {
(
UCSStr::from_str(message.content.as_str())
.lower_case()
.hiragana()
.to_string(),
filter
.include
.iter()
.map(|x| UCSStr::from_str(&x).lower_case().hiragana().to_string())
.collect(),
filter
.exclude
.iter()
.map(|x| UCSStr::from_str(&x).lower_case().hiragana().to_string())
.collect(),
)
};
if filter.use_regex {
if !include.is_empty()
&& include
.into_iter()
.map(|x| Regex::new(&x).unwrap()) .any(|x| x.is_match(&content))
{
return (false, "The message does not contain include".to_owned());
}
if exclude
.into_iter()
.map(|x| Regex::new(&x).unwrap()) .any(|x| x.is_match(&content))
{
return (false, "The message contains exclude".to_owned());
}
} else {
if !include.is_empty() && include.into_iter().any(|x| content.contains(&x)) {
return (false, "The message does not contain include".to_owned());
}
if exclude.into_iter().any(|x| content.contains(&x)) {
return (false, "The message contains exclude".to_owned());
}
}
(true, String::new())
}