Skip to content

Commit

Permalink
✨ — Add --cancel-errors-from-list, --unsubscribe-users-in-error-from-…
Browse files Browse the repository at this point in the history
…list and --show_status_of_members to sympa.pl
  • Loading branch information
ldidry committed Jan 26, 2021
1 parent 3392c83 commit 72d3511
Show file tree
Hide file tree
Showing 2 changed files with 201 additions and 27 deletions.
6 changes: 6 additions & 0 deletions src/lib/Sympa/List.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6506,6 +6506,12 @@ I<Instance method>.
Returns the number of messages sent to the list.
FIXME
=item get_first_bouncing_list_member ( )
I<Instance method>.
Get first bouncing user.
FIXME
=item get_next_bouncing_list_member ( )
I<Instance method>.
Expand Down
222 changes: 195 additions & 27 deletions src/sbin/sympa.pl.in
Original file line number Diff line number Diff line change
Expand Up @@ -63,33 +63,63 @@ srand(time());
my %options;
unless (
GetOptions(
\%main::options, 'dump=s',
'debug|d', 'log_level=s',
'config|f=s', 'lang|l=s',
'mail|m', 'help|h',
'version|v', 'import=s',
'make_alias_file', 'lowercase',
'sync_list_db', 'md5_encode_password',
'close_list=s', 'rename_list=s',
'copy_list=s', 'new_listname=s',
'new_listrobot=s', 'purge_list=s',
'create_list', 'instantiate_family=s',
'robot=s', 'add_list=s',
'modify_list=s', 'close_family=s',
'md5_digest=s', 'change_user_email',
'current_email=s', 'new_email=s',
'input_file=s', 'sync_include=s',
'upgrade', 'upgrade_shared',
'from=s', 'to=s',
'reload_list_config', 'list=s',
'quiet', 'close_unknown',
'test_database_message_buffer', 'conf_2_db',
'export_list', 'health_check',
'send_digest', 'keep_digest',
'upgrade_config_location', 'role=s',
'dump_users', 'restore_users',
'open_list=s', 'show_pending_lists=s',
'notify', 'rebuildarc=s'
\%main::options,
'dump=s',
'debug|d',
'log_level=s',
'config|f=s',
'lang|l=s',
'mail|m',
'help|h',
'version|v',
'import=s',
'make_alias_file',
'lowercase',
'sync_list_db',
'md5_encode_password',
'close_list=s',
'rename_list=s',
'copy_list=s',
'new_listname=s',
'new_listrobot=s',
'purge_list=s',
'create_list',
'instantiate_family=s',
'robot=s',
'add_list=s',
'modify_list=s',
'close_family=s',
'md5_digest=s',
'change_user_email',
'current_email=s',
'new_email=s',
'input_file=s',
'sync_include=s',
'upgrade',
'upgrade_shared',
'from=s',
'to=s',
'reload_list_config',
'list=s',
'quiet',
'close_unknown',
'test_database_message_buffer',
'conf_2_db',
'export_list',
'health_check',
'send_digest',
'keep_digest',
'upgrade_config_location',
'role=s',
'dump_users',
'restore_users',
'open_list=s',
'show_pending_lists=s',
'notify',
'rebuildarc=s',
'cancel_errors_from_list=s',
'unsubscribe_users_in_error_from_list=s',
'show_status_of_members=s'
)
) {
pod2usage(-exitval => 1, -output => \*STDERR);
Expand Down Expand Up @@ -1095,6 +1125,127 @@ elsif ($main::options{'sync_list_db'}) {
printf "Archive rebuild scheduled for %s.\n",
$main::options{'rebuildarc'};
exit 0;
} elsif ($main::options{'cancel_errors_from_list'}) {
my ($listname, $robot_id) = split /\@/,
$main::options{'cancel_errors_from_list'}, 2;
my $list = Sympa::List->new($listname, $robot_id);
unless ($list) {
printf STDERR "Incorrect list name %s.\n",
$main::options{'cancel_errors_from_list'};
exit 1;
}

my ($errors, $users) = (0, 0);
for (
my $i = $list->get_first_bouncing_list_member();
$i;
$i = $list->get_next_bouncing_list_member()
) {
if ($list->update_list_member(
$i->{email},
bounce => undef,
update_date => time,
bounce_score => 0
)
) {
$users++;
} else {
printf STDERR "Unable to cancel error for %s\n", $i->{email};
}
$errors++;
}

if ($errors) {
my $text =
($users > 1)
? "Canceled %d errors on %d\n"
: "Canceled %d error on %d\n";
printf $text, $users, $errors;
} else {
print "No errors to cancel\n";
}

exit 0;
} elsif ($main::options{'unsubscribe_users_in_error_from_list'}) {
my ($listname, $robot_id) = split /\@/,
$main::options{'unsubscribe_users_in_error_from_list'}, 2;
my $list = Sympa::List->new($listname, $robot_id);
unless ($list) {
printf STDERR "Incorrect list name %s.\n",
$main::options{'unsubscribe_users_in_error_from_list'};
exit 1;
}

my ($users, $unsubscribed) = (0, 0);
for (
my $i = $list->get_first_bouncing_list_member();
$i;
$i = $list->get_next_bouncing_list_member()
) {
my $spindle = Sympa::Spindle::ProcessRequest->new(
context => $list,
action => 'del',
email => $i->{email},
sender => Sympa::get_address($list, 'listmaster'),
quiet => $main::options{quiet},
md5_check => 1,
scenario_context => {skip => 1},
);
unless ($spindle and $spindle->spin) {
printf STDERR "Failed to unsubscribe %s from %s\n", $i->{email},
$list;
} else {
$unsubscribed++;
}
$users++;
}

if ($users) {
my $text =
($unsubscribed > 1)
? "Unsubscribed %d users on %d\n"
: "Unsubscribed %d user on %d\n";
printf $text, $unsubscribed, $users;
} else {
print "No users to unsubscribe\n";
}

exit 0;
} elsif ($main::options{'show_status_of_members'}) {
my ($listname, $robot_id) = split /\@/,
$main::options{'show_status_of_members'}, 2;
my $list = Sympa::List->new($listname, $robot_id);
unless ($list) {
printf STDERR "Incorrect list name %s.\n",
$main::options{'show_status_of_members'};
exit 1;
}

my @members = $list->get_members('member');
unless (scalar(@members)) {
print "The list has no members\n";
exit 0;
}

my @ok =
grep { !defined($_->{bounce}) && !defined($_->{suspend}) } @members;
my @bounce = grep { defined($_->{bounce}) } @members;
my @suspend = grep { defined($_->{suspend}) } @members;

if (scalar(@ok)) {
printf "Users without problems:\n %s\n",
join("\n ", map { $_->{email} } @ok);
}
if (scalar(@bounce)) {
printf "Bounced users:\n %s\n",
join("\n ", map { $_->{email} } @bounce);
}
if (scalar(@suspend)) {
printf "Suspended users:\n %s\n",
join("\n ", map { $_->{email} } @suspend);
}

exit 0;
}

die 'Unknown option';
Expand Down Expand Up @@ -1787,6 +1938,9 @@ S<[ C<--dump_users> C<--list>=I<list>@I<domain>|ALL [ C<--role>=I<roles> ] ]>
S<[ C<--restore_users> C<--list>=I<list>@I<domain>|ALL [ C<--role>=I<roles> ] ]>
S<[ C<--show_pending_lists>=I<robot> ]>
S<[ C<--rebuildarc>=I<list>[I<@robot>] ]>
S<[ C<--cancel_errors_from_list>=I<list>[I<@robot>] ]>
S<[ C<--unsubscribe_users_in_error_from_list>=I<list>[I<@robot>] ]>
S<[ C<--show_status_of_members>=I<list>[I<@robot>] ]>
=head1 DESCRIPTION
Expand Down Expand Up @@ -1961,6 +2115,20 @@ Print all pending lists for the robot, with informations.
Rebuild the archives of the list.
=item C<--cancel_errors_from_list>=I<list>[I<@robot>]
Cancel the errors of the subscribers of the list.
=item C<--unsubscribe_users_in_error_from_list>=I<list>[I<@robot>]
Unsubscribe the users of the list who are in error status
Use C<--quiet> to prevent unsubscription emails.
=item C<--show_status_of_members>=I<list>[I<@robot>]
Show the status of the users of the list (error status or not).
=item C<--reload_list_config>
[ C<--list=>I<mylist>@I<mydom> ] [ C<--robot=>I<mydom> ]
Expand Down

0 comments on commit 72d3511

Please sign in to comment.