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_table({-align => 'center',
168 -width => '100%'}) . "\n";
172 td {-class => 'tablebordertopleft'}, ' ',
173 th {-class => 'tableborder'}, 'Sender',
174 th {-class => 'tableborder'}, 'List',
175 th {-class => 'tableborder'}, 'Hit Count',
176 th {-class => 'tableborder'}, 'Rule',
177 th {-class => 'tablebordertopright'}, 'Comment',
180 my @senders = ReturnSenders(
188 for my $sender (@senders) {
189 my $msgs = ReturnMessages(
194 my $leftclass = 'tableleftdata';
195 my $dataclass = 'tabledata';
196 my $rightclass = 'tablerightdata';
197 my $senderclass = 'sender';
198 my $subjectclass = 'subject';
200 # Check to see if this is the last line
201 if ((($next + 1) % $lines) == (@senders % $lines)) {
202 # We always "bottom" the first column
203 $leftclass = 'tablebottomleft';
205 # Check to see if there any message lines to display
207 $dataclass = 'tablebottomdata';
208 $rightclass = 'tablebottomright';
209 $senderclass = 'senderbottom';
213 # This is for the purposes of supplying a subject line if the mailto address
214 # is clicked on. It's kludgy because we are simply grabbing the subject line
215 # of the first email sent where there may be many emails from this sender
216 # Still it is often the right subject (or a good enough one)
218 # A little tricky here because of transliteration. If I test for
219 # $msg->[0]{subject} when $msg->[0] is essentially empty I create the hash
220 # making it non empty. Therefore I need to first test if $msgs->[0] exists
225 $heading = $msgs->[0]{subject} if $msgs->[0]{subject};
233 ($onlist, $rule, $seq, $hit_count) = OnWhitelist($sender, $userid, 0);
236 ($onlist, $rule, $seq, $hit_count) = OnBlacklist($sender, 0);
239 ($onlist, $rule, $seq, $hit_count) = OnNulllist($sender, 0);
243 my ($list, $sequence, $comment);
247 if ($rule =~ /\((\w+):(\d+)\)\s+"(\S*)"/) {
252 } elsif ($rule =~ /\((\w+):(\d+)\)\s+"(\S*) - (.*)"/) {
265 my $rowspan = @$msgs + 1;
267 print start_Tr {-valign => 'middle'};
269 -class => $leftclass,
272 -rowspan => $rowspan,
275 -name => "action$next",
281 -name => "email$next",
286 $heading = "?subject=$heading" if $heading;
289 -class => $senderclass,
291 -href => "mailto:$sender$heading",
294 my $listlink = ($list and $sequence) ? "$list:$sequence" : ' ';
297 -class => $dataclass,
300 href => "/maps/php/list.php?type=$list&next=" . ($sequence - 1),
303 -class => $dataclass,
305 }, "$hit_count ",
307 -class => $dataclass,
310 -class => $rightclass,
314 for my $rec (@$msgs) {
315 # We increased $next earlier so do not add 1 here
316 if (($next % $lines) == (@senders % $lines)) {
317 $dataclass = 'tablebottomdata';
318 $rightclass = 'tablebottomright';
319 $subjectclass = 'subjectbottom';
322 if ($date eq substr ($rec->{timestamp}, 0, 10)) {
323 $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
325 $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
328 $rec->{subject} //= '<Unspecified>';
329 $rec->{subject} = decode_mimewords ($rec->{subject});
330 $rec->{subject} =~ s/\>/>/g;
331 $rec->{subject} =~ s/\</</g;
336 -class => $subjectclass,
339 -href => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}",
340 }, ' ' . $rec->{subject},
341 td {-class => $rightclass,
343 -align => 'right'}, span {-class => 'date'}, $rec->{date} . ' ',
358 my @scripts = ('ListActions.js');
360 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
365 (ucfirst ($type) . ' Report'),
367 $types{$type} [1] . $heading_date,
372 $userid ||= $ENV{USER};
375 NavigationBar($userid);
378 my %options = GetUserOptions($userid);
379 $lines = $options{'Page'};
383 $condition .= "type = '$type'";
385 my $sod = $date . ' 00:00:00';
386 my $eod = $date . ' 23:59:59';
388 $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
393 additional => $condition,
398 $last = $next + $lines < $total ? $next + $lines : $total;
400 if (($next - $lines) > 0) {
401 $prev = $next - $lines;
403 $prev = $next == 0 ? -1 : 0;
408 Footing($table_name);