From e60c4dc1f2a8256f3144174b6e733b7de5cc1799 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Mon, 6 Sep 2021 12:43:18 -0700 Subject: [PATCH] MessageHistory: Add `akadelete` command --- lib/PBot/Core/Commands/MessageHistory.pm | 74 ++++++++++++++++++- .../Core/MessageHistory/Storage/SQLite.pm | 71 +++++++++++++++++- lib/PBot/VERSION.pm | 4 +- 3 files changed, 142 insertions(+), 7 deletions(-) diff --git a/lib/PBot/Core/Commands/MessageHistory.pm b/lib/PBot/Core/Commands/MessageHistory.pm index d8cee27f..c4b4f7ad 100644 --- a/lib/PBot/Core/Commands/MessageHistory.pm +++ b/lib/PBot/Core/Commands/MessageHistory.pm @@ -24,10 +24,12 @@ sub initialize { $self->{pbot}->{commands}->register(sub { $self->cmd_rebuild_aliases(@_) }, "rebuildaliases", 1); $self->{pbot}->{commands}->register(sub { $self->cmd_aka_link(@_) }, "akalink", 1); $self->{pbot}->{commands}->register(sub { $self->cmd_aka_unlink(@_) }, "akaunlink", 1); + $self->{pbot}->{commands}->register(sub { $self->cmd_aka_delete(@_) }, "akadelete", 1); # add capabilities to admin group $self->{pbot}->{capabilities}->add('admin', 'can-akalink', 1); $self->{pbot}->{capabilities}->add('admin', 'can-akaunlink', 1); + $self->{pbot}->{capabilities}->add('admin', 'can-akadelete', 1); } sub cmd_list_also_known_as { @@ -471,7 +473,7 @@ sub cmd_aka_link { $type = $self->{pbot}->{messagehistory}->{database}->{alias_type}->{STRONG} if not defined $type; if (not $id or not $alias) { - return "Usage: link [type]"; + return "Usage: akalink [type]"; } my $source = $self->{pbot}->{messagehistory}->{database}->find_most_recent_hostmask($id); @@ -498,7 +500,7 @@ sub cmd_aka_unlink { my ($id, $alias) = split /\s+/, $context->{arguments}; if (not $id or not $alias) { - return "Usage: unlink "; + return "Usage: akaunlink "; } my $source = $self->{pbot}->{messagehistory}->{database}->find_most_recent_hostmask($id); @@ -519,4 +521,72 @@ sub cmd_aka_unlink { } } +sub cmd_aka_delete { + my ($self, $context) = @_; + + my $usage = "Usage: akadelete [-hn] ; -h delete only hostmask; -n delete only nickserv"; + + if (not length $context->{arguments}) { + return $usage; + } + + my ($delete_hostmask, $delete_nickserv); + + my %opts = ( + h => \$delete_hostmask, + n => \$delete_nickserv, + ); + + my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt( + $context->{arguments}, + \%opts, + ['bundling_override'], + qw(h n), + ); + + return "/say $opt_error -- $usage" if defined $opt_error; + return "Too many arguments -- $usage" if @$opt_args > 1; + return "Missing argument -- $usage" if @$opt_args != 1; + + my $id = $opt_args->[0]; + + my $hostmask; + + if ($id !~ /^\d+$/) { + $hostmask = $id; + $id = $self->{pbot}->{messagehistory}->{database}->get_message_account_id($hostmask); + + if (not defined $id) { + return "No such hostmask $hostmask found."; + } + } else { + $hostmask = $self->{pbot}->{messagehistory}->{database}->find_most_recent_hostmask($id); + + if (not defined $hostmask) { + return "No such id $id found."; + } + } + + my @deletions; + + if ($delete_hostmask) { + $self->{pbot}->{messagehistory}->{database}->delete_hostmask($id, $hostmask); + push @deletions, 'hostmask'; + } + + if ($delete_nickserv) { + $self->{pbot}->{messagehistory}->{database}->delete_nickserv_accounts($id); + $self->{pbot}->{messagehistory}->{database}->set_current_nickserv_account($id, undef); + push @deletions, 'NickServ accounts'; + } + + if ($delete_hostmask || $delete_nickserv) { + return 'Deleted ' . (join ' and ', @deletions) . " from $hostmask ($id)"; + } + + $self->{pbot}->{messagehistory}->database->delete_account($id); + + return "/say Deleted $hostmask ($id)."; +} + 1; diff --git a/lib/PBot/Core/MessageHistory/Storage/SQLite.pm b/lib/PBot/Core/MessageHistory/Storage/SQLite.pm index b2eeacfe..50d04374 100644 --- a/lib/PBot/Core/MessageHistory/Storage/SQLite.pm +++ b/lib/PBot/Core/MessageHistory/Storage/SQLite.pm @@ -190,7 +190,7 @@ sub get_gecos { my ($self, $id) = @_; my $gecos = eval { - my $sth = $self->{dbh}->prepare('SELECT gecos FROM Gecos WHERE ID = ?'); + my $sth = $self->{dbh}->prepare('SELECT gecos FROM Gecos WHERE id = ?'); $sth->execute($id); return $sth->fetchall_arrayref(); }; @@ -202,7 +202,7 @@ sub get_nickserv_accounts { my ($self, $id) = @_; my $nickserv_accounts = eval { - my $sth = $self->{dbh}->prepare('SELECT nickserv FROM Nickserv WHERE ID = ?'); + my $sth = $self->{dbh}->prepare('SELECT nickserv FROM Nickserv WHERE id = ?'); $sth->execute($id); return $sth->fetchall_arrayref(); }; @@ -210,6 +210,23 @@ sub get_nickserv_accounts { return map { $_->[0] } @$nickserv_accounts; } +sub delete_nickserv_accounts { + my ($self, $id) = @_; + + eval { + $self->{dbh}->do('DELETE FROM Nickserv WHERE id = ?', undef, $id); + $self->{dbh}->commit; + $self->{dbh}->begin_work; + }; + + if ($@) { + $self->{pbot}->{logger}->log($@); + return 0; + } + + return 1; +} + sub set_current_nickserv_account { my ($self, $id, $nickserv) = @_; @@ -785,7 +802,8 @@ sub find_most_recent_hostmask { my $hostmask = eval { my $sth = $self->{dbh}->prepare('SELECT hostmask FROM Hostmasks WHERE ID = ? ORDER BY last_seen DESC LIMIT 1'); $sth->execute($id); - return $sth->fetchrow_hashref()->{'hostmask'}; + my $row = $sth->fetchrow_hashref(); + return defined $row ? $row->{hostmask} : undef; }; $self->{pbot}->{logger}->log($@) if $@; return $hostmask; @@ -1626,6 +1644,53 @@ sub unlink_alias { return $ret; } +sub delete_hostmask { + my ($self, $id, $hostmask) = @_; + + eval { + $self->{dbh}->do('DELETE FROM Hostmasks WHERE id = ? AND hostmask = ?', undef, $id, $hostmask); + $self->{dbh}->commit; + $self->{dbh}->begin_work; + }; + + if ($@) { + $self->{pbot}->{logger}->log($@); + return 0; + } + + return 1; +} + +sub delete_account { + my ($self, $id) = @_; + + $self->{dbh}->commit; + $self->{dbh}->begin_work; + + my $ret = eval { + $self->{dbh}->do('DELETE FROM Hostmasks WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Accounts WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM NickServ WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Gecos WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Channels WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Messages WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Aliases WHERE id = ?', undef, $id); + $self->{dbh}->do('DELETE FROM Aliases WHERE alias = ?', undef, $id); + $self->{dbh}->commit; + $self->{dbh}->begin_work; + return 1; + }; + + if ($@) { + $self->{pbot}->{logger}->log($@); + $self->{dbh}->rollback; + $self->{dbh}->begin_work; + return 0; + } + + return $ret; +} + sub vacuum { my $self = shift; diff --git a/lib/PBot/VERSION.pm b/lib/PBot/VERSION.pm index cfacbf8b..635d039c 100644 --- a/lib/PBot/VERSION.pm +++ b/lib/PBot/VERSION.pm @@ -25,8 +25,8 @@ use PBot::Imports; # These are set by the /misc/update_version script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 4376, - BUILD_DATE => "2021-09-04", + BUILD_REVISION => 4377, + BUILD_DATE => "2021-09-06", }; sub initialize {}