Added use lib for clearscm
[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 use lib "$FindBin::Bin/../../lib";
29
30 use MAPS;
31 use MAPSLog;
32 use MAPSWeb;
33 use DateUtils;
34
35 my $type   = param 'type';
36 my $next   = param 'next';
37 my $lines  = param 'lines';
38 my $date   = param 'date';
39
40 $date ||= '';
41
42 my ($userid, $current, $last, $prev, $total);
43
44 my $table_name = 'detail';
45
46 my %types = (
47   'blacklist'   => [
48     'Blacklist report',
49     'The following blacklisted users attempted to email you'
50   ],
51   'whitelist'   => [
52     'Delivered report',
53     'Delivered email from the following users'
54   ],
55   'nulllist'    => [
56     'Discarded report',
57     'Discarded messages from the following users'
58   ],
59   'error'       => [
60     'Error report',
61     'Errors detected'
62   ],
63   'mailloop'    => [
64     'MailLoop report',
65     'Automatically detected mail loops from the following users'
66   ],
67   'registered'  => [
68     'Registered report',
69     'The following users have recently registered'
70   ],
71   'returned'    => [
72     'Returned report',
73     'Sent Register reply to the following users'
74   ]
75 );
76
77 sub MakeButtons($) {
78   my ($type) = @_;
79
80   my $prev_button = $prev >= 0 ?
81     a ({-href      => "detail.cgi?type=$type;date=$date;next=$prev",
82         -accesskey => 'p',
83     }, '<img src=/maps/images/previous.gif border=0 alt=Previous align=middle>') : '';
84   my $next_button = ($next + $lines) < $total ?
85     a {-href      => "detail.cgi?type=$type;date=$date;next=" . ($next + $lines),
86        -accesskey => 'n',
87     }, '<img src=/maps/images/next.gif border=0 alt=Next align=middle>' : '';
88
89   my $buttons = $prev_button;
90
91   if ($type eq 'whitelist') {
92     $buttons = $buttons .
93       submit ({-name    => 'action',
94                -value   => 'Blacklist',
95                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
96       submit ({-name    => 'action',
97                -value   => 'Nulllist',
98                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
99       submit ({-name    => 'action',
100                -value   => 'Reset',
101                -onClick => 'return ClearAll (document.detail);'});
102   } elsif ($type eq 'blacklist') {
103     $buttons = $buttons .
104       submit ({-name    => 'action',
105                -value   => 'Whitelist',
106                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
107       submit ({-name    => 'action',
108                -value   => 'Nulllist',
109                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
110       submit ({-name    => 'action',
111                -value   => 'Reset',
112                -onClick => 'return ClearAll (document.detail);'});
113   } elsif ($type eq 'nulllist') {
114     $buttons = $buttons .
115       submit ({-name    => 'action',
116                -value   => 'Whitelist',
117                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
118       submit ({-name    => 'action',
119                -value   => 'Blacklist',
120                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
121       submit ({-name    => 'action',
122                -value   => 'Reset',
123                -onClick => 'return ClearAll (document.detail);'});
124   } else {
125     $buttons = $buttons .
126       submit ({-name    => 'action',
127                -value   => 'Whitelist',
128                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
129       submit ({-name    => 'action',
130                -value   => 'Blacklist',
131                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
132       submit ({-name    => 'action',
133                -value   => 'Nulllist',
134                -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . '&nbsp;' .
135       submit ({-name    => 'action',
136                -value   => 'Reset',
137                -onClick => 'return ClearAll (document.detail);'});
138   } # if
139
140   return $buttons . $next_button;
141 } # MakeButtons
142
143 sub Body($) {
144   my ($type) = @_;
145
146   my $current = $next + 1;
147
148   print div {-align => 'center'}, b (
149     '(' . $current . '-' . $last . ' of ' . $total . ')');
150   print start_form {
151     -method => 'post',
152     -action => 'processaction.cgi',
153     -name   => 'detail'
154   };
155   print start_table({-align        => 'center',
156                      -id           => $table_name,
157                      -border       => 0,
158                      -cellspacing  => 0,
159                      -cellpadding  => 0,
160                      -width        => '100%'}) . "\n";
161
162   my $buttons = MakeButtons $type;
163
164   print start_div {-class => 'toolbar'};
165   print
166     Tr [
167       td {-class  => 'tablebordertopleft',
168           -valign => 'middle'},
169       td {-class  => 'tablebordertopright',
170           -valign => 'middle',
171           -align  => 'center'}, $buttons,
172     ];
173   print end_div;
174
175   for my $sender (ReturnSenders(
176     userid   => $userid,
177     type     => $type,
178     start_at => $next,
179     lines    => $lines,
180     date     => $date
181   )) {
182     my $msgs = ReturnMessages(
183       userid => $userid,
184       sender => $sender,
185     );
186
187     # This is for the purposes of supplying a subject line if the mailto address
188     # is clicked on. It's kludgy because we are simply grabbing the subject line
189     # of the first email sent where there may be many emails from this sender.
190     # Still it is often the right subject (or a good enough one)
191     #
192     # A little tricky here because of transliteration. If I test for
193     # $msg->[0]{subject} when $msg->[0] is essentially empty I create the hash
194     # making it non empty. Therefore I need to first test if $msgs->[0] exists
195     # first.
196     my $heading = '';
197
198     if ($msgs->[0]) {
199       $heading = $msgs->[0]{subject} if $msgs->[0]{subject};
200     } # if
201
202     my ($onlist, $seq);
203
204     my $rule      = 'none';
205     my $hit_count = 0;
206
207     ($onlist, $rule, $seq, $hit_count) = OnWhitelist($sender, $userid, 0);
208
209     unless ($onlist) {
210       ($onlist, $rule, $seq, $hit_count) = OnBlacklist($sender, 0);
211
212       unless ($onlist) {
213         ($onlist, $rule, $seq, $hit_count) = OnNulllist($sender, 0);
214       } # unless
215     } # unless
216
217     if ($rule) {
218       if ($rule =~ /\((\w+):(\d+)\)\s+"(.*)"/) {
219         my $list     = $1;
220         my $sequence = $2;
221         my $next     = $sequence - 1;
222         $rule        = $3;
223
224         $rule =~ s/\\@/\@/;
225
226         $rule = "<a href=\"/maps/php/list.php?type=$list&next=$next\">$list:$sequence</a>/$hit_count $rule";
227       } # if
228     } # if
229
230     $next++;
231     print
232       start_Tr {-valign => 'middle'};
233     print
234       td {-class => 'tableborder'}, small ($next,
235         checkbox {-name  => "action$next",
236                   -label => ''}),
237           hidden ({-name    => "email$next",
238                    -default => $sender});
239     print
240       start_td {-align => 'left'};
241     print
242       start_table {-class       => 'tablerightdata',
243                    -cellpadding => 2,
244                    -callspacing => 0,
245                    -border      => 0,
246                    -width       => '100%',
247                    -bgcolor     => '#d4d0c8'};
248
249     # Get subject line
250     $heading = "?subject=$heading" if $heading;
251     print
252       td {-class   => 'tablelabel',
253           -valign  => 'middle',
254           -width   => '40'}, 'Sender:',
255       td {-class   => 'sender',
256           -valign  => 'middle',
257           -width   => '40%'},
258         a {-href   => "mailto:$sender$heading"}, $sender,
259       td {
260           -valign  => 'middle'},
261           $rule;
262     print
263       end_table;
264
265     my $messages = 1;
266
267     for my $rec (@$msgs) {
268       if ($date eq substr ($rec->{timestamp}, 0, 10)) {
269         $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
270       } else {
271         $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
272       } # if
273
274       $rec->{subject} //= '&lt;Unspecified&gt;';
275       $rec->{subject} = decode_mimewords ($rec->{subject});
276       $rec->{subject} =~ s/\>/&gt;/g;
277       $rec->{subject} =~ s/\</&lt;/g;
278
279       print
280         start_table {-class       => 'tablerightdata',
281                      -cellpadding => 2,
282                      -cellspacing => 2,
283                      -border      => 0,
284                      -width       => '100%'};
285       print
286         Tr [
287           td {-class   => 'msgnbr',
288               -valign  => 'middle',
289               -rowspan => 2,
290               -width   => '2%'}, $messages++,
291           td {-class   => 'tablelabel',
292               -valign  => 'middle',
293               -width   => '45'}, 'Subject:',
294           td {-class   => 'subject',
295               -valign  => 'middle',
296               -bgcolor => '#ffffff'},
297            a {-href    => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}"}, $rec->{subject},
298           td {-class   => 'date',
299               -width   => '150',
300               -valign  => 'middle'}, $rec->{date},
301         ];
302       print end_table;
303     } # for
304     print end_td;
305     print end_Tr;
306   } # for
307
308   print start_div {-class => 'toolbar'};
309   print
310     Tr [
311       td {-class  => 'tableborderbottomleft',
312           -valign => 'middle'},
313       td {-class  => 'tableborderbottomright',
314           -valign => 'middle'},
315       $buttons
316     ];
317   print end_div;
318   print end_table;
319   print end_form;
320
321   return;
322 } # Body
323
324 # Main
325 my $condition;
326 my @scripts = ('ListActions.js');
327
328 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
329
330 $userid = Heading(
331   'getcookie',
332   '',
333   (ucfirst ($type) . ' Report'),
334   $types{$type} [0],
335   $types{$type} [1] . $heading_date,
336   $table_name,
337   @scripts
338 );
339
340 $userid ||= $ENV{USER};
341
342 SetContext($userid);
343 NavigationBar($userid);
344
345 unless ($lines) {
346   my %options = GetUserOptions($userid);
347   $lines = $options{'Page'};
348 } # unless
349
350 if ($date eq '') {
351   $condition .= "type = '$type'";
352 } else {
353   my $sod = $date . ' 00:00:00';
354   my $eod = $date . ' 23:59:59';
355
356   $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
357 } # if
358
359 $total = CountLog(
360   userid     => $userid,
361   additional => $condition,
362 );
363
364 $next ||= 0;
365
366 $last = $next + $lines < $total ? $next + $lines : $total;
367
368 if (($next - $lines) > 0) {
369   $prev = $next - $lines;
370 } else {
371   $prev = $next == 0 ? -1 : 0;
372 } # if
373
374 Body($type);
375
376 Footing($table_name);
377
378 exit;