Initial checkin
[ndccode.git] / stats / foreverstats3.pl
1 #!/usr/bin/perl -w
2
3 # foreverstats3.pl
4 # NDC Code Release 1
5 #
6 # Connects to the database holding the statistic data. Builds a
7 # web page based on a template file.
8 # This script has limited functionality compared to foreverstats2,
9 # bus has _much_ cleaner code.
10 #
11 #   Copyright (C) 2001 Andreas Ulbrich, Ralf Ertzinger (ndccode@ndc.sh)
12 #
13 #   This program is free software; you can redistribute it and/or modify
14 #   it under the terms of the GNU General Public License as published by
15 #   the Free Software Foundation; either version 2 of the License, or
16 #   (at your option) any later version.
17 #
18 #   This program is distributed in the hope that it will be useful,
19 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
20 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 #   GNU General Public License for more details.
22 #
23 #   You should have received a copy of the GNU General Public License
24 #   along with this program; if not, write to the Free Software
25 #   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
27 use strict;
28 use CGI;
29 use CGI::Debug (report => 'everything', on => 'warnings');
30 use DBI;
31
32 # Define some variables
33 my $template_path = "templates";
34 my $scriptpath = "http://www.ndc.sh/cgi-bin/quake/foreverstats3.pl";
35 my $template_file;
36 my @main_source;
37 my %variables;
38 my @playerdata;
39
40 my $CGI_query;
41
42 # Info about the script
43 $variables{parser_selfinfo} =   "<!--\nThis is the [NDC] foreverstats script, Release 3.0.\n" .
44                                 "Featuring support for selectable viewlimits and player highlighting.\n" .
45                                 "Parsing-Engine: Lilith, Version 1.1.\n" .
46                                 "Output is HTML 4.01 strict compliant.\n\n".
47                                 "Original Release by [NDC]Maria.\n" .
48                                 "Rewrite by [NDC]Sundancer.\n" .
49                                 "Lilith by [NDC]Sundancer.\n" .
50                                 "Source code is available. Contact ndccode\@ndc.sh or see http://www.ndc.sh/ndccode.\n" .
51                                 "//-->";
52 $variables{scriptpath} = $ENV{REQUEST_URI};
53
54 sub parse {
55
56         # This is Lilith. Takes an array on input, and parses it line by line,
57         # printing the result to STDOUT.
58
59         # Variables
60         my $template_line;
61         my @parser_comment;
62         my @looparray;
63         my $comment;
64         my $fullcomment;
65         my $replacement;
66         my $loop_variable;
67         my $in_loop_players = 0;
68
69         LOOP: while ($template_line = shift) {
70
71                 if ($template_line =~ /^\s*\<!--loop [\w_]+--\>/) {
72                         ($loop_variable) = ($template_line =~ /<!--loop ([\w_]+)--\>/);
73                         if ($loop_variable eq "players") {
74                                 $in_loop_players = 1;
75                         }
76                         next LOOP;
77                 }
78
79                 if ($template_line =~ /^\s*\<!--endloop [\w_]+--\>/) {
80                         ($loop_variable) = ($template_line =~ /<!--endloop ([\w_]+)--\>/);
81                         if ($loop_variable eq "players") {
82                                 $in_loop_players = 0;
83
84                                 # Unroll the loop.
85                                 for (my $i=0;$i<scalar(@playerdata);$i++) {
86                                         $variables{'parser_playerrank'} = $i+1;
87                                         $variables{'parser_playername'} = make_compatible(@{$playerdata[$i]}->[0]);
88                                         $variables{'parser_playerskill'} = @{$playerdata[$i]}->[1];
89                                         $variables{'parser_playerfph'} = @{$playerdata[$i]}->[2];
90                                         $variables{'parser_playermapsplayed'} = @{$playerdata[$i]}->[3];
91                                         $variables{'parser_playermapswon'} = @{$playerdata[$i]}->[4];
92                                         $variables{'parser_playerkills'} = @{$playerdata[$i]}->[5];
93                                         $variables{'parser_playervictims'} = @{$playerdata[$i]}->[6];
94                                         $variables{'parser_playersuicides'} = @{$playerdata[$i]}->[7];
95                                         $variables{'parser_playertime'} = @{$playerdata[$i]}->[8];
96                                         $variables{'parser_playerlastseen'} = @{$playerdata[$i]}->[9];
97                                         parse(@looparray);
98                                 }
99                         }
100                         next LOOP;
101                 }
102
103                 # If we are in loopmode, copy lines into an array for later parsing.
104                 if ($in_loop_players == 1) {
105                         push @looparray, $template_line;
106                         next LOOP;
107                 }
108
109                 @parser_comment = ($template_line =~ /\<!--\$([\w_]+)--\>/g);
110                 foreach $comment ( @parser_comment) {
111                         if(defined($variables{$comment})) {
112                                 $fullcomment = "\\<!--\\\$" . $comment . "--\\>";
113                                 $replacement = $variables{$comment};
114                                 $template_line =~ s/$fullcomment/$replacement/g;
115                         }
116                 }
117                 print $template_line;
118         }
119 }
120                 
121 sub main {
122
123         # Main routine.
124
125         my $template;
126
127         $CGI_query = new CGI;
128         $template = ($CGI_query->param('template')?$CGI_query->param('template'):'/foreverstatsstrict.template');
129         $template_file = $template_path;
130         if ($template =~ /\W/) {
131                 # template file name contains illegal characters
132                 $template_file .= "/forerverstatsstrict.template";
133         } else {
134                 $template_file .= $template . ".template";
135         }
136
137         if ( ! -e $template_file) {
138                 $template_file = $template_path . "/foreverstatsstrict.template";
139         }
140
141         # Read the contents of the templatefile
142         open(TEMPLATE, $template_file) or die "Could not open template file: $!\n";
143         @main_source = <TEMPLATE>;
144         close(TEMPLATE);
145         GetPlayerData();
146         print "Content-Type: text/html\n\n";
147         parse(@main_source);
148 }
149
150 sub buildsqlquery {
151
152         # Evaluates the parameters and constructs a SQL-query.
153
154         my $operator;
155         my $field;
156         my $value;
157         my $sql_query;
158
159         my %operatormapping = ( 'mehrgleich' => '>=',
160                                 'wenigergleich' => '<=',
161                                 'gleich' => '=',
162                                 'mehr' => '>',
163                                 'weniger' => '<' );
164
165         my %fieldmapping = (    'Mapsplayed' => 'fe_MapsPlayed',
166                                 'Mapswon' => 'fe_MapsWon',
167                                 'Kills' => 'fe_Kills',
168                                 'Victims' => 'fe_Victims',
169                                 'Suicides' => 'fe_Suicides' );
170
171         $operator = ($CGI_query->param('sel_operator')?$CGI_query->param('sel_operator'):'mehrgleich');
172         $field = ($CGI_query->param('sel_field')?$CGI_query->param('sel_field'):'50');
173         $value = ($CGI_query->param('sel_number')?$CGI_query->param('sel_number'):'mehrgleich');
174
175         if(defined($operatormapping{$operator})) {
176                 $operator = $operatormapping{$operator};
177         } else {
178                 $operator = $operatormapping{'mehrgleich'};
179         }
180
181         if(defined($fieldmapping{$field})) {
182                 $field = $fieldmapping{$field};
183         } else {
184                 $field = $fieldmapping{'Mapsplayed'};
185         }
186
187         unless($value=~/\d+/) {
188                 $value = 50;
189         }
190
191         # Build the Query. Hiho.
192         $sql_query = 'SELECT nick, fe_skill, fe_fph, fe_mapsplayed, fe_mapswon, fe_kills, fe_victims, fe_suicides, fe_time, date_format(LastSeen, \'%d.%m.%Y\') as date_europe FROM PlayerStats WHERE (' . $field . $operator . $value . ') ORDER BY fe_skill DESC LIMIT 20';
193
194         return $sql_query;
195 }
196
197 sub GetPlayerData {
198
199         # Get the players from the database.
200
201         my $sql_handle;
202         my $sql_query;
203         my $sql_querystring;
204         my @row;
205         my $i=0;
206
207         my $sql_user = "";
208         my $sql_pass = "";
209
210         $sql_handle = DBI->connect("DBI:mysql:NDC",$sql_user,$sql_pass) or die;
211         $sql_querystring = buildsqlquery();
212         $sql_query = $sql_handle->prepare($sql_querystring);
213         $sql_query->execute or die;
214
215         while (@row = $sql_query->fetchrow_array) {
216                 $playerdata[$i++] = [ @row ];
217         }
218         $sql_query->finish;
219         $sql_handle->disconnect;
220 }
221
222 sub make_compatible {
223
224         # Takes a string. Converts all suspicious characters into HTML.
225         
226         my $input;
227
228         $input = shift;
229         $input =~ s/&/&amp;/g;
230         $input =~ s/\x1c/&middot;/g;
231         $input =~ s/</&lt;/g;
232         $input =~ s/>/&gt;/g;
233         $input =~ s/"/&quot;/g;
234         return $input;
235 }
236
237
238 # This is the main program.
239
240 main();