Enhancements for wordfilter.pl\n\n o reload words on file modification\n o use a hash so word lookup is O(1)

This commit is contained in:
Robert Barretto 2025-04-28 17:04:33 -05:00
parent de1c3ea8f1
commit 5ae27a4e2c

View file

@ -1,9 +1,11 @@
use POSIX qw(strftime);
use File::stat;
my $filename;
my @words;
my $read_date;
my $last_mtime;
my %words_lookup;
my $debug;
my $logfile;
@ -12,34 +14,44 @@ sub dolog {
return unless $debug;
my $ts = strftime("%Y-%m-%d %H:%M:%S", localtime);
open(OUT, ">>$logfile");
print OUT "$ts $str";
print OUT "$ts $str\n";
close(OUT);
}
sub refresh_words {
my @now = localtime();
my $year = $now[5];
my $mon = $now[4];
my $mday = $now[3];
my $dayno = 0 + ($year + 1900) * 10000 + $mon * 100 + $mday;
return unless ($dayno > $read_date);
@words = ();
my ($id) = @_;
my $stat = stat($filename);
# If the filtered words files doesn't exist, nothing to do
return unless $state;
# If the filtered words file hasn't been modified, nothing to do
$last_mtime ||= 0;
return unless ($stat->mtime > $last_mtime);
# The filtered words file has changed. Create a new lookup hash
%words_lookup = ();
if (open(my $fh, '<', $filename)) {
while (my $row = <$fh>) {
chomp($row);
next if length($row) < 1;
push @words, lc($row);
}
dolog("load from " . $filename . ", found " . @words . " words\n");
dolog("[$id] - '" . $filename . "' modified. Loaded " . scalar(@words) . " words.");
close($fh);
}
$read_date = $dayno;
# Create new hash for O(1) lookups
%words_lookup = map { $_ => 1 } @words;
# update last modified time
$last_mtime = $stat->mtime;
}
sub create_config {
my ($name, $configdata) = @_;
$filename = $configdata;
$read_date = 0;
$last_mtime = 0;
$debug = 1;
$logfile = "/tmp/wordfilter.log";
}
@ -47,10 +59,12 @@ sub create_config {
sub check {
my ($id, $msg) = @_;
refresh_words;
foreach my $word (@words) {
next unless ($msg =~ /\b${word}\b/);
dolog("reject message " . $id . " containing `" . $word . "' in message: `" . $msg . "'\n");
refresh_words($id);
my @msg_words = split /\s+/, $msg;
# check each word in the message to see if has any filter words
foreach my $msg_word (@msg_words) {
next unless (exists $words_lookup{lc($msg_word)});
dolog("[$id] - rejecting message containing '" . $msg_word . "' in message: '" . $msg . "'");
return 8;
}
return 0;