refactorization to manage old rules with a separated class
[brisk.git] / web / briskin5 / stat-day.php
1 <?php
2 /*
3  *  brisk - stat-day.php
4  *
5  *  Copyright (C) 2009-2012 Matteo Nastasi
6  *                          mailto: nastasi@alternativeoutput.it
7  *                                  matteo.nastasi@milug.org
8  *                          web: http://www.alternativeoutput.it
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details. You should have received a
19  * copy of the GNU General Public License along with this program; if
20  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
21  * Suite 330, Boston, MA 02111-1307, USA.
22  *
23  */
24
25 /*
26   call example:
27 wget -O daily.txt dodo.birds.van/brisk/briskin5/stat-day.php?pazz=yourpasswd&from=1000&to=1380308086
28
29 now="$(date +%s)"
30
31 # from 100 days ago to 1 day after
32 to="$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$(date +%s) + 86400" | bc))"
33 from="$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$(date +%s) - 8640000" | bc))"
34 # to="$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$now + 7200 " | bc))"
35 # from="$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$now - 9200 " | bc))"
36
37 curl -d "pazz=$BRISK_PASS" "http://$BRISK_SITE/briskin5/stat-day.php?from=$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$(date +%s) - 8640000" | bc))&to=$(date +"%Y-%m-%d+%H:%M:%S" -d @$(echo "$(date +%s) + 86400" | bc))"
38
39 */
40
41 $G_base = "../";
42
43 // SYNC WITH bin5_tournaments table
44 $mlang_stat_day = array(
45                          'old rules: with draw'=> array( 'it' => 'Partite vecchie (con il pareggio)',
46                                                          'en' => 'Old matches (with draw)' ),
47
48                          'new rules: without draw' => array( 'it' => 'Partite nuove (senza pareggio)',
49                                                              'en' => 'New matches (without draw)'),
50
51                          'special match' => array( 'it' => 'Partite speciali',
52                                                    'en' => 'Special matches'),
53
54                          'info_total'=> array( 'it' => 'totali',
55                                                'en' => 'En totali')
56                          );
57
58
59 ini_set("max_execution_time",  "240");
60
61 require_once("../Obj/brisk.phh");
62 require_once("../Obj/user.phh");
63 require_once("../Obj/auth.phh");
64 require_once("../Obj/dbase_${G_dbasetype}.phh");
65 require_once("Obj/briskin5.phh");
66 require_once("Obj/placing.phh");
67
68 function main_file($curtime)
69 {
70     GLOBAL $G_lang, $G_alarm_passwd;
71   $tri = array();
72   $mon = array();
73   $wee = array();
74
75   if (($fp = @fopen(LEGAL_PATH."/points.log", 'r')) == FALSE) {
76     echo "Open data file error";
77     exit;
78   }
79   echo "prima<br>";
80
81   if (($fp_start = @fopen(LEGAL_PATH."/points.start", 'r')) != FALSE) {
82     $skip = intval(fgets($fp_start));
83     if ($skip > 0)
84       fseek($fp, $skip, SEEK_SET);
85     fclose($fp_start);
86   }
87
88   if (($bdb = BriskDB::create()) == FALSE) {
89     echo "database connection failed";
90     exit;
91   }
92
93   $bdb->users_load();
94
95   for ($i = 0 ; $i < $bdb->count() ; $i++) {
96     $login = $bdb->getlogin_byidx($i);
97     $tri[$i] = new Ptsgam($login);
98     $mon[$i] = new Ptsgam($login);
99     $wee[$i] = new Ptsgam($login);
100   }
101
102   // recalculate all the placings
103   // 1246428948|492e4e9e856b0|N|tre|172.22.1.90|STAT:BRISKIN5:FINISH_GAME|4a4afd4983039|6|3|tre|1|due|2|uno|-1|
104   while (!feof($fp)) {
105     $p = 0;
106     $bf = fgets($fp, 4096);
107     $ar = csplitter($bf, '|');
108     // if not auth table, continue
109     if (count($ar) < 15)
110       continue;
111
112     // echo $p++."<br>";
113     if ($ar[7] >= TABLES_AUTH_N)
114       continue;
115     // echo $p++." ".$ar[5]."<br>";
116     // if not FINISH_GAME line, continue
117     if ($ar[5] != "STAT:BRISKIN5:FINISH_GAME")
118       continue;
119     // echo $p++."<br>";
120     // if to much old points, continue
121     if ($ar[0] < $curtime - TRI_LIMIT) {
122       if (($fp_start = @fopen(LEGAL_PATH."/points.start", 'w')) != FALSE) {
123         $curpos = ftell($fp);
124         fwrite($fp_start, sprintf("%d\n", $curpos));
125         fclose($fp_start);
126       }
127
128       continue;
129     }
130     // echo $p++." ".BIN5_PLAYERS_N."<br>";
131
132     $found = FALSE;
133     $mult = 1;
134     for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
135       for ($e = $i + 1 ; $e < BIN5_PLAYERS_N ; $e++) {
136         if ($ar[10+($i*2)] == $ar[10+($e*2)]) {
137           $mult = abs($ar[10+($i*2)]);
138           $found = TRUE;
139         }
140       }
141       if ($found)
142         break;
143     }
144
145     if ($mult == 0)
146        continue;
147     for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
148       // echo $p." i) ".$i."<br>";
149       $username = $ar[9+($i*2)];
150       if (($item = $bdb->getitem_bylogin($username, &$id)) == FALSE) {
151         echo "WARNING: the user [".$username."] NOT EXISTS!<br>";
152         continue;
153       }
154
155       // echo $item->login." id)".$id."  ".$ar[10+($i*2)]." mult: ".$mult."<br>";
156       $tri[$id]->add($ar[10+($i*2)] / $mult);
157       if ($ar[0] >= $curtime - MON_LIMIT)
158         $mon[$id]->add($ar[10+($i*2)] / $mult);
159       if ($ar[0] >= $curtime - WEE_LIMIT)
160         $wee[$id]->add($ar[10+($i*2)] / $mult);
161     }
162     // $p++; echo $p++."<br>";
163   }
164   fclose($fp);
165
166   usort($tri, ptsgam_cmp);
167   usort($mon, ptsgam_cmp);
168   usort($wee, ptsgam_cmp);
169
170   echo "<br><br>TRI<br>\n";
171
172   if (($fplo = @fopen(LEGAL_PATH."/class_tri_lo.log", 'w')) == FALSE) {
173     echo "Open tri_lo failed<br>";
174     exit;
175   }
176   if (($fphi = @fopen(LEGAL_PATH."/class_tri_hi.log", 'w')) == FALSE) {
177     echo "Open tri_hi failed<br>";
178     exit;
179   }
180
181   for ($i = 0 ; $i < count($tri) ; $i++) {
182     if ($tri[$i]->gam == 0.0)
183       continue;
184     printf("%s: %s (%d) <br>\n",  $tri[$i]->username,  $tri[$i]->snormpts(), $tri[$i]->gam);
185     if ($tri[$i]->gam >= TRI_MAX_GAMES)
186       fwrite($fphi, sprintf("%s|%d|%d|\n", xcapelt($tri[$i]->username), $tri[$i]->pts, $tri[$i]->gam));
187     else if ($tri[$i]->gam > TRI_MIN_GAMES)
188       fwrite($fplo, sprintf("%s|%d|%d|\n", xcapelt($tri[$i]->username), $tri[$i]->pts, $tri[$i]->gam));
189   }
190   fclose($fphi);
191   fclose($fplo);
192
193   echo "<br><br>MON<br>\n";
194
195   if (($fplo = @fopen(LEGAL_PATH."/class_mon_lo.log", 'w')) == FALSE) {
196     echo "Open tri_lo failed<br>";
197     exit;
198   }
199   if (($fphi = @fopen(LEGAL_PATH."/class_mon_hi.log", 'w')) == FALSE) {
200     echo "Open tri_hi failed<br>";
201     exit;
202   }
203
204   for ($i = 0 ; $i < count($mon) ; $i++) {
205     if ($mon[$i]->gam == 0.0)
206       continue;
207     printf("%s: %s (%d) <br>\n",  $mon[$i]->username,  $mon[$i]->snormpts(), $mon[$i]->gam);
208     if ($mon[$i]->gam >= MON_MAX_GAMES)
209       fwrite($fphi, sprintf("%s|%d|%d|\n", xcapelt($mon[$i]->username), $mon[$i]->pts, $mon[$i]->gam));
210     else if ($mon[$i]->gam > MON_MIN_GAMES)
211       fwrite($fplo, sprintf("%s|%d|%d|\n", xcapelt($mon[$i]->username), $mon[$i]->pts, $mon[$i]->gam));
212   }
213   fclose($fphi);
214   fclose($fplo);
215
216   echo "<br><br>WEE<br>\n";
217   if (($fplo = @fopen(LEGAL_PATH."/class_wee_lo.log", 'w')) == FALSE) {
218     echo "Open wee_lo failed<br>";
219     exit;
220   }
221   if (($fphi = @fopen(LEGAL_PATH."/class_wee_hi.log", 'w')) == FALSE) {
222     echo "Open wee_hi failed<br>";
223     exit;
224   }
225
226   for ($i = 0 ; $i < count($wee) ; $i++) {
227     if ($wee[$i]->gam == 0.0)
228       continue;
229     printf("%s: %s (%d) <br>\n",  $wee[$i]->username,  $wee[$i]->snormpts(), $wee[$i]->gam);
230     if ($wee[$i]->gam >= WEE_MAX_GAMES)
231       fwrite($fphi, sprintf("%s|%d|%d|\n", xcapelt($wee[$i]->username), $wee[$i]->pts, $wee[$i]->gam));
232     else if ($wee[$i]->gam > WEE_MIN_GAMES)
233       fwrite($fplo, sprintf("%s|%d|%d|\n", xcapelt($wee[$i]->username), $wee[$i]->pts, $wee[$i]->gam));
234   }
235   fclose($fphi);
236   fclose($fplo);
237
238 }
239
240 function main_pgsql($from, $to)
241 {
242     GLOBAL $G_lang, $G_dbpfx, $mlang_stat_day;
243
244     $ret = FALSE;
245     $fpexp = FALSE;
246
247     // log_crit("stat-day: BEGIN");
248     do {
249         if (($fpexp = @fopen(LEGAL_PATH."/explain.log", 'w')) == FALSE) {
250             log_crit("stat-day: open explain failed");
251             break;
252         }
253         fprintf($fpexp, "<h2>Minuta delle partite dal (%s) al (%s)</h2>",
254                 $from, $to);
255
256         if (($bdb = BriskDB::create()) == FALSE) {
257             log_crit("stat-day: database connection failed");
258             break;
259         }
260
261         if (pg_query($bdb->dbconn->db(), "BEGIN") == FALSE) {
262             log_crit("stat-day: begin failed");
263             break;
264         }
265
266         // retrieve list of active tournaments
267         $trn_sql = sprintf("SELECT * FROM %sbin5_tournaments WHERE active = 1;", $G_dbpfx);
268         if (($trn_pg = pg_query($bdb->dbconn->db(), $trn_sql)) == FALSE) {
269             log_crit("stat-day: select from tournaments failed");
270             break;
271         }
272
273         $trn_n = pg_numrows($trn_pg);
274         printf("Number of tournaments: %d\n", $trn_n);
275
276         // loop on tournaments
277         for ($t = 0 ; $t < $trn_n ; $t++) {
278             // log_crit("stat-day: LOOP t");
279             $trn_obj = pg_fetch_object($trn_pg, $t);
280
281             $tmt_sql = sprintf("
282 SELECT m.code AS code, m.mazzo_next as minus_one_is_old
283     FROM %sbin5_matches AS m, %sbin5_games AS g, %sbin5_tournaments as t
284     WHERE t.code = m.tcode AND m.code = g.mcode
285         AND t.code = %d AND g.tstamp >= '%s' AND g.tstamp < '%s'
286     GROUP BY m.code, minus_one_is_old
287     ORDER BY m.code, minus_one_is_old DESC;",
288                                $G_dbpfx, $G_dbpfx, $G_dbpfx, $trn_obj->code, $from, $to);
289
290             // if deletable old matches exists then ...
291             if (($tmt_pg = pg_query($bdb->dbconn->db(), $tmt_sql)) == FALSE) {
292                 log_crit("stat-day: select from matches failed");
293                 break;
294             }
295
296             //
297             // store matches before clean them
298             //
299             $tmt_n = pg_numrows($tmt_pg);
300             // get matches
301             if ($tmt_n == 0)
302                 continue;
303
304             if (!isset($mlang_stat_day[$trn_obj->name][$G_lang])) {
305                 log_crit("stat-day: tournament name not found in array");
306                 break;
307             }
308             printf("[Tournament [%s]], number of matches: %d\n", $mlang_stat_day[$trn_obj->name][$G_lang], $tmt_n);
309             fprintf($fpexp, "<h3>%s</h3>", $mlang_stat_day[$trn_obj->name][$G_lang]);
310
311             // loop on matches
312             for ($m = 0 ; $m < $tmt_n ; $m++) {
313                 // log_crit("stat-day: LOOP m");
314                 fprintf($fpexp, "<br>");
315                 $tmt_obj = pg_fetch_object($tmt_pg, $m);
316
317                 // get users for the match m
318                 if (($users = $bdb->users_get($tmt_obj->code, TRUE, ($tmt_obj->minus_one_is_old > -1))) == FALSE) {
319                     log_crit(sprintf("stat_day: users_get failed %d", $tmt_obj->code));
320                     break;
321                 }
322
323                 $gam_sql = sprintf("
324 SELECT g.* FROM %sbin5_tournaments AS t, %sbin5_matches AS m, %sbin5_games AS g
325     WHERE t.code = m.tcode AND m.code = g.mcode AND m.code = %d
326     ORDER BY g.tstamp;",
327                                    $G_dbpfx, $G_dbpfx, $G_dbpfx, $tmt_obj->code);
328                 if (($gam_pg = pg_query($bdb->dbconn->db(), $gam_sql)) == FALSE ) {
329                     log_crit("stat-day: gam_sql failed");
330                     break;
331                 }
332
333                 // loop on users of the match m
334                 for ($u = 0 ; $u < count($users) ; $u++) {
335                     // log_crit("stat-day: LOOP u");
336                     if ($u == 0) {
337                         fprintf($fpexp, "<h3>Codice: %d (%s - %s), Tavolo: %s</h3>\n", $tmt_obj->code, $users[$u]['first'], $users[$u]['last'], $users[$u]['tidx']);
338                         fprintf($fpexp, "<table align='center' class='placing'><tr>\n");
339                     }
340                     fprintf($fpexp, "<th>%s</th>", $users[$u]['login']);
341                     // note: we are looping on users, order on them not needed
342                     $pts_sql = sprintf("
343 SELECT p.pts AS pts
344     FROM %sbin5_games AS g, %sbin5_points AS p
345     WHERE g.code = p.gcode AND g.mcode = %d AND p.ucode = %d
346     ORDER BY g.tstamp",
347                                        $G_dbpfx, $G_dbpfx,
348                                        $tmt_obj->code, $users[$u]['code']);
349
350                     // points of the match for each user
351                     if (($pts_pg[$u] = pg_query($bdb->dbconn->db(), $pts_sql)) == FALSE) {
352                         log_crit("stat-day: pts_sql failed");
353                         break;
354                     }
355                     if ($u == 0) {
356                         $num_games = pg_numrows($pts_pg[$u]);
357                     }
358                     else {
359                         if ($num_games != pg_numrows($pts_pg[$u])) {
360                             log_crit("stat-day: num_games != pg_numrows");
361                             break;
362                         }
363                     }
364                 }
365                 if ($u != BIN5_PLAYERS_N) {
366                     log_crit("stat-day: u != BIN5_PLAYERS_N");
367                     break;
368                 }
369
370                 if ($tmt_obj->minus_one_is_old != -1) {
371                     fprintf($fpexp, "<th>mazzo</th><th>descrizione</th></tr>\n");
372                 }
373                 // LISTA DELLE VARIE PARTITE
374                 $pts_obj = array();
375                 for ($g = 0 ; $g < $num_games ; $g++) {
376                     $gam_obj = pg_fetch_object($gam_pg, $g);
377                     fprintf($fpexp, "<tr>");
378                     $pt_min   = 1000;
379                     $pt_min_n = 0;
380                     $pt_max   = -1000;
381                     $pt_max_n = 0;
382                     for ($u = 0 ; $u < BIN5_PLAYERS_N ; $u++) {
383                         $pts_obj[$u] = pg_fetch_object($pts_pg[$u], $g);
384
385                         if ($pt_min > $pts_obj[$u]->pts) {
386                             $pt_min = $pts_obj[$u]->pts;
387                             $pt_min_n = 1;
388                         }
389                         else if ($pt_min == $pts_obj[$u]->pts) {
390                             $pt_min_n++;
391                         }
392
393                         if ($pt_max < $pts_obj[$u]->pts) {
394                             $pt_max = $pts_obj[$u]->pts;
395                             $pt_max_n = 1;
396                         }
397                         else if ($pt_max == $pts_obj[$u]->pts) {
398                             $pt_max_n++;
399                         }
400                     }
401                     if ($pt_min_n > 1) {
402                         $pt_min =  1000;
403                     }
404                     if ($pt_max_n > 1) {
405                         $pt_max = -1000;
406                     }
407
408                     /* cases:
409                        pts = 0       -> white
410                        pts == pt_min -> red
411                        pts == pt_max -> green
412                        pts < 0       -> light red
413                        pts > 0       -> light green
414                      */
415                     for ($u = 0 ; $u < BIN5_PLAYERS_N ; $u++) {
416                         $pts = $pts_obj[$u]->pts;
417
418                         if ($pts == 0)
419                             $cla_nam = 'bg_white';
420                         else if ($pts == $pt_min)
421                             $cla_nam = 'bg_red';
422                         else if ($pts == $pt_max)
423                             $cla_nam = 'bg_green';
424                         else if ($pts < 0)
425                             $cla_nam = 'bg_lired';
426                         else if ($pts > 0)
427                             $cla_nam = 'bg_ligre';
428
429                         fprintf($fpexp, "<%s class='%s'>%d</%s>",
430                                 ($tmt_obj->minus_one_is_old == -1 ? "td" : "th"),
431                                 $cla_nam,
432                                 pow(2,$gam_obj->mult) * $pts,
433                                 ($tmt_obj->minus_one_is_old == -1 ? "td" : "th"));
434                     }
435                     if ($tmt_obj->minus_one_is_old != -1) {
436                         // FIXME
437                         $rules_name = "Rules_old_rules";
438                         fprintf($fpexp, "<td>%s</td><td>%s</td>", $users[$gam_obj->mazzo]['login'],
439                                 xcape( ${rules_name}::game_description($gam_obj->act, 'plain', $gam_obj->mult,
440                                                         $gam_obj->asta_win,
441                                                         ($gam_obj->asta_win != -1 ?
442                                                          $users[$gam_obj->asta_win]['login'] : ""),
443                                                         $gam_obj->friend,
444                                                         ($gam_obj->friend != -1 ?
445                                                          $users[$gam_obj->friend]['login'] : ""),
446                                                         $gam_obj->pnt, $gam_obj->asta_pnt, $gam_obj->tourn_pts) )
447                                 );
448                     }
449                     fprintf($fpexp, "</tr>\n");
450                 }
451
452                 // LISTA DEI TOTALI
453                 fprintf($fpexp, "<tr>");
454                 for ($u = 0 ; $u < BIN5_PLAYERS_N ; $u++) {
455                     // NOTE: this part must be revisited when we move to multiple game rules
456                     //       probably removing the sum and adding another nested iteration on games.
457                     $tot_sql = sprintf("
458 SELECT sum(p.pts * (2^g.mult)) AS pts
459     FROM %sbin5_matches AS m, %sbin5_games AS g, %sbin5_points AS p, %susers AS u
460     WHERE m.code = g.mcode AND g.code = p.gcode AND u.code = p.ucode
461         AND ( (u.type & (CAST (X'00ff0000' as integer))) <> (CAST (X'00800000' as integer)) )
462         AND m.code = %d AND u.code = %d",
463                                        $G_dbpfx, $G_dbpfx, $G_dbpfx, $G_dbpfx,
464                                        $tmt_obj->code, $users[$u]['code']);
465                     if (($tot_pg  = pg_query($bdb->dbconn->db(), $tot_sql)) == FALSE ) {
466                         break;
467                     }
468                     $tot_obj = pg_fetch_object($tot_pg, 0);
469                     fprintf($fpexp, "<th>%d</th>", $tot_obj->pts);
470                 }
471                 if ($tmt_obj->minus_one_is_old != -1) {
472                     fprintf($fpexp, "<th colspan='2'>%s</th></tr>\n", $mlang_stat_day['info_total'][$G_lang]);
473                 }
474                 fprintf($fpexp, "</table>\n");
475             }
476             if ($m < $tmt_n) {
477                 log_crit("stat-day: m < tmt_n");
478                 break;
479             }
480         }
481         if ($t < $trn_n) {
482             log_crit(sprintf("stat-day: t < trn_n (%d, %d)", $t, $trn_n));
483             break;
484         }
485         $ret = (TRUE);
486     } while (0);
487
488     if ($ret == FALSE) {
489         pg_query($bdb->dbconn->db(), "ROLLBACK");
490     }
491     if ($fpexp != FALSE) {
492         fclose($fpexp);
493     }
494
495     return ($ret);
496 }
497
498 function main()
499 {
500     GLOBAL $G_lang, $G_dbasetype, $G_alarm_passwd, $pazz, $from, $to;
501
502     if ($pazz != $G_alarm_passwd) {
503         echo "Wrong password<br>";
504         mop_flush();
505         exit;
506     }
507
508     $fun_name = "main_${G_dbasetype}";
509
510     if ($ret = $fun_name($from, $to))
511         echo "Success.<br>\n";
512     else
513         echo "Failed.<br>\n";
514
515     echo "Fine.\n";
516     mop_flush();
517 }
518
519 main();
520 ?>