mirror of
https://github.com/wassname/talk.git
synced 2026-09-10 12:43:11 +08:00
feat: added memoization to the regexp generation
This commit is contained in:
@@ -7,7 +7,7 @@ import {
|
||||
IntermediateModerationPhase,
|
||||
IntermediatePhaseResult,
|
||||
} from "talk-server/services/comments/moderation";
|
||||
import { containsMatchingPhrase } from "talk-server/services/comments/moderation/wordlist";
|
||||
import { containsMatchingPhraseMemoized } from "talk-server/services/comments/moderation/wordlist";
|
||||
|
||||
// This phase checks the comment against the wordList.
|
||||
export const wordList: IntermediateModerationPhase = ({
|
||||
@@ -23,7 +23,7 @@ export const wordList: IntermediateModerationPhase = ({
|
||||
// has pre-mod enabled or not. If the comment was rejected based on the
|
||||
// wordList, then reject it, otherwise if the moderation setting is
|
||||
// premod, set it to `premod`.
|
||||
if (containsMatchingPhrase(tenant.wordList.banned, comment.body)) {
|
||||
if (containsMatchingPhraseMemoized(tenant.wordList.banned, comment.body)) {
|
||||
// Add the flag related to Trust to the comment.
|
||||
return {
|
||||
status: GQLCOMMENT_STATUS.REJECTED,
|
||||
@@ -40,9 +40,9 @@ export const wordList: IntermediateModerationPhase = ({
|
||||
// flag to it to indicate that it needs to be looked at.
|
||||
// Otherwise just return the new comment.
|
||||
|
||||
// If the wordlist has matched the suspect word filter and we haven't disabled
|
||||
// If the wordList has matched the suspect word filter and we haven't disabled
|
||||
// auto-flagging suspect words, then we should flag the comment!
|
||||
if (containsMatchingPhrase(tenant.wordList.suspect, comment.body)) {
|
||||
if (containsMatchingPhraseMemoized(tenant.wordList.suspect, comment.body)) {
|
||||
return {
|
||||
actions: [
|
||||
{
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import {
|
||||
GQLCOMMENT_FLAG_REASON,
|
||||
GQLCOMMENT_STATUS,
|
||||
} from "talk-server/graph/tenant/schema/__generated__/types";
|
||||
import { ACTION_TYPE } from "talk-server/models/action";
|
||||
import {
|
||||
IntermediateModerationPhase,
|
||||
IntermediatePhaseResult,
|
||||
} from "talk-server/services/comments/moderation";
|
||||
import { containsMatchingPhrase } from "talk-server/services/comments/moderation/wordlist";
|
||||
|
||||
// This phase checks the comment against the wordList.
|
||||
export const wordList: IntermediateModerationPhase = ({
|
||||
tenant,
|
||||
comment,
|
||||
}): IntermediatePhaseResult | void => {
|
||||
// If there isn't a body, there can't be a bad word!
|
||||
if (!comment.body) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Decide the status based on whether or not the current asset/settings
|
||||
// has pre-mod enabled or not. If the comment was rejected based on the
|
||||
// wordList, then reject it, otherwise if the moderation setting is
|
||||
// premod, set it to `premod`.
|
||||
if (containsMatchingPhrase(tenant.wordList.banned, comment.body)) {
|
||||
// Add the flag related to Trust to the comment.
|
||||
return {
|
||||
status: GQLCOMMENT_STATUS.REJECTED,
|
||||
actions: [
|
||||
{
|
||||
action_type: ACTION_TYPE.FLAG,
|
||||
reason: GQLCOMMENT_FLAG_REASON.COMMENT_DETECTED_BANNED_WORD,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
// If the comment has a suspect word or a link, we need to add a
|
||||
// flag to it to indicate that it needs to be looked at.
|
||||
// Otherwise just return the new comment.
|
||||
|
||||
// If the wordlist has matched the suspect word filter and we haven't disabled
|
||||
// auto-flagging suspect words, then we should flag the comment!
|
||||
if (containsMatchingPhrase(tenant.wordList.suspect, comment.body)) {
|
||||
return {
|
||||
actions: [
|
||||
{
|
||||
action_type: ACTION_TYPE.FLAG,
|
||||
reason: GQLCOMMENT_FLAG_REASON.COMMENT_DETECTED_SUSPECT_WORD,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,3 +1,9 @@
|
||||
import { memoize } from "lodash";
|
||||
|
||||
// TODO: reintroduce this when we have https://github.com/DefinitelyTyped/DefinitelyTyped/pull/30035 merged
|
||||
// // Replace `memoize.Cache`.
|
||||
// memoize.Cache = WeakMap;
|
||||
|
||||
/**
|
||||
* Escape string for special regular expression characters.
|
||||
*/
|
||||
@@ -21,5 +27,13 @@ export function generateRegExp(phrases: string[]) {
|
||||
return new RegExp(`(^|[^\\w])(${inner})(?=[^\\w]|$)`, "iu");
|
||||
}
|
||||
|
||||
export const generateRegExpMemoized = memoize(generateRegExp);
|
||||
|
||||
export const containsMatchingPhrase = (phrases: string[], testString: string) =>
|
||||
phrases.length > 0 ? generateRegExp(phrases).test(testString) : false;
|
||||
|
||||
export const containsMatchingPhraseMemoized = (
|
||||
phrases: string[],
|
||||
testString: string
|
||||
) =>
|
||||
phrases.length > 0 ? generateRegExpMemoized(phrases).test(testString) : false;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Escape string for special regular expression characters.
|
||||
*/
|
||||
export function escapeRegExp(str: string) {
|
||||
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a regular expression that catches the `phrases`.
|
||||
*/
|
||||
export function generateRegExp(phrases: string[]) {
|
||||
const inner = phrases
|
||||
.map(phrase =>
|
||||
phrase
|
||||
.split(/\s+/)
|
||||
.map(word => escapeRegExp(word))
|
||||
.join('[\\s"?!.]+')
|
||||
)
|
||||
.join("|");
|
||||
|
||||
return new RegExp(`(^|[^\\w])(${inner})(?=[^\\w]|$)`, "iu");
|
||||
}
|
||||
|
||||
export const containsMatchingPhrase = (phrases: string[], testString: string) =>
|
||||
phrases.length > 0 ? generateRegExp(phrases).test(testString) : false;
|
||||
Reference in New Issue
Block a user