Skip to content

Commit

Permalink
Merge pull request #526 from yvanzo/mbs-9357-part-1-admin-script
Browse files Browse the repository at this point in the history
Update RemoveSpamAccount admin script for MBS-9357 (part 1)
  • Loading branch information
yvanzo committed Sep 7, 2017
2 parents 37964e5 + 0842e29 commit 103d0f5
Showing 1 changed file with 102 additions and 18 deletions.
120 changes: 102 additions & 18 deletions admin/RemoveSpamAccounts.pl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# MusicBrainz -- the open internet music database
#
# Copyright (C) 2011 MetaBrainz Foundation
# Copyright (C) 2011-2017 MetaBrainz Foundation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -28,46 +28,130 @@

use FindBin;
use lib "$FindBin::Bin/../lib";
use open ':std', ':encoding(UTF-8)';

use Getopt::Long;
use Log::Dispatch;
use MusicBrainz::Server::Context;

my $verbose = 0;
my $case_insensitive = 0;
my $force = 0;
my $dry_run = 0;
my $pattern = undef;
my $column = undef;

GetOptions(
"dryrun|d" => \$dry_run,
"column|c=s" => \$column,
"pattern|p=s" => \$pattern,
"dry-run|d" => \$dry_run,
"force|f" => \$force,
) or return 2;
"ignore-case|i" => \$case_insensitive,
"verbose|v" => \$verbose,
) or usage();

my $c = MusicBrainz::Server::Context->create_script_context();
my $sql = Sql->new($c->conn);
my $dbh = $c->dbh;
my %allowed_columns = (
'name' => 1,
'email' => 1,
'website' => 1,
'bio' => 1,
);

sub usage {
warn <<EOF;
Usage: $0 <filter> [options]
FILTERS
-c --column COLUMN Specify the column used to filter accounts
-p --pattern PATTERN Specify the pattern matching column values
Allowed columns
name
email
website
bio
Patterns are case sensitive POSIX regular expressions, see
https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-POSIX-REGEXP
my $prefix = shift;
if (!defined $prefix || $prefix eq '') {
warn "no prefix given, you dolt. Refusing to do anything.\n";
OPTIONS
-d, --dry-run Perform a trial run without removing any account
-f, --force Remove accounts even if they have edits/votes/OAuth tokens
-i, --ignore-case Consider patterns as case insensitive POSIX regular expressions
-v, --verbose Print filtered column additionally to id and name
EXAMPLES
$0 --column name --dry-run --pattern '^yvanzo\$'
Perform a trial run of removing account of script author
$0 --column email --dry-run --pattern '\@metabrainz.org\$'
Perform a trial run of removing accounts of MetaBrainz team
$0 --column website --dry-run --pattern '\\<gracenote\\.com\\>'
Perform a trial run of removing every account linked to Gracenote
$0 --column bio --dry-run --pattern 'unicorn' --ignore-case
Perform a trial run of removing every account which dared to mention unicorn in its bio
EOF
exit(2);
};

if (!defined $column || $column eq '') {
warn "No filtered column given, you dolt. Refusing to do anything.\n";
usage();
}

if (!exists($allowed_columns{$column})) {
warn "Given filtered column is not allowed, you dolt. Refusing to do anything.\n";
usage();
}

if (!defined $pattern || $pattern eq '') {
warn "No matching pattern given, you dolt. Refusing to do anything.\n";
usage();
}
$prefix .= "%";

my $editors = $c->sql->select_list_of_hashes("SELECT id, name FROM editor WHERE name ILIKE ?", $prefix);
my $c = MusicBrainz::Server::Context->create_script_context();
my $sql = Sql->new($c->conn);
my $dbh = $c->dbh;

my $regexp_operator = $case_insensitive ? '~*' : '~';
my $editors = $c->sql->select_list_of_hashes("SELECT id, name, $column FROM editor WHERE $column $regexp_operator ?", $pattern);
foreach my $ed (@{$editors}) {
my $details = $dbh->quote($ed->{name});
if ($verbose && $column ne 'name') {
$details .= " [${column}=" . $dbh->quote($ed->{$column}) . "]";
}

my $id = $ed->{id};
my $edit_count = $c->sql->select_single_value("SELECT count(*) FROM edit WHERE editor = ?", $id);
if ($edit_count > 0 && !$force)
{
print "Not removing account " . $ed->{name} . " because it has edits.\n";
next;

if (!$force) {
my $edit_count = $c->sql->select_single_value("SELECT count(*) FROM edit WHERE editor = ?", $id);
if ($edit_count > 0) {
print "Not removing account " . $details . " because it has edits.\n";
next;
}

my $vote_count = $c->sql->select_single_value("SELECT count(*) FROM vote WHERE editor = ?", $id);
if ($vote_count > 0) {
print "Not removing account " . $details . " because it has votes.\n";
next;
}

my $oauth_token_count = $c->sql->select_single_value("SELECT count(*) FROM editor_oauth_token WHERE editor = ?", $id);
if ($oauth_token_count > 0) {
print "Not removing account " . $details . " because it has OAuth tokens.\n";
next;
}
}

if ($dry_run) {
print "removing account '" . $ed->{name} . "' (dry run)\n";
print "removing account " . $details . " (dry run)\n";
}
else
{
print "removing account '" . $ed->{name} . "'\n";
print "removing account " . $details . "\n";
eval {
$c->model('Editor')->delete($id);
$sql->begin;
Expand Down

0 comments on commit 103d0f5

Please sign in to comment.