]> git.sesse.net Git - wloh/blobdiff - www/rating.pl
Increase the expiry time for the ratings page, and rely on clearing it explicitly...
[wloh] / www / rating.pl
index fe97fd631908d86760713ea46b4d51e7d8965b79..557231538514e8743bf8463418e1d10aea5b7a15 100755 (executable)
@@ -10,7 +10,9 @@ use POSIX;
 use HTML::Entities;
 use utf8;
 use locale;
-require '../config.pm';
+use lib qw(../include);
+require 'config.pm';
+require 'common.pm';
 
 my $dbh = DBI->connect($config::local_connstr, $config::local_username, $config::local_password)
        or die "connect: " . $DBI::errstr;
@@ -19,127 +21,91 @@ $dbh->{RaiseError} = 1;
 
 binmode STDOUT, ':utf8';
 
-# Find auxillary parameters.
-my %params = ();
-my $q = $dbh->prepare('SELECT * FROM ratings WHERE id < 0');
-$q->execute;
+my $cgi = CGI->new;
+my $locale = wloh_common::get_locale($cgi);
+
+my $aux_parms = wloh_common::get_auxillary_parameters($dbh, $locale);
+
+wloh_common::set_locale($locale);
+
+my $season = wloh_common::get_max_season($dbh, $locale);
+
+# Pick up all the subdivisions' ratings.
+my %subdivision_ratings = ();
+my $q = $dbh->prepare('SELECT divisjon, avdeling, serie_id, AVG(rating) AS avg_rating FROM ratings NATURAL JOIN siste_divisjon NATURAL JOIN spiller_kultur WHERE kultur=? AND sesong=? GROUP BY divisjon, avdeling, serie_id ORDER BY divisjon, avdeling');
+$q->execute($locale, $season);
+
 while (my $ref = $q->fetchrow_hashref) {
-       $params{$ref->{'id'}} = $ref->{'rating'};
+       my $division = $ref->{'divisjon'};
+       my $rating = $ref->{'avg_rating'};
+       my $id = $ref->{'serie_id'};
+
+       push @{$subdivision_ratings{$division}}, [ $id, $rating ];
 }
-my $match_stddev = $params{-2} * sqrt(2.0);
-
-print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+5m');
-POSIX::setlocale(&POSIX::LC_ALL, 'nb_NO.UTF-8');
-
-printf <<"EOF", $params{-3}, $match_stddev;
-<html>
-  <head>
-    <title>WLoH-rating</title>
-    <link rel="stylesheet" href="/style" type="text/css" />
-  </head>
-  <body>
-    <h1>WLoH-rating</h1>
-
-    <p><em>Dette er et hobbyprosjekt fra tredjepart, og ikke en offisiell del av
-      <a href="http://wordfeud.aasmul.net/">Wordfeud Leage of Honour</a>.</em></p>
-
-    <p>Ratingen er dog basert på spilledata fra WLoH (takk til Lobotommy
-      for tilgang!), og oppdateres
-      hver hele time. Den er fullstendig uoffisiell, og har ingen innflytelse
-      på WLoH, men brukes for å estimere vinnersannsynligheter i
-      <a href="/">sannsynlighetsberegningen</a>.</p>
-
-    <p>Vær obs på at det
-      er betydelig usikkerhetsmargin, spesielt for spillere som ikke
-      har spilt spesielt mange kamper.</p>
-
-    <p>Modellen kan endre seg når som helst når jeg føler for det :-)
-      Ikke ta ratingen alt for alvorlig, selv om den er basert på
-      relativt fornuftige matematiske modeller. Husk at all statistikk
-      sier mer om fortiden enn om framtiden.</p>
-
-    <h2>Modellparametre</h2>
-
-    <p>For de som vet litt om slikt. Mer utførlig forklaring for begynnere kommer seinere.</p>
-
-    <ul>
-      <li>MLE-basert modell med én skalar (styrke) per spiller og to globale skalarer (begge standardavvik, se under), løst med syklisk MM (minorization-maximization). Antall iterasjoner før konvergens: $params{-1}.</li>
-      <li>Rimelighetfunksjon, prior: Normalfordeling med µ=1500, &sigma;=%.1f (est.)</li>
-      <li>Rimelighetfunksjon, per kamp: Normalfordeling med µ=(score1 - score2), &sigma;=%.1f (est.)</li>
-      <li>Vekting: Inneværende sesong samt de tre siste vektes fullt ut
-       (likt med prior). Deretter eksponentielt synkende vekting, med
-        halveringstid på tre sesonger. Spill som er registrert med
-        150-0, 0-150 eller 150-150 ignoreres.</li>
-    </ul>
-
-    <h2>Divisjonsoversikt</h2>
-
-    <table>
-      <tr>
-        <th>Div.</th>
-        <th>Snitt</th>
-        <th>Std.avvik</th>
-      </tr>
-EOF
-
-$q = $dbh->prepare('SELECT divisjon,AVG(rating) AS avg_rating,STDDEV(rating) AS stddev_rating FROM ratings NATURAL JOIN siste_divisjon GROUP BY divisjon ORDER BY divisjon');
-$q->execute;
+
+$q = $dbh->prepare('SELECT divisjon,AVG(rating) AS avg_rating,STDDEV(rating) AS stddev_rating FROM ratings NATURAL JOIN siste_divisjon NATURAL JOIN spiller_kultur WHERE kultur=? AND sesong=? GROUP BY divisjon ORDER BY divisjon');
+$q->execute($locale, $season);
+
+my @divisions = ();
 
 my $i = 0;
 while (my $ref = $q->fetchrow_hashref) {
-       if (++$i % 2 == 0) {
-               print "      <tr class=\"odd\">\n";
-       } else {
-               print "      <tr class=\"even\">\n";
+       my %division = ();
+
+       $division{'#rank'} = wloh_common::get_ordinal($ref->{'divisjon'}, $locale);
+       $division{'#average'} = sprintf "%.1f", $ref->{'avg_rating'};
+       $division{'#stddev'} = sprintf "%.1f", $ref->{'stddev_rating'};
+
+       my @subdivisions = ();
+       for my $arr (@{$subdivision_ratings{$ref->{'divisjon'}}}) {
+               my ($id, $rating) = @$arr;
+               push @subdivisions, {
+                       '#divlink' => sprintf("%.1f", $rating),
+                       '#divlink/href' => sprintf("http://wordfeud.aasmul.net/serie-%d", $id)
+               };
        }
-       printf "        <th>%d.</th>\n", $ref->{'divisjon'};
-       printf "        <td class=\"num\">%.1f</td>\n", $ref->{'avg_rating'};
-       printf "        <td class=\"num\">%.1f</td>\n", $ref->{'stddev_rating'};
-       print "      </tr>\n";
-}
-
-print <<"EOF";
-    </table>
 
-  <h2>Rankingliste</h2>
+       $division{'subdivisions'} = \@subdivisions;
 
-  <table>
-    <tr>
-      <th></th>
-      <th>Nick</th>
-      <th>Rating</th>
-      <th>Sist sett</th>
-    </tr>
-EOF
+       push @divisions, \%division;
+}
 
 $q = $dbh->prepare('
 SELECT *
 FROM ratings
   NATURAL JOIN kanonisk_navn
   NATURAL JOIN siste_divisjon
+  NATURAL JOIN spiller_kultur
+WHERE kultur=?
 ORDER BY rating DESC');
-$q->execute;
+$q->execute($locale);
+
+my @players = ();
 
 $i = 0;
 while (my $ref = $q->fetchrow_hashref) {
-       if (++$i % 2 == 0) {
-               print "    <tr class=\"odd\">\n";
-       } else {
-               print "    <tr class=\"even\">\n";
-       }
-       printf "      <th>%d.</th>\n", $i;
-       printf "      <td><a href=\"http://wordfeud.aasmul.net/bruker-%d\">%s</a></td>\n", $ref->{'id'}, HTML::Entities::encode_entities(Encode::decode_utf8($ref->{'navn'}));
-       printf "      <td class=\"num\">%.1f</td>\n", $ref->{'rating'};
-       printf "      <td><a href=\"http://wordfeud.aasmul.net/serie-%d\">%s</a></td>\n", $ref->{'serie_id'}, $ref->{'serie_navn'};
-       print "    </tr>\n";
-}
+       my %player = ();
 
-print <<"EOF";
-    </table>
-  </body>
-</html>
-EOF
+       $player{'#rank'} = wloh_common::get_ordinal(++$i, $locale);
+       $player{'#user'} = Encode::decode_utf8($ref->{'navn'});
+       $player{'#user/href'} = sprintf "http://wordfeud.aasmul.net/bruker-%d", $ref->{'id'};
+       $player{'#rating'} = sprintf "%.1f", $ref->{'rating'};
+       $player{'#stddev'} = sprintf "%.1f", $ref->{'rating_stddev'};
+       $player{'#divlink'} = $ref->{'serie_navn'};
+       $player{'#divlink/href'} = sprintf "http://wordfeud.aasmul.net/serie-%d", $ref->{'serie_id'};
+
+       push @players, \%player;
+}
 
-$match_stddev = $params{-2} * sqrt(2.0);
+print CGI->header(-type=>'text/html; charset=utf-8', -expires=>'+75m');
+wloh_common::process_template('rating', $locale, {
+       '#navbar' => wloh_common::get_navbar($cgi, $dbh, $locale),
+       'iterations' => $aux_parms->{'num_iterations'},
+       'rating-prior-stddev' => sprintf("%.1f", $aux_parms->{'rating_prior_stddev'}),
+       'match-stddev' => sprintf("%.1f", $aux_parms->{'score_stddev'} * sqrt(2.0)),
+       '#divisions' => XML::Template::alternate('tr/class', \@divisions, 'even', 'odd'),
+       '#players' => XML::Template::alternate('tr/class', \@players, 'even', 'odd'),
+       'last-sync' => wloh_common::get_last_sync($dbh)
+});
 
 $dbh->rollback;