3389c6a7bde03b285108d22201fae8f033a879ee
[clearscm.git] / maps / lib / MAPSWeb.pm
1 #################################################################################
2 #
3 # File:         $RCSfile: MAPSWeb.pm,v $
4 # Revision:     $Revision: 1.1 $
5 # Description:  Routines for generating portions of MAPSWeb
6 # Author:       Andrew@DeFaria.com
7 # Created:      Fri Nov 29 14:17:21  2002
8 # Modified:     $Date: 2013/06/12 14:05:47 $
9 # Language:     perl
10 #
11 # (c) Copyright 2000-2006, Andrew@DeFaria.com, all rights reserved.
12 #
13 ################################################################################
14 package MAPSWeb;
15
16 use strict;
17 use warnings;
18
19 use base qw(Exporter);
20
21 use DateUtils;
22
23 use MAPS;
24 use MAPSLog;
25
26 use CGI qw(:standard *table start_Tr end_Tr start_div end_div);
27
28 our @EXPORT = qw(
29   DebugWeb
30   DisplayError
31   Footing
32   Heading
33   NavigationBar
34 );
35
36 sub getquickstats(%) {
37   my (%params) = @_;
38
39   my %dates = GetStats(
40     userid => $params{userid},
41     days   => 1,
42     date   => $params{date},
43   );
44
45   my $date = $params{date};
46
47   for (@MAPSLog::Types) {
48     $dates{$date}{processed} += $dates{$date}{$_};
49   } # for
50
51   return %dates;
52 } # getquickstats
53
54 sub displayquickstats($) {
55   my ($userid) = @_;
56
57   # Quick stats are today only
58   my $today = Today2SQLDatetime;
59   my $time  = substr $today, 11;
60   my $date  = substr $today, 0, 10;
61   my %dates = getquickstats(
62     userid => $userid,
63     date   => $date
64   );
65
66   print start_div {-class => 'quickstats'};
67   print h4 {-class    => 'todaysactivity',
68             -align    => 'center'},
69     'Today\'s Activity';
70   print p {-align     => 'center'},
71     b ('as of ' . FormatTime($time));
72   print start_table {
73     -align       => 'center',
74     -border      => 0,
75     -cellspacing => 0,
76     -cellpadding => 2};
77   print start_Tr {-align => 'right'};
78   print
79     td {-class => 'smalllabel',
80         -align => 'right'},
81       'Processed';
82   print
83     td {-class => 'smallnumber',
84         -align => 'right'},
85       $dates{$date}{'processed'};
86   print
87     td {-class => 'smallnumber',
88         -align => 'right'},
89       'n/a';
90   print end_Tr;
91
92   for (@MAPSLog::Types) {
93     print start_Tr {-align => 'right'};
94
95     my $value = $dates{$date}{$_};
96     my $percent;
97
98     if ($_ eq 'mailloop' || $_ eq 'registered') {
99       $percent = 'n/a';
100     } else {
101       $percent = $dates{$date}{processed} == 0 ?
102         0 : $dates{$date}{$_} / $dates{$date}{processed} * 100;
103       $percent = sprintf '%5.1f%s', $percent, '%';
104     } # if
105
106     my $report = ucfirst $_;
107
108     if ($value) {
109       $report  = a {-href => "detail.cgi?type=$_;date=$date"}, $report;
110       $value   = a {-href => "detail.cgi?type=$_;date=$date"}, $value;
111       $percent = a {-href => "detail.cgi?type=$_;date=$date"}, $percent;
112     } # if
113
114     print td {-class => 'smalllabel'},  $report,
115           td {-class => 'smallnumber'}, $value,
116           td {-class => 'smallnumber'}, $percent;
117
118     print end_Tr;
119   } # for
120
121   print end_table;
122   print end_div;
123
124   return;
125 } # displayquickstats
126
127 sub Footing(;$) {
128   my ($table_name) = @_;
129
130   # General footing (copyright). Note we calculate the current year
131   # so that the copyright automatically extends itself.
132   my $year = substr((scalar (localtime)), 20, 4);
133
134   print start_div {-class => "copyright"};
135   print "Copyright © 2001-$year - All rights reserved";
136   print br (
137     a ({-href => 'https://defaria.com'},
138       'Andrew DeFaria'),
139     a ({-href => 'mailto:Andrew@DeFaria.com'},
140       '<Andrew@DeFaria.com>'));
141   print end_div;
142
143   print end_div; # This div ends "content" which was started in Heading
144   print "<script language='JavaScript1.2'>AdjustTableWidth (\"$table_name\");</script>"
145     if $table_name;
146   print end_html;
147
148   return;
149 } # Footing
150
151 sub DebugWeb($) {
152   my ($msg) = @_;
153
154   print br, font({ -class => 'error' }, 'DEBUG: '), $msg;
155
156   return;
157 } # Debug
158
159 sub DisplayError($) {
160   my ($errmsg) = @_;
161
162   print h3({
163     -class => 'error',
164     -align => 'center'},
165     'ERROR: ' . $errmsg
166   );
167
168   Footing;
169
170   exit 1;
171 } # DisplayError
172
173 # This subroutine puts out the header for web pages. It is called by
174 # various cgi scripts thus has a few parameters.
175 sub Heading($$$$;$$@) {
176   my ($action,          # One of getcookie, setcookie, unsetcookie
177       $userid,          # User id (if setting a cookie)
178       $title,           # Title string
179       $h1,              # H1 header
180       $h2,              # H2 header (optional)
181       $table_name,      # Name of table in page, if any
182       @scripts) = @_;   # Array of JavaScript scripts to include
183
184   my @java_scripts;
185   my $cookie;
186
187   # Since CheckAddress appears on all pages (well except for the login
188   # page) include it by default along with MAPSUtils.js
189   push @java_scripts, [
190     {-language => 'JavaScript1.2',
191      -src      => '/maps/JavaScript/MAPSUtils.js'},
192     {-language => 'JavaScript1.2',
193      -src      => '/maps/JavaScript/CheckAddress.js'}
194   ];
195
196   # Add on any additional JavaScripts that the caller wants. Note the
197   # odd single element array of hashes but that's what CGI requires!
198   # Build up scripts from array
199   for (@scripts) {
200     push @{$java_scripts[0]},
201       {-language => 'JavaScript1.2',
202        -src      => "/maps/JavaScript/$_"}
203   } # foreach
204
205   # Since Heading is called from various scripts we sometimes need to
206   # set a cookie, other times delete a cookie but most times return the
207   # cookie.
208   if ($action eq 'getcookie') {
209     # Get userid from cookie
210     $userid = cookie ('MAPSUser');
211   } elsif ($action eq 'setcookie') {
212     $cookie = cookie (
213        -name    => 'MAPSUser',
214        -value   => $userid,
215        -expires => '+1y',
216        -path    => '/maps'
217     );
218   } elsif ($action eq 'unsetcookie') {
219     $cookie = cookie (
220        -name    => 'MAPSUser',
221        -value   => '',
222        -expires => '-1d',
223        -path    => '/maps'
224     );
225   } # if
226
227   print header(
228     -title  => $title,
229     -cookie => $cookie
230   );
231
232   if ($table_name) {
233     print start_html(
234       -title    => $title,
235       -author   => 'Andrew\@DeFaria.com',
236       -style    => {-src    => '/maps/css/MAPSStyle.css'},
237       -onResize => "AdjustTableWidth (\"$table_name\");",
238       -head     => [
239       Link({-rel  => 'icon',
240         -href => '/maps/MAPS.png',
241         -type => 'image/png'}),
242       Link({-rel  => 'shortcut icon',
243         -href => '/maps/favicon.ico'})
244       ],
245       -script    => @java_scripts);
246   } else {
247     print start_html(
248       -title  => $title,
249       -author => 'Andrew\@DeFaria.com',
250       -style  => {-src    => '/maps/css/MAPSStyle.css'},
251       -head   => [
252       Link({-rel  => 'icon',
253         -href => '/maps/MAPS.png',
254         -type => 'image/png'}),
255       Link({-rel  => 'shortcut icon',
256         -href => '/maps/favicon.ico'})],
257         -script    => @java_scripts);
258   } # if
259
260   print start_div {class => 'heading'};
261   print h2 {
262     -align => 'center',
263     -class => 'header'}, $h1;
264
265   if (defined $h2 && $h2 ne '') {
266     print h3 {
267       -align => 'center',
268       -class => 'header'}, $h2;
269   } # if
270   print end_div;
271
272   # Start body content
273   print start_div {-class => 'content'};
274
275   return $userid
276 } # Heading
277
278 sub NavigationBar($) {
279   my ($userid) = @_;
280
281   print start_div {-id => 'leftbar'};
282
283   unless ($userid) {
284     print h2({-align => 'center'}, font({-color => 'white'}, "MAPS $MAPS::Version"));
285     print div ({-class => 'username'}, 'Welcome to MAPS');
286     print div ({-class => 'menu'},
287       (a {-href => '/maps/doc/'},
288         'What is MAPS?<br>'),
289       (a {-href => '/maps/doc/SPAM.html'},
290         'What is SPAM?<br>'),
291       (a {-href => '/maps/doc/Requirements.html'},
292         'Requirements<br>'),
293       (a {-href => '/maps/SignupForm.html'},
294         'Signup<br>'),
295       (a {-href => '/maps/doc/Using.html'},
296         'Using MAPS<br>'),
297       (a {-href => '/maps/doc/'},
298         'Help<br>'),
299     );
300   } else {
301     print h2({-align => 'center'}, font({-color => 'white'}, "MAPS $MAPS::Version"));
302     print div ({-class => 'username'}, 'Welcome '. ucfirst $userid);
303
304     print div ({-class => 'menu'},
305       (a {-href => '/maps/'},
306         'Home<br>'),
307       (a {-href => '/maps/bin/stats.cgi'},
308         'Statistics<br>'),
309       (a {-href => '/maps/bin/editprofile.cgi'},
310         'Profile<br>'),
311       (a {-href => '/maps/php/Reports.php'},
312         'Reports<br>'),
313       (a {-href => '/maps/php/list.php?type=white'},
314         'White<br>'),
315       (a {-href => '/maps/php/list.php?type=black'},
316         'Black<br>'),
317       (a {-href => '/maps/php/list.php?type=null'},
318         'Null<br>'),
319       (a {-href => '/maps/doc/'},
320         'Help<br>'),
321       (a {-href => '/maps/adm/'},
322         'MAPS<br>'),
323       (a {-href => '/maps/?logout=yes'},
324         'Logout'),
325     );
326
327     displayquickstats($userid);
328
329     print start_div {-class => 'search'};
330     print start_form {-method => 'get',
331                       -action => '/maps/bin/search.cgi',
332                       -name   => 'search'};
333     print 'Search Sender/Subject',
334       textfield {-class     => 'searchfield',
335                  -id        => 'searchfield',
336                  -name      => 'str',
337                  -size      => 20,
338                  -maxlength => 255,
339                  -value     => '',
340                  -onclick   => "document.search.str.value = '';"};
341     print end_form;
342     print end_div;
343
344     print start_div {-class => 'search'};
345     print start_form {-method => 'post',
346                 -action   => 'javascript://',
347                 -name     => 'address',
348                 -onsubmit => 'checkaddress(this);'};
349     print 'Check Email Address',
350       textfield {-class     => 'searchfield',
351                  -id        => 'searchfield',
352                  -name      => 'email',
353                  -size      => 20,
354                  -maxlength => 255,
355                  -value     => '',
356                  -onclick   => "document.address.email.value = '';"};
357     print p "";
358     print end_form;
359     print end_div;
360   } # if
361
362   print end_div;
363
364   return;
365 } # NavigationBar
366
367 1;