2 ################################################################################
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 $
12 # (c) Copyright 2000-2021, Andrew@DeFaria.com, all rights reserved.
14 ################################################################################
18 use MIME::Words qw(:all);
20 use CGI qw(:standard *table start_td end_td start_Tr end_Tr start_div end_div);
21 use CGI::Carp 'fatalsToBrowser';
25 local $0 = $FindBin::Script;
27 use lib "$FindBin::Bin/../lib";
28 use lib "$FindBin::Bin/../../lib";
35 my $type = param 'type';
36 my $next = param 'next';
37 my $lines = param 'lines';
38 my $date = param 'date';
42 my ($userid, $current, $last, $prev, $total);
44 my $table_name = 'detail';
49 'The following blacklisted users attempted to email you'
53 'Delivered email from the following users'
57 'Discarded messages from the following users'
65 'Automatically detected mail loops from the following users'
69 'The following users have recently registered'
73 'Sent Register reply to the following users'
80 my $prev_button = $prev >= 0 ?
81 a ({-href => "detail.cgi?type=$type;date=$date;next=$prev",
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),
87 }, '<img src=/maps/images/next.gif border=0 alt=Next align=middle>' : '';
89 my $buttons = $prev_button;
91 if ($type eq 'whitelist') {
93 submit ({-name => 'action',
94 -value => 'Blacklist',
95 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
96 submit ({-name => 'action',
98 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
99 submit ({-name => 'action',
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);'}) . ' ' .
107 submit ({-name => 'action',
108 -value => 'Nulllist',
109 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
110 submit ({-name => 'action',
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);'}) . ' ' .
118 submit ({-name => 'action',
119 -value => 'Blacklist',
120 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
121 submit ({-name => 'action',
123 -onClick => 'return ClearAll (document.detail);'});
125 $buttons = $buttons .
126 submit ({-name => 'action',
127 -value => 'Whitelist',
128 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
129 submit ({-name => 'action',
130 -value => 'Blacklist',
131 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
132 submit ({-name => 'action',
133 -value => 'Nulllist',
134 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
135 submit ({-name => 'action',
137 -onClick => 'return ClearAll (document.detail);'});
143 }, $buttons . $next_button;
151 my $current = $next + 1;
153 print div {-align => 'center'}, b (
154 '(' . $current . '-' . $last . ' of ' . $total . ')');
157 -action => 'processaction.cgi',
163 print start_div {-id => 'highlightrow'};
165 print start_table({-align => 'center',
170 -width => '100%'}) . "\n";
174 th {-class => 'tablebordertopleft'}, '',
175 th {-class => 'tableborder'}, 'Sender',
176 th {-class => 'tableborder'}, 'List',
177 th {-class => 'tableborder'}, 'Hit Count',
178 th {-class => 'tableborder'}, 'Rule',
179 th {-class => 'tablebordertopright'}, 'Comment',
182 my @senders = ReturnSenders(
190 for my $sender (@senders) {
191 my $msgs = ReturnMessages(
196 my $leftclass = 'tableleftdata';
197 my $dataclass = 'tabledata';
198 my $rightclass = 'tablerightdata';
199 my $senderclass = 'sender';
200 my $subjectclass = 'subject';
202 # Check to see if this is the last line
203 if ((($next + 1) % $lines) == (@senders % $lines)) {
204 # We always "bottom" the first column
205 $leftclass = 'tablebottomleft';
207 # Check to see if there any message lines to display
209 $dataclass = 'tablebottomdata';
210 $rightclass = 'tablebottomright';
211 $senderclass = 'senderbottom';
215 # This is for the purposes of supplying a subject line if the mailto address
216 # is clicked on. It's kludgy because we are simply grabbing the subject line
217 # of the first email sent where there may be many emails from this sender
218 # Still it is often the right subject (or a good enough one)
220 # A little tricky here because of transliteration. If I test for
221 # $msg->[0]{subject} when $msg->[0] is essentially empty I create the hash
222 # making it non empty. Therefore I need to first test if $msgs->[0] exists
227 $heading = $msgs->[0]{subject} if $msgs->[0]{subject};
235 ($onlist, $rule, $seq, $hit_count) = OnWhitelist($sender, $userid, 0);
238 ($onlist, $rule, $seq, $hit_count) = OnBlacklist($sender, 0);
241 ($onlist, $rule, $seq, $hit_count) = OnNulllist($sender, 0);
253 if ($rule =~ /\((\w+):(\d+)\)\s+"(\S*)"/) {
258 } elsif ($rule =~ /\((\w+):(\d+)\)\s+"(\S*) - (.*)"/) {
272 my $rowspan = @$msgs + 1;
274 print start_Tr {-valign => 'middle'};
276 -class => $leftclass,
279 -rowspan => $rowspan,
282 -name => "action$next",
288 -name => "email$next",
293 $heading = "?subject=$heading" if $heading;
296 -class => $senderclass,
298 -href => "mailto:$sender$heading",
301 my $listlink = ($list and $sequence) ? "$list:$sequence" : ' ';
304 -class => $dataclass,
307 href => "/maps/php/list.php?type=$list&next=" . ($sequence - 1),
310 -class => $dataclass,
312 }, "$hit_count ",
314 -class => $dataclass,
317 -class => $rightclass,
323 for my $rec (@$msgs) {
326 # We increased $next earlier so do not add 1 here
327 if (($next % $lines) == (@senders % $lines)) {
328 $dataclass = 'tablebottomdata';
329 $rightclass = 'tablebottomright' if $msgnbr == @$msgs;
331 # Only subjectbottom the last message
332 $subjectclass = 'subjectbottom' if $msgnbr == @$msgs;
335 if ($date eq substr ($rec->{timestamp}, 0, 10)) {
336 $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
338 $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
341 $rec->{subject} //= '<Unspecified>';
342 $rec->{subject} = decode_mimewords ($rec->{subject});
343 $rec->{subject} =~ s/\>/>/g;
344 $rec->{subject} =~ s/\</</g;
349 -class => $subjectclass,
352 -href => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}",
353 }, ' ' . $rec->{subject},
354 td {-class => $rightclass,
356 -align => 'right'}, span {-class => 'date'}, $rec->{date} . ' ',
373 my @scripts = ('ListActions.js');
375 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
380 (ucfirst ($type) . ' Report'),
382 $types{$type} [1] . $heading_date,
387 $userid ||= $ENV{USER};
390 NavigationBar($userid);
393 my %options = GetUserOptions($userid);
394 $lines = $options{'Page'};
398 $condition .= "type = '$type'";
400 my $sod = $date . ' 00:00:00';
401 my $eod = $date . ' 23:59:59';
403 $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
406 # Need to count distinct on sender
407 $total = CountLogDistinct(
410 additional => $condition,
415 $last = $next + $lines < $total ? $next + $lines : $total;
417 if (($next - $lines) > 0) {
418 $prev = $next - $lines;
420 $prev = $next == 0 ? -1 : 0;
425 Footing($table_name);