Fixed long standing bug about displaying proper message
[clearscm.git] / maps / bin / detail.cgi
1 #!/usr/bin/perl
2 ################################################################################
3 #
4 # File:         $RCSfile: detail.cgi,v $
5 # Revision:     $Revision: 1.1 $
6 # Description:  Displays list of email addresses based on report type.
7 # Author:       Andrew@DeFaria.com
8 # Created:      Fri Nov 29 14:17:21  2002
9 # Modified:     $Date: 2013/06/12 14:05:47 $
10 # Language:     perl
11 #
12 # (c) Copyright 2000-2006, Andrew@DeFaria.com, all rights reserved.
13 #
14 ################################################################################
15 use strict;
16 use warnings;
17
18 use MIME::Words qw(:all);
19 use FindBin;
20 $0 = $FindBin::Script;
21
22 use lib "$FindBin::Bin/../lib";
23
24 use MAPS;
25 use MAPSLog;
26 use MAPSUtil;
27 use MAPSWeb;
28 use CGI qw(:standard *table start_td end_td start_Tr end_Tr start_div end_div);
29 use CGI::Carp 'fatalsToBrowser';
30
31 my $type   = param('type');
32 my $next   = param('next');
33 my $lines  = param('lines');
34 my $date   = param('date');
35
36 $date ||= '';
37
38 my $userid;
39 my $current;
40 my $last;
41 my $prev;
42 my $total;
43 my $table_name = 'detail';
44
45 my %types = (
46   'blacklist'   => [
47     'Blacklist report',
48     'The following blacklisted users attempted to email you'
49   ],
50   'whitelist'   => [
51     'Delivered report',
52     'Delivered email from the following users'
53   ],
54   'nulllist'    => [
55     'Discarded report',
56     'Discarded messages from the following users'
57   ],
58   'error'       => [
59     'Error report',
60     'Errors detected'
61   ],
62   'mailloop'    => [
63     'MailLoop report',
64     'Automatically detected mail loops from the following users'
65   ],
66   'registered'  => [
67     'Registered report',
68     'The following users have recently registered'
69   ],
70   'returned'    => [
71     'Returned report',
72     'Sent Register reply to the following users'
73   ]
74 );
75
76 sub MakeButtons {
77   my ($type) = @_;
78
79   my $prev_button = $prev >= 0 ?
80     a ({-href      => "detail.cgi?type=$type;date=$date;next=$prev",
81         -accesskey => 'p',
82     }, '<img src=/maps/images/previous.gif border=0 alt=Previous align=middle>') : '';
83   my $next_button = ($next + $lines) < $total ?
84     a {-href      => "detail.cgi?type=$type;date=$date;next=" . ($next + $lines),
85        -accesskey => 'n',
86     }, '<img src=/maps/images/next.gif border=0 alt=Next align=middle>' : '';
87
88   my $buttons = $prev_button;
89
90   if ($type eq 'whitelist') {
91     $buttons = $buttons .
92       submit ({-name    => 'action',
93                -value   => 'Blacklist',
94                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
95       submit ({-name    => 'action',
96                -value   => 'Nulllist',
97                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
98       submit ({-name    => 'action',
99                -value   => 'Reset',
100                -onClick => 'return ClearAll (document.detail);'});
101   } elsif ($type eq 'blacklist') {
102     $buttons = $buttons .
103       submit ({-name    => 'action',
104                -value   => 'Whitelist',
105                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
106       submit ({-name    => 'action',
107                -value   => 'Nulllist',
108                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
109       submit ({-name    => 'action',
110                -value   => 'Reset',
111                -onClick => 'return ClearAll (document.detail);'});
112   } elsif ($type eq 'nulllist') {
113     $buttons = $buttons .
114       submit ({-name    => 'action',
115                -value   => 'Whitelist',
116                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
117       submit ({-name    => 'action',
118                -value   => 'Blacklist',
119                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
120       submit ({-name    => 'action',
121                -value   => 'Reset',
122                -onClick => 'return ClearAll (document.detail);'});
123   } else {
124     $buttons = $buttons .
125       submit ({-name    => 'action',
126                -value   => 'Whitelist',
127                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
128       submit ({-name    => 'action',
129                -value   => 'Blacklist',
130                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
131       submit ({-name    => 'action',
132                -value   => 'Nulllist',
133                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) .
134       submit ({-name    => 'action',
135                -value   => 'Reset',
136                -onClick => 'return ClearAll (document.detail);'});
137   } # if
138
139   return $buttons . $next_button;
140 } # MakeButtons
141
142 sub PrintTable {
143   my ($type) = @_;
144
145   my $current = $next + 1;
146
147   print div {-align => 'center'}, b (
148     '(' . $current . '-' . $last . ' of ' . $total . ')');
149   print start_form {
150     -method => 'post',
151     -action => 'processaction.cgi',
152     -name   => 'detail'
153   };
154   print start_table({-align        => 'center',
155                      -id           => $table_name,
156                      -border       => 0,
157                      -cellspacing  => 0,
158                      -cellpadding  => 0,
159                      -width        => '100%'}) . "\n";
160
161   my $buttons = MakeButtons $type;
162
163   print start_div {-class => 'toolbar'};
164   print
165     Tr [
166       td {-class  => 'tablebordertopleft',
167           -valign => 'middle'},
168       td {-class  => 'tablebordertopright',
169           -valign => 'middle',
170           -align  => 'center'}, $buttons,
171     ];
172   print end_div;
173
174   for my $sender (ReturnSenders($userid, $type, $next, $lines, $date)) {
175     my @msgs  = ReturnMessages($userid, $sender);
176     my @msgs2 = @msgs;
177
178     my ($onlist, $seq);
179
180     my $rule      = 'none';
181     my $hit_count = 0;
182
183     ($onlist, $rule, $seq, $hit_count) = OnWhitelist($sender, $userid, 0);
184
185     unless ($onlist) {
186       ($onlist, $rule, $seq, $hit_count) = OnBlacklist($sender, 0);
187
188       unless ($onlist) {
189         ($onlist, $rule, $seq, $hit_count) = OnNulllist($sender, 0);
190       } # unless
191     } # unless
192
193     if ($rule) {
194       $rule =~ s/Matching rule: \(//;
195       $rule =~ s/\)//;
196
197       if ($rule =~ /(\w+):(\d+)/) {
198         my $list     = $1;
199         my $sequence = $2 - 1;
200         my $link     = "<a href=\"/maps/php/list.php?type=$list&next=$sequence\">$list:$2</a>/$hit_count";
201
202         $rule =~ s/\w+:\d+/$link/;
203       } # if
204     } # if
205
206     $next++;
207     print
208       start_Tr {-valign => 'middle'};
209     print
210       td {-class => 'tableborder'}, small ($next,
211         checkbox {-name  => "action$next",
212                   -label => ''}),
213           hidden ({-name    => "email$next",
214                    -default => $sender});
215     print
216       start_td {-align => 'left'};
217     print
218       start_table {-class       => 'tablerightdata',
219                    -cellpadding => 2,
220                    -callspacing => 0,
221                    -border      => 0,
222                    -width       => '100%',
223                    -bgcolor     => '#d4d0c8'};
224
225     # Get subject line
226     my $heading = $msgs2[0][0] || '';
227     $heading = "?subject=$heading" if $heading;
228     print
229       td {-class   => 'tablelabel',
230           -valign  => 'middle',
231           -width   => '40'}, 'Sender:',
232       td {-class   => 'sender',
233           -valign  => 'middle',
234           -width   => '40%'},
235         a {-href   => "mailto:$sender$heading"}, $sender,
236       td {
237           -valign  => 'middle'},
238           $rule;
239     print
240       end_table;
241
242     my $messages = 1;
243
244     for (@msgs) {
245       my $msg_date  = pop @{$_};
246       my $link_date = $msg_date;
247       my $subject   = pop @{$_};
248
249       if ($date eq substr ($msg_date, 0, 10)) {
250         $msg_date = b font {-color => 'green'}, SQLDatetime2UnixDatetime $msg_date;
251       } else {
252         $msg_date = SQLDatetime2UnixDatetime $msg_date;
253       } # if
254
255       $subject = $subject eq '' ? '&lt;Unspecified&gt;' : $subject;
256       $subject = decode_mimewords ($subject);
257       $subject =~ s/\>/&gt;/g;
258       $subject =~ s/\</&lt;/g;
259
260       print
261         start_table {-class       => 'tablerightdata',
262                      -cellpadding => 2,
263                      -cellspacing => 2,
264                      -border      => 0,
265                      -width       => '100%'};
266       print
267         Tr [
268           td {-class   => 'msgnbr',
269               -valign  => 'middle',
270               -rowspan => 2,
271               -width   => '2%'}, $messages++,
272           td {-class   => 'tablelabel',
273               -valign  => 'middle',
274               -width   => '45'}, 'Subject:',
275           td {-class   => 'subject',
276               -valign  => 'middle',
277               -bgcolor => '#ffffff'},
278            a {-href    => "display.cgi?sender=$sender;msg_date=$link_date"}, $subject,
279           td {-class   => 'date',
280               -width   => '150',
281               -valign  => 'middle'}, $msg_date
282         ];
283       print end_table;
284     } # for
285     print end_td;
286     print end_Tr;
287   } # for
288
289   print start_div {-class => 'toolbar'};
290   print
291     Tr [
292       td {-class  => 'tableborderbottomleft',
293           -valign => 'middle'},
294       td {-class  => 'tableborderbottomright',
295           -valign => 'middle'},
296       $buttons
297     ];
298   print end_div;
299   print end_table;
300   print end_form;
301
302   return;
303 } # PrintTable
304
305 # Main
306 my $condition;
307 my @scripts = ('ListActions.js');
308
309 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date) : '';
310
311 $userid = Heading(
312   'getcookie',
313   '',
314   (ucfirst ($type) . ' Report'),
315   $types {$type} [0],
316   $types {$type} [1] . $heading_date,
317   $table_name,
318   @scripts
319 );
320
321 $userid ||= $ENV{USER};
322
323 SetContext($userid);
324 NavigationBar($userid);
325
326 unless ($lines) {
327   my %options = GetUserOptions($userid);
328   $lines = $options{'Page'};
329 } # unless
330
331 if ($date eq '') {
332   $condition .= "userid = '$userid' and type = '$type'";
333 } else {
334   my $sod = $date . ' 00:00:00';
335   my $eod = $date . ' 23:59:59';
336
337   $condition .= "userid = '$userid' and type = '$type' "
338               . "and timestamp > '$sod' and timestamp < '$eod' ";
339 } # if
340
341 $total = count_distinct('log', 'sender', $condition);
342
343 $next ||= 0;
344
345 $last = $next + $lines < $total ? $next + $lines : $total;
346
347 if (($next - $lines) > 0) {
348   $prev = $next - $lines;
349 } else {
350   $prev = $next == 0 ? -1 : 0;
351 } # if
352
353 PrintTable($type);
354
355 Footing($table_name);
356
357 exit;