Welcome to MAPS 2.0
[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
20 use CGI qw(:standard *table start_td end_td start_Tr end_Tr start_div end_div);
21 use CGI::Carp 'fatalsToBrowser';
22
23 use FindBin;
24
25 local $0 = $FindBin::Script;
26
27 use lib "$FindBin::Bin/../lib";
28
29 use MAPS;
30 use MAPSLog;
31 use MAPSWeb;
32 use DateUtils;
33
34 my $type   = param 'type';
35 my $next   = param 'next';
36 my $lines  = param 'lines';
37 my $date   = param 'date';
38
39 $date ||= '';
40
41 my ($userid, $current, $last, $prev, $total);
42
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);'}) . '&nbsp;' .
95       submit ({-name    => 'action',
96                -value   => 'Nulllist',
97                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
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);'}) . '&nbsp;' .
106       submit ({-name    => 'action',
107                -value   => 'Nulllist',
108                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
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);'}) . '&nbsp;' .
117       submit ({-name    => 'action',
118                -value   => 'Blacklist',
119                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
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);'}) . '&nbsp;' .
128       submit ({-name    => 'action',
129                -value   => 'Blacklist',
130                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
131       submit ({-name    => 'action',
132                -value   => 'Nulllist',
133                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
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 Body($) {
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(
175     userid   => $userid,
176     type     => $type,
177     start_at => $next,
178     lines    => $lines,
179     date     => $date
180   )) {
181     my $msgs = ReturnMessages(
182       userid => $userid,
183       sender => $sender,
184     );
185
186     # This is for the purposes of supplying a subject line if the mailto address
187     # is clicked on. It's kludgy because we are simply grabbing the subject line
188     # of the first email sent where there may be many emails from this sender.
189     # Still it is often the right subject (or a good enough one)
190     #
191     # A little tricky here because of transliteration. If I test for
192     # $msg->[0]{subject} when $msg->[0] is essentially empty I create the hash
193     # making it non empty. Therefore I need to first test if $msgs->[0] exists
194     # first.
195     my $heading = '';
196
197     if ($msgs->[0]) {
198       $heading = $msgs->[0]{subject} if $msgs->[0]{subject};
199     } # if
200
201     my ($onlist, $seq);
202
203     my $rule      = 'none';
204     my $hit_count = 0;
205
206     ($onlist, $rule, $seq, $hit_count) = OnWhitelist($sender, $userid, 0);
207
208     unless ($onlist) {
209       ($onlist, $rule, $seq, $hit_count) = OnBlacklist($sender, 0);
210
211       unless ($onlist) {
212         ($onlist, $rule, $seq, $hit_count) = OnNulllist($sender, 0);
213       } # unless
214     } # unless
215
216     if ($rule) {
217       if ($rule =~ /\((\w+):(\d+)\)\s+"(.*)"/) {
218         my $list     = $1;
219         my $sequence = $2;
220         my $next     = $sequence - 1;
221         $rule        = $3;
222
223         $rule =~ s/\\@/\@/;
224
225         $rule = "<a href=\"/maps/php/list.php?type=$list&next=$next\">$list:$sequence</a>/$hit_count $rule";
226       } # if
227     } # if
228
229     $next++;
230     print
231       start_Tr {-valign => 'middle'};
232     print
233       td {-class => 'tableborder'}, small ($next,
234         checkbox {-name  => "action$next",
235                   -label => ''}),
236           hidden ({-name    => "email$next",
237                    -default => $sender});
238     print
239       start_td {-align => 'left'};
240     print
241       start_table {-class       => 'tablerightdata',
242                    -cellpadding => 2,
243                    -callspacing => 0,
244                    -border      => 0,
245                    -width       => '100%',
246                    -bgcolor     => '#d4d0c8'};
247
248     # Get subject line
249     $heading = "?subject=$heading" if $heading;
250     print
251       td {-class   => 'tablelabel',
252           -valign  => 'middle',
253           -width   => '40'}, 'Sender:',
254       td {-class   => 'sender',
255           -valign  => 'middle',
256           -width   => '40%'},
257         a {-href   => "mailto:$sender$heading"}, $sender,
258       td {
259           -valign  => 'middle'},
260           $rule;
261     print
262       end_table;
263
264     my $messages = 1;
265
266     for my $rec (@$msgs) {
267       if ($date eq substr ($rec->{timestamp}, 0, 10)) {
268         $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
269       } else {
270         $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
271       } # if
272
273       $rec->{subject} //= '&lt;Unspecified&gt;';
274       $rec->{subject} = decode_mimewords ($rec->{subject});
275       $rec->{subject} =~ s/\>/&gt;/g;
276       $rec->{subject} =~ s/\</&lt;/g;
277
278       print
279         start_table {-class       => 'tablerightdata',
280                      -cellpadding => 2,
281                      -cellspacing => 2,
282                      -border      => 0,
283                      -width       => '100%'};
284       print
285         Tr [
286           td {-class   => 'msgnbr',
287               -valign  => 'middle',
288               -rowspan => 2,
289               -width   => '2%'}, $messages++,
290           td {-class   => 'tablelabel',
291               -valign  => 'middle',
292               -width   => '45'}, 'Subject:',
293           td {-class   => 'subject',
294               -valign  => 'middle',
295               -bgcolor => '#ffffff'},
296            a {-href    => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}"}, $rec->{subject},
297           td {-class   => 'date',
298               -width   => '150',
299               -valign  => 'middle'}, $rec->{date},
300         ];
301       print end_table;
302     } # for
303     print end_td;
304     print end_Tr;
305   } # for
306
307   print start_div {-class => 'toolbar'};
308   print
309     Tr [
310       td {-class  => 'tableborderbottomleft',
311           -valign => 'middle'},
312       td {-class  => 'tableborderbottomright',
313           -valign => 'middle'},
314       $buttons
315     ];
316   print end_div;
317   print end_table;
318   print end_form;
319
320   return;
321 } # Body
322
323 # Main
324 my $condition;
325 my @scripts = ('ListActions.js');
326
327 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
328
329 $userid = Heading(
330   'getcookie',
331   '',
332   (ucfirst ($type) . ' Report'),
333   $types{$type} [0],
334   $types{$type} [1] . $heading_date,
335   $table_name,
336   @scripts
337 );
338
339 $userid ||= $ENV{USER};
340
341 SetContext($userid);
342 NavigationBar($userid);
343
344 unless ($lines) {
345   my %options = GetUserOptions($userid);
346   $lines = $options{'Page'};
347 } # unless
348
349 if ($date eq '') {
350   $condition .= "type = '$type'";
351 } else {
352   my $sod = $date . ' 00:00:00';
353   my $eod = $date . ' 23:59:59';
354
355   $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
356 } # if
357
358 $total = CountLog(
359   userid     => $userid,
360   additional => $condition,
361 );
362
363 $next ||= 0;
364
365 $last = $next + $lines < $total ? $next + $lines : $total;
366
367 if (($next - $lines) > 0) {
368   $prev = $next - $lines;
369 } else {
370   $prev = $next == 0 ? -1 : 0;
371 } # if
372
373 Body($type);
374
375 Footing($table_name);
376
377 exit;