Commit 0021bb31 authored by sikeda's avatar sikeda
Browse files

[dev] Introducing Sympa::Spindle::ResendArchive class to resend messages in archive to user.


git-svn-id: https://subversion.renater.fr/sympa/branches/sympa-6.2-branch@12579 05aa8bb8-cd2b-0410-b1d7-8918dfa770ce
parent eb78c965
......@@ -73,7 +73,7 @@ use Sympa::Robot;
use Sympa::Scenario;
use Sympa::Session;
use Sympa::SharedDocument;
use Sympa::Spindle::TransformOutgoing;
use Sympa::Spindle::ResendArchive;
use Sympa::Spool::Archive;
use Sympa::Spool::Held;
use Sympa::Spool::Incoming;
......@@ -10118,8 +10118,9 @@ sub do_send_me {
wwslog('info', '(%s, %s, %s, %s)',
$in{'list'}, $in{'yyyy'}, $in{'month'}, $in{'msgid'});
 
unless ($in{'msgid'}
and $in{'msgid'} !~ /NO-ID-FOUND\.mhonarc\.org/) {
my $message_id = tools::clean_msg_id($in{'msgid'});
unless ($message_id
and $message_id !~ /NO-ID-FOUND\.mhonarc\.org/) {
Sympa::Report::reject_report_web('intern', 'may_not_send_me', {},
$param->{'action'}, $list, $param->{'user'}{'email'}, $robot);
wwslog('info', 'No message id found');
......@@ -10127,76 +10128,31 @@ sub do_send_me {
return undef;
}
 
my $archive = Sympa::Archive->new(context => $list);
my ($message, $handle);
if ($archive->select_archive("$in{'yyyy'}-$in{'month'}")) {
($message, $handle) = $archive->fetch(message_id => $in{'msgid'});
}
if ($message) {
# Decrypt message if possible
$message->smime_decrypt;
# Add or remove several header fields.
Sympa::Spindle::TransformOutgoing->post_archive($message); #FIXME
my $spindle = Sympa::Spindle::ResendArchive->new(
resent_by => $param->{'user'}{'email'},
context => $list, arc => "$in{'yyyy'}-$in{'month'}",
message_id => $message_id, quiet => 1);
 
# Add footer/header.
$message->prepare_message_according_to_mode('mail', $list);
# Shelve DMARC protection.
$message->{shelved}{dmarc_protect} = 1
if $list->{'admin'}{'dmarc_protection'}
and $list->{'admin'}{'dmarc_protection'}{'mode'}
and not $list->{'admin'}{'anonymous_sender'};
# Shelve personalization.
$message->{shelved}{merge} = 1
if Sympa::Tools::Data::smart_eq($list->{'admin'}{'merge_feature'},
'on');
# Check if re-encryption is possible.
if ($message->{smime_crypted}) {
# unless ($message->dup->smime_encrypt($param->{'user'}{'email'})) {
# # If encryption failed, send a generic error message:
# # X509 cert missing.
# $message = Sympa::Message->new_from_template(
# $list,
# 'x509-user-cert-missing',
# $param->{'user'}{'email'},
# { 'mail' => {
# 'sender' => $message->{sender},
# 'subject' => $message->{decoded_subject},
# },
# }
# );
# } else {
# # Otherwise shelve re-encryption with S/MIME.
$message->{shelved}{smime_encrypt} = 1;
# }
}
# Overwrite original envelope sender. It is REQUIRED for delivery.
$message->{envelope_sender} = $list->get_list_address('return_path');
unless (defined $bulk->store($message, $param->{'user'}{'email'})) {
$param->{'status'} = 'message_err';
wwslog(
'err',
'Impossible to send archive file to %s',
$param->{'user'}{'email'}
);
return undef;
}
unless ($spindle and $spindle->spin) {
wwslog('info', 'No file match msgid');
$param->{'status'} = 'not_found';
return undef;
} elsif ($spindle->{finish} and $spindle->{finish} eq 'success') {
wwslog(
'info', 'Message %s spooled for %s',
$message, $param->{'user'}{'email'}
$message_id, $param->{'user'}{'email'}
);
Sympa::Report::notice_report_web('performed', {}, $param->{'action'});
$in{'month'} = $in{'yyyy'} . "-" . $in{'month'};
return 'arc';
} else {
wwslog('info', 'No file match msgid');
$param->{'status'} = 'not_found';
return undef;
$param->{'status'} = 'message_err';
wwslog(
'err',
'Impossible to send archive file to %s',
$param->{'user'}{'email'}
);
return undef;
}
 
return 1;
......
......@@ -89,6 +89,7 @@ nobase_modules_DATA = \
Sympa/Spindle/ProcessIncoming.pm \
Sympa/Spindle/ProcessModeration.pm \
Sympa/Spindle/ProcessOutgoing.pm \
Sympa/Spindle/ResendArchive.pm \
Sympa/Spindle/SendDigest.pm \
Sympa/Spindle/StoreArchive.pm \
Sympa/Spindle/ToArchive.pm \
......
# -*- indent-tabs-mode: nil; -*-
# vim:ft=perl:et:sw=4
# $Id: Commands.pm 12548 2015-11-28 08:33:32Z sikeda $
# Sympa - SYsteme de Multi-Postage Automatique
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
# Copyright (c) 2011, 2012, 2013, 2014, 2015 GIP RENATER
#
# 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
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
package Sympa::Spindle::ResendArchive;
use strict;
use warnings;
use Sympa;
use Conf;
use Sympa::Language;
use Sympa::Log;
use base qw(Sympa::Spindle);
my $log = Sympa::Log->instance;
use constant _distaff => 'Sympa::Archive';
sub _init {
my $self = shift;
my $state = shift;
if ($state == 0) {
die 'bug in logic. Ask developer'
unless $self->{resent_by}
and $self->{context}
and $self->{arc}
and $self->{message_id};
$self->{distaff}->select_archive($self->{arc})
or return 0;
}
1;
}
sub _on_garbage {
my $self = shift;
my $handle = shift;
# Keep broken message and skip it.
$handle->close;
}
sub _on_failure {
my $self = shift;
my $message = shift;
my $handle = shift;
# Keep failed message and exit.
$handle->close;
$self->{finish} = 'failure';
}
sub _on_success {
my $self = shift;
my $message = shift;
my $handle = shift;
# Keep succeeded message and exit.
$handle->close;
$self->{finish} = 'success';
}
sub _twist {
my $self = shift;
my $message = shift;
my $message_id =
tools::clean_msg_id($message->get_header('Message-Id')) || '';
return 0 unless $message_id eq $self->{message_id};
# Decrpyt message.
# If encrypted, it will be re-encrypted by succeeding processes.
$message->smime_decrypt;
# Assign privileges of resending user to the message.
$message->{envelope_sender} = $self->{resent_by};
return ['Sympa::Spindle::TransformOutgoing', 'Sympa::Spindle::ToList'];
}
1;
__END__
=encoding utf-8
=head1 NAME
Sympa::Spindle::ResendArchive - Workflow of resending messages in archive
=head1 SYNOPSIS
use Sympa::Spindle::ResendArchive;
my $spindle = Sympa::Spindle::ResendArchive->new(
resent_by => $email, context => $list, arc => $arc,
message_id => $message_id);
$spindle->spin;
=head1 DESCRIPTION
L<Sympa::Spindle::ResendArchive> defines workflow for resending of messages
in archive.
When spin() method is invoked, it reads a message in archive,
decorate and distribute it.
Either resending failed or not, spin() will terminate
processing.
=head2 Public methods
See also L<Sympa::Spindle/"Public methods">.
=over
=item new ( resent_by =E<gt> $email,
context =E<gt> $list, arc =E<gt> $arc, message_id =E<gt> $message_id,
[ quiet =E<gt> 1 ] )
=item spin ( )
new() must take following options:
=over
=item resent_by =E<gt> $email
E-mail address of the user who requested resending message.
It is given by do_send_me() function of wwsympa.fcgi and
used by L<Sympa::Spindle::ToList> to whom distribute message.
=item context =E<gt> $list
=item arc =E<gt> $arc
=item message_id =E<gt> $message_id
Context (List), archive and message ID to specify the message in archive.
=item quiet =E<gt> 1
NOT YET IMPLEMENTED.
If this option is set, automatic replys reporting result of processing
to the user (see L</"resent_by">) will not be sent.
=back
=back
=head2 Properties
See also L<Sympa::Spindle/"Properties">.
=over
=item {distaff}
Instance of L<Sympa::Archive> class.
=item {finish}
C<'success'> is set if processing succeeded.
C<'failure'> is set if processing failed.
=back
=head1 SEE ALSO
L<Sympa::Archive>,
L<Sympa::Message>,
L<Sympa::Spindle>, L<Sympa::Spindle::ToList>,
L<Sympa::Spool::TransformOutgoing>.
=head1 HISTORY
L<Sympa::Spindle::ResendArchive> appeared on Sympa 6.2.13.
=cut
......@@ -50,10 +50,11 @@ sub _twist {
my $sender =
$self->{confirmed_by}
|| $self->{distributed_by}
|| $self->{resent_by}
|| $message->{sender};
my $numsmtp = _send_msg($message);
unless (defined $numsmtp) {
my $numstored = _send_msg($message, $self->{resent_by});
unless (defined $numstored) {
$log->syslog('err', 'Unable to send message %s to list %s',
$message, $list);
Sympa::send_notify_to_listmaster(
......@@ -87,6 +88,7 @@ sub _twist {
{'key' => $self->{authkey}, 'message' => $message},
$list->{'domain'}, $list);
}
# No notification sent to {resent_by} user.
}
$log->syslog(
......@@ -96,7 +98,7 @@ sub _twist {
$list,
$sender,
Time::HiRes::time() - $self->{start_time},
$numsmtp,
$numstored,
$list->get_total,
$messageid,
$message->{'size'}
......@@ -149,10 +151,15 @@ sub _extract_verp_rcpt {
# Old names: List::send_msg(), (part of) Sympa::List::distribute_msg().
sub _send_msg {
my $message = shift;
my $message = shift;
my $resent_by = shift;
my $list = $message->{context};
my $verp_rate;
my $tags_to_use;
my $available_recipients;
unless ($resent_by) { # Not in ResendArchive spindle.
# Synchronize list members, required if list uses include sources
# unless sync_include has been performed recently.
if ($list->has_include_data_sources()) {
......@@ -165,14 +172,17 @@ sub _send_msg {
# Blindly send the message to all users.
my $total = $list->get_total('nocache');
unless ($total > 0) {
unless ($total and 0 < $total) {
$log->syslog('info', 'No subscriber in list %s', $list);
$list->savestats;
return 0;
}
## Bounce rate
# Postpone delivery if delivery time is specified.
my $delivery_date = $list->get_next_delivery_date;
$message->{date} = $delivery_date if defined $delivery_date;
# Bounce rate.
my $rate = $list->get_total_bouncing() * 100 / $total;
if ($rate > $list->{'admin'}{'bounce'}{'warn_rate'}) {
$list->send_notify_to_owner('bounce_rate', {'rate' => $rate});
......@@ -184,43 +194,44 @@ sub _send_msg {
}
}
#save the message before modifying it
my $nbr_smtp = 0;
# prepare verp parameter
my $verp_rate = $list->{'admin'}{'verp_rate'};
# force VERP if tracking is requested.
# Prepare verp parameter.
$verp_rate = $list->{'admin'}{'verp_rate'};
# Force VERP if tracking is requested.
$verp_rate = '100%'
if Sympa::Tools::Data::smart_eq($message->{shelved}{tracking},
qr/dsn|mdn/);
my $tags_to_use;
# Define messages which can be tagged as first or last according to the
# VERP rate.
# If the VERP is 100%, then all the messages are VERP. Don't try to tag
# not VERP
# messages as they won't even exist.
# not VERP messages as they won't even exist.
if ($verp_rate eq '0%') {
$tags_to_use->{'tag_verp'} = '0';
$tags_to_use->{'tag_noverp'} = 'z';
$tags_to_use = {tag_verp => '0', tag_noverp => 'z'};
} else {
$tags_to_use->{'tag_verp'} = 'z';
$tags_to_use->{'tag_noverp'} = '0';
$tags_to_use = {tag_verp => 'z', tag_noverp => '0'};
}
# Separate subscribers depending on user reception option and also if VERP
# a dicovered some bounce for them.
# Separate subscribers depending on user reception option and also if
# VERP a dicovered some bounce for them.
# Storing the not empty subscribers' arrays into a hash.
my $available_recipients = $list->get_recipients_per_mode($message);
$available_recipients = $list->get_recipients_per_mode($message);
unless ($available_recipients) {
$log->syslog('info', 'No subscriber for sending msg in list %s',
$list);
$list->savestats;
return 0;
}
} else {
$verp_rate = '0%';
$tags_to_use = { tag_verp => '0', tag_noverp => 'z', };
$available_recipients =
{ mail => { noverp => [$resent_by] } };
}
my $numstored = 0;
foreach my $mode (sort keys %$available_recipients) {
# Save the message before modifying it.
my $new_message = $message->dup;
unless ($new_message->prepare_message_according_to_mode($mode, $list))
{
......@@ -268,7 +279,7 @@ sub _send_msg {
return undef;
}
$tags_to_use->{'tag_noverp'} = '0' if $result;
$nbr_smtp++;
$numstored++;
# Add number and size of messages sent to total in stats file.
my $numsent = scalar @selected_tabrcpt;
......@@ -314,7 +325,7 @@ sub _send_msg {
return undef;
}
$tags_to_use->{'tag_verp'} = '0' if $result;
$nbr_smtp++;
$numstored++;
# Add number and size of messages sent to total in stats file.
my $numsent = scalar @verp_selected_tabrcpt;
......@@ -344,14 +355,14 @@ sub _send_msg {
}
}
$list->savestats;
return $nbr_smtp;
return $numstored;
}
# Distribute a message to a list, shelving encryption if needed.
#
# IN : -$message(+) : ref(Sympa::Message)
# -\@rcpt(+) : recipients
# OUT : -$numsmtp : number of sendmail process | undef
# Returns: Marshalled metadata (file name) or undef
#
# Old name: Sympa::Mail::mail_message(), Sympa::List::_mail_message().
sub _mail_message {
......@@ -378,11 +389,6 @@ sub _mail_message {
$message->{shelved}{smime_encrypt} = 1
if $message->{'smime_crypted'};
# if not specified, delivery time is right now (used for sympa messages
# etc.)
my $delivery_date = $list->get_next_delivery_date;
$message->{'date'} = $delivery_date if defined $delivery_date;
# Overwrite original envelope sender. It is REQUIRED for delivery.
$message->{envelope_sender} = $list->get_list_address('return_path');
......
......@@ -138,11 +138,6 @@ sub _twist {
1;
}
# Tentative.
sub post_archive {
goto &_twist;
}
1;
__END__
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment