1# -*- indent-tabs-mode: nil; -*-
2# vim:ft=perl:et:sw=4
3# $Id$
4
5# Sympa - SYsteme de Multi-Postage Automatique
6#
7# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
8# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
9# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
10# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
11# Copyright 2017 The Sympa Community. See the AUTHORS.md file at the top-level
12# directory of this distribution and at
13# <https://github.com/sympa-community/sympa.git>.
14#
15# This program is free software; you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation; either version 2 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
28package Sympa::Spool::Digest;
29
30use strict;
31use warnings;
32
33use Conf;
34
35use base qw(Sympa::Spool);
36
37sub new {
38    my $class   = shift;
39    my %options = @_;
40
41    return undef unless ref $options{context} eq 'Sympa::List';
42    $class->SUPER::new(%options);
43}
44
45sub _directories {
46    my $self    = shift;
47    my %options = @_;
48
49    my $list = ref($self) ? $self->{context} : $options{context};
50    die 'bug in logic.  Ask developer' unless ref $list eq 'Sympa::List';
51
52    return {
53        parent_directory => $Conf::Conf{'queuedigest'},
54        directory        => $list->get_digest_spool_dir,
55        bad_directory    => $list->get_digest_spool_dir . '/bad',
56    };
57}
58
59use constant _generator => 'Sympa::Message';
60
61sub _init {
62    my $self   = shift;
63    my $status = shift;
64
65    unless ($status) {
66        # Get earliest time of messages in the spool.
67        my $metadatas = $self->_load || [];
68        my $metadata;
69        while (my $marshalled = shift @$metadatas) {
70            $metadata = $self->unmarshal($marshalled);
71            last if $metadata;
72        }
73        $self->{time} = $metadata ? $metadata->{time} : undef;
74        $self->{_metadatas} = undef;    # Rewind cache.
75    }
76    return 1;
77}
78
79use constant _marshal_format => '%ld.%f,%ld,%d';
80use constant _marshal_keys   => [qw(date TIME PID RAND)];
81use constant _marshal_regexp => qr{\A(\d+)\.(\d+\.\d+)(?:,.*)?\z};
82
83use constant _no_glob_pattern => 1;
84
85sub next {
86    my $self = shift;
87
88    my ($message, $handle) = $self->SUPER::next();
89    if ($message) {
90        # Assign context which is not given by metadata.
91        $message->{context} = $self->{context};
92    }
93    return ($message, $handle);
94}
95
96# Old name: Sympa::List::store_digest().
97sub store {
98    my $self    = shift;
99    my $message = shift->dup;
100
101    # Delete original message ID because it can be anonymized.
102    delete $message->{message_id};
103
104    return $self->SUPER::store($message);
105}
106
107sub get_id {
108    my $self = shift;
109
110    if ($self->{context}) {
111        if (ref $self->{context} eq 'Sympa::List') {
112            return $self->{context}->get_id;
113        } else {
114            return $self->{context};
115        }
116    } else {
117        return '';
118    }
119}
120
1211;
122__END__
123
124=encoding utf-8
125
126=head1 NAME
127
128Sympa::Spool::Digest - Spool for messages waiting for digest sending
129
130=head1 SYNOPSIS
131
132  use Sympa::Spool::Digest;
133  my $spool = Sympa::Spool::Digest->new(context => $list);
134
135  $spool->store($message);
136
137  my ($message, $handle) = $spool->next;
138
139=head1 DESCRIPTION
140
141L<Sympa::Spool::Digest> implements the spool for messages waiting for
142digest sending.
143
144=head2 Methods
145
146See also L<Sympa::Spool/"Public methods">.
147
148=over
149
150=item new ( context =E<gt> $list )
151
152Creates new instance of L<Sympa::Spool::Digest> related to the list $list.
153
154=item next ( )
155
156Order is controlled by delivery date, then by reception date.
157
158=back
159
160=head2 Properties
161
162See also L<Sympa::Spool/"Properties">.
163
164=over
165
166=item {time}
167
168Earliest time of messages in the spool, or C<undef>.
169
170=back
171
172=head2 Context and metadata
173
174See also L<Sympa::Spool/"Marshaling and unmarshaling metadata">.
175
176This class particularly gives following metadata:
177
178=over
179
180=item {date}
181
182Unix time when the message was delivered.
183
184=item {time}
185
186Unix time in floating point number when the message was stored.
187
188=back
189
190=head1 CONFIGURATION PARAMETERS
191
192Following site configuration parameters in sympa.conf will be referred.
193
194=over
195
196=item queuedigest
197
198Parent directory path of digest spools.
199
200=back
201
202=head1 SEE ALSO
203
204L<sympa_msg(8)>,
205L<Sympa::Message>, L<Sympa::Spool>, L<Sympa::Spool::Digest::Collection>.
206
207=head1 HISTORY
208
209L<Sympa::Spool::Digest> appeared on Sympa 6.2.6.
210
211=cut
212