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 $list = substr $type, 0, -4 if $type =~ /list$/;
37 my $next = param 'next';
38 my $lines = param 'lines';
39 my $date = param 'date';
43 my ($userid, $current, $last, $prev, $total);
45 my $table_name = 'detail';
50 'The following blacklisted users attempted to email you'
54 'Delivered email from the following users'
58 'Discarded messages from the following users'
66 'Automatically detected mail loops from the following users'
70 'The following users have recently registered'
74 'Sent Register reply to the following users'
81 return '' unless $rec->{pattern} or $rec->{domain};
83 $rec->{pattern} //= '';
84 $rec->{domain} //= '';
86 return "$rec->{pattern}\@$rec->{domain}";
92 my $prev_button = $prev >= 0 ?
93 a ({-href => "detail.cgi?type=$type;date=$date;next=$prev",
95 }, '<img src=/maps/images/previous.gif border=0 alt=Previous align=middle>') : '';
96 my $next_button = ($next + $lines) < $total ?
97 a {-href => "detail.cgi?type=$type;date=$date;next=" . ($next + $lines),
99 }, '<img src=/maps/images/next.gif border=0 alt=Next align=middle>' : '';
101 my $buttons = $prev_button;
103 if ($type eq 'whitelist') {
104 $buttons = $buttons .
105 submit ({-name => 'action',
106 -value => 'Blacklist',
107 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
108 submit ({-name => 'action',
109 -value => 'Nulllist',
110 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
111 submit ({-name => 'action',
113 -onClick => 'return ClearAll (document.detail);'});
114 } elsif ($type eq 'blacklist') {
115 $buttons = $buttons .
116 submit ({-name => 'action',
117 -value => 'Whitelist',
118 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
119 submit ({-name => 'action',
120 -value => 'Nulllist',
121 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
122 submit ({-name => 'action',
124 -onClick => 'return ClearAll (document.detail);'});
125 } elsif ($type eq 'nulllist') {
126 $buttons = $buttons .
127 submit ({-name => 'action',
128 -value => 'Whitelist',
129 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
130 submit ({-name => 'action',
131 -value => 'Blacklist',
132 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
133 submit ({-name => 'action',
135 -onClick => 'return ClearAll (document.detail);'});
137 $buttons = $buttons .
138 submit ({-name => 'action',
139 -value => 'Whitelist',
140 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
141 submit ({-name => 'action',
142 -value => 'Blacklist',
143 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
144 submit ({-name => 'action',
145 -value => 'Nulllist',
146 -onClick => 'return CheckAtLeast1Checked (document.detail);'}) . ' ' .
147 submit ({-name => 'action',
149 -onClick => 'return ClearAll (document.detail);'});
155 }, $buttons . $next_button;
163 my $current = $next + 1;
167 print div {-align => 'center'}, b (
168 '(' . $current . '-' . $last . ' of ' . $total . ')');
171 -action => 'processaction.cgi',
177 print start_div {-id => 'highlightrow'};
179 print start_table({-align => 'center',
184 -width => '100%'}) . "\n";
188 th {-class => 'tablebordertopleft'}, '',
189 th {-class => 'tableborder'}, 'Sender',
190 th {-class => 'tableborder'}, 'List',
191 th {-class => 'tableborder'}, 'Hit Count',
192 th {-class => 'tableborder'}, 'Rule',
193 th {-class => 'tableborder'}, 'Retention',
194 th {-class => 'tablebordertopright'}, 'Comment/Date',
197 my @senders = ReturnSenders(
205 for my $sender (@senders) {
206 my $msgs = ReturnMessages(
211 my $leftclass = 'tableleftdata';
212 my $dataclass = 'tabledata';
213 my $rightclass = 'tablerightdata';
214 my $senderclass = 'sender';
215 my $subjectclass = 'subject';
217 # Check to see if this is the last line
218 if ((($next + 1) % $lines) == (@senders % $lines)) {
219 # We always "bottom" the first column
220 $leftclass = 'tablebottomleft';
222 # Check to see if there any message lines to display
224 $dataclass = 'tablebottomdata';
225 $rightclass = 'tablebottomright';
226 $senderclass = 'senderbottom';
230 # This is for the purposes of supplying a subject line if the mailto address
231 # is clicked on. It's kludgy because we are simply grabbing the subject line
232 # of the first email sent where there may be many emails from this sender
233 # Still it is often the right subject (or a good enough one)
235 # A little tricky here because of transliteration. If I test for
236 # $msg->[0]{subject} when $msg->[0] is essentially empty I create the hash
237 # making it non empty. Therefore I need to first test if $msgs->[0] exists
242 $heading = $msgs->[0]{subject} if $msgs->[0]{subject};
245 ($onlist, $rec) = OnWhitelist($sender, $userid, 0);
248 ($onlist, $rec) = OnBlacklist($sender, 0);
251 ($onlist, $rec) = OnNulllist($sender, 0);
258 my $rowspan = @$msgs + 1;
260 print start_Tr {-valign => 'middle'};
262 -class => $leftclass,
265 -rowspan => $rowspan,
268 -name => "action$next",
274 -name => "email$next",
279 $heading = "?subject=$heading" if $heading;
282 -class => $senderclass,
284 -href => "mailto:$sender$heading",
288 my $listlink = ($rec->{type} and $rec->{sequence}) ? "$rec->{type}:$rec->{sequence}" : '';
290 $rec->{comment} //= '';
293 -class => $dataclass,
296 href => "/maps/php/list.php?type=$rec->{type}&next=" . ($rec->{sequence} - 1),
299 -class => $dataclass,
301 }, "$rec->{hit_count} ",
303 -class => $dataclass,
306 -class => $dataclass,
308 }, "$rec->{retention} ",
310 -class => $rightclass,
313 # $rec will be undefined if this message will be returned
314 print td {-class => $dataclass},
315 td {-class => $dataclass},
316 td {-class => $dataclass},
317 td {-class => $dataclass},
318 td {-class => $rightclass};
325 for my $rec (@$msgs) {
328 # We increased $next earlier so do not add 1 here
329 if (($next % $lines) == (@senders % $lines)) {
330 $dataclass = 'tablebottomdata';
331 $rightclass = 'tablebottomright' if $msgnbr == @$msgs;
333 # Only subjectbottom the last message
334 $subjectclass = 'subjectbottom' if $msgnbr == @$msgs;
337 if ($date eq substr ($rec->{timestamp}, 0, 10)) {
338 $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
340 $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
343 $rec->{subject} //= '<Unspecified>';
344 $rec->{subject} = decode_mimewords ($rec->{subject});
345 $rec->{subject} =~ s/\>/>/g;
346 $rec->{subject} =~ s/\</</g;
351 -class => $subjectclass,
354 -href => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}",
355 }, ' ' . $rec->{subject},
356 td {-class => $rightclass,
358 -align => 'right'}, span {-class => 'date'}, $rec->{date} . ' ',
375 my @scripts = ('ListActions.js');
377 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
382 (ucfirst ($type) . ' Report'),
384 $types{$type} [1] . $heading_date,
389 $userid ||= $ENV{USER};
392 NavigationBar($userid);
395 my %options = GetUserOptions($userid);
396 $lines = $options{'Page'};
400 $condition .= "type = '$type'";
402 my $sod = $date . ' 00:00:00';
403 my $eod = $date . ' 23:59:59';
405 $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
408 # Need to count distinct on sender
409 $total = CountLogDistinct(
412 additional => $condition,
417 $last = $next + $lines < $total ? $next + $lines : $total;
419 if (($next - $lines) > 0) {
420 $prev = $next - $lines;
422 $prev = $next == 0 ? -1 : 0;
427 Footing($table_name);