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} //= '';
291 $rec->{retention} //= '';
294 -class => $dataclass,
297 href => "/maps/php/list.php?type=$rec->{type}&next=" . ($rec->{sequence} - 1),
300 -class => $dataclass,
302 }, "$rec->{hit_count} ",
304 -class => $dataclass,
307 -class => $dataclass,
309 }, "$rec->{retention} ",
311 -class => $rightclass,
314 # $rec will be undefined if this message will be returned
315 print td {-class => $dataclass},
316 td {-class => $dataclass},
317 td {-class => $dataclass},
318 td {-class => $dataclass},
319 td {-class => $rightclass};
326 for my $rec (@$msgs) {
329 # We increased $next earlier so do not add 1 here
330 if (($next % $lines) == (@senders % $lines)) {
331 $dataclass = 'tablebottomdata';
332 $rightclass = 'tablebottomright' if $msgnbr == @$msgs;
334 # Only subjectbottom the last message
335 $subjectclass = 'subjectbottom' if $msgnbr == @$msgs;
338 if ($date eq substr ($rec->{timestamp}, 0, 10)) {
339 $rec->{date} = b font {-color => 'green'}, SQLDatetime2UnixDatetime $rec->{timestamp};
341 $rec->{date} = SQLDatetime2UnixDatetime $rec->{timestamp};
344 $rec->{subject} //= '<Unspecified>';
345 $rec->{subject} = decode_mimewords ($rec->{subject});
346 $rec->{subject} =~ s/\>/>/g;
347 $rec->{subject} =~ s/\</</g;
352 -class => $subjectclass,
355 -href => "display.cgi?sender=$sender;msg_date=$rec->{timestamp}",
356 }, ' ' . $rec->{subject},
357 td {-class => $rightclass,
359 -align => 'right'}, span {-class => 'date'}, $rec->{date} . ' ',
376 my @scripts = ('ListActions.js');
378 my $heading_date =$date ne '' ? ' on ' . FormatDate ($date, 1) : '';
383 (ucfirst ($type) . ' Report'),
385 $types{$type} [1] . $heading_date,
390 $userid ||= $ENV{USER};
393 NavigationBar($userid);
396 my %options = GetUserOptions($userid);
397 $lines = $options{'Page'};
401 $condition .= "type = '$type'";
403 my $sod = $date . ' 00:00:00';
404 my $eod = $date . ' 23:59:59';
406 $condition .= "type = '$type' and timestamp > '$sod' and timestamp < '$eod'";
409 # Need to count distinct on sender
410 $total = CountLogDistinct(
413 additional => $condition,
418 $last = $next + $lines < $total ? $next + $lines : $total;
420 if (($next - $lines) > 0) {
421 $prev = $next - $lines;
423 $prev = $next == 0 ? -1 : 0;
428 Footing($table_name);