aboutsummaryrefslogtreecommitdiffstats
path: root/toj/sqmod
diff options
context:
space:
mode:
Diffstat (limited to 'toj/sqmod')
-rwxr-xr-xtoj/sqmod/sqmod_test/sqmod_test.css97
-rwxr-xr-xtoj/sqmod/sqmod_test/sqmod_test.html33
-rw-r--r--toj/sqmod/sqmod_test/sqmod_test.inc.php149
-rwxr-xr-xtoj/sqmod/sqmod_test/sqmod_test.js259
-rwxr-xr-xtoj/sqmod/sqmod_test/sqmod_test.php84
-rw-r--r--toj/sqmod/sqmod_test/team.inc.php37
6 files changed, 659 insertions, 0 deletions
diff --git a/toj/sqmod/sqmod_test/sqmod_test.css b/toj/sqmod/sqmod_test/sqmod_test.css
new file mode 100755
index 0000000..52009d2
--- /dev/null
+++ b/toj/sqmod/sqmod_test/sqmod_test.css
@@ -0,0 +1,97 @@
+div.sqmod_test > div.pro_tab > table.prolist{
+ width:62%;
+ margin:0px 0px 6px 257px;
+ border-collapse:collapse;
+ text-align:left;
+}
+div.sqmod_test > div.pro_tab > table.prolist tr.head{
+ height:64px;
+ font-size:20px;
+}
+div.sqmod_test > div.pro_tab > table.prolist tr.item{
+ height:32px;
+ border-left:2px solid;
+ border-color:#1C1C1C;
+}
+div.sqmod_test > div.pro_tab > table.prolist tr:hover.item{
+ background-color:rgba(255,255,255,0.2);
+}
+div.sqmod_test > div.pro_tab > table.prolist th.no,div.sqmod_test > div.pro_tab > table.prolist td.no{
+ width:96px;
+ padding:0px 0px 0px 6px;
+}
+div.sqmod_test > div.pro_tab > table.prolist th.name,div.sqmod_test > div.pro_tab > table.prolist td.name{
+ width:auto;
+}
+div.sqmod_test > div.pro_tab > table.prolist th.bscore,div.sqmod_test > div.pro_tab > table.prolist td.bscore{
+ width:128px;
+}
+div.sqmod_test > div.pro_tab > table.prolist th.team,div.sqmod_test > div.pro_tab > table.prolist td.team{
+ width:64px;
+ display:none;
+}
+div.sqmod_test > div.pro_tab > table.prolist a.link{
+ color:#E9E9E9;
+ text-decoration:none;
+}
+div.sqmod_test > div.pro_tab > table.prolist a:hover.link{
+ color:#E0E0E0;
+ text-decoration:underline;
+}
+
+div.sqmod_test > div.pro_tab > table.stat{
+ margin:32px 0px 6px 256px;
+ border-collapse:collapse;
+ text-align:left;
+}
+div.sqmod_test > div.pro_tab > table.stat tr{
+ height:32px;
+}
+div.sqmod_test > div.pro_tab div.prog_box{
+ width:512px;
+ height:16px;
+ background-color:rgba(255,255,255,0.2);
+ color:#1C1C1C;
+ font-size:12px;
+ font-family:monospace;
+ line-height:16px;
+ text-align:right;
+ position:relative;
+}
+div.sqmod_test > div.pro_tab div.prog_box > div.pass{
+ width:0%;
+ height:16px;
+ border-right:rgba(0,255,0,0.8) 2px solid;
+ position:absolute;
+ top:0px;
+ left:0%;
+ overflow:hidden;
+}
+div.sqmod_test > div.pro_tab div.prog_box > div.good{
+ width:0%;
+ height:16px;
+ border-right:rgba(255,255,0,0.8) 2px solid;
+ position:absolute;
+ top:0px;
+ left:0%;
+ overflow:hidden;
+}
+div.sqmod_test > div.pro_tab div.prog_box > div.total{
+ width:0%;
+ height:16px;
+ border-right:rgba(255,255,255,0.8) 2px solid;
+ position:absolute;
+ top:0px;
+ left:0%;
+ overflow:hidden;
+}
+div.sqmod_test > div.pro_tab div.prog_box > div.prog{
+ width:0%;
+ height:16px;
+ background-color:rgba(0,0,0,0);
+ font-weight:bold;
+ position:absolute;
+ top:0px;
+ left:0px;
+ overflow:hidden;
+}
diff --git a/toj/sqmod/sqmod_test/sqmod_test.html b/toj/sqmod/sqmod_test/sqmod_test.html
new file mode 100755
index 0000000..9b93096
--- /dev/null
+++ b/toj/sqmod/sqmod_test/sqmod_test.html
@@ -0,0 +1,33 @@
+<div tab="pro" class="common_tab pro_tab">
+ <table class="prolist">
+ <tr class="head">
+ <th class="no">#</th>
+ <th class="name">題目名稱</th>
+ <th class="bscore">最佳分數</th>
+ <th class="team"><a class="link"></a></th>
+ <th class="team"><a class="link"></a></th>
+ <th class="team"><a class="link"></a></th>
+ <th class="team"><a class="link"></a></th>
+ </tr>
+ </table>
+ <table class="stat">
+ <tr class="user_prog">
+ <td style="width:105px;">個人進度</td>
+ <td><div class="prog_box user_prog">
+ <div class="pass"></div>
+ <div class="good"></div>
+ <div class="total"></div>
+ <div class="prog"></div>
+ </div></td>
+ </tr>
+ <tr class="team_prog" style="display:none;">
+ <td>小組進度</td>
+ <td><div class="prog_box team_prog">
+ <div class="pass"></div>
+ <div class="good"></div>
+ <div class="total"></div>
+ <div class="prog"></div>
+ </div></td>
+ </tr>
+ </table>
+</div>
diff --git a/toj/sqmod/sqmod_test/sqmod_test.inc.php b/toj/sqmod/sqmod_test/sqmod_test.inc.php
new file mode 100644
index 0000000..3e472e7
--- /dev/null
+++ b/toj/sqmod/sqmod_test/sqmod_test.inc.php
@@ -0,0 +1,149 @@
+<?php
+
+require_once('../../php/common.inc.php');
+require_once('../../php/square.inc.php');
+require_once('../../php/sqlib_scoreboard.inc.php');
+
+const SQMODNAME = 'sqmod_test';
+
+const SCOREBOARD_ID_PROBSTAT = 1;
+
+
+function get_pro_stat_uid($sqlc, $msqlc, $sqid, $sboard_id, $uid)
+{
+ //get user $uid solving status of square $sqid. $sboard_id can be set as a fixed value.
+ $sq = square::get($sqlc, $sqid);
+ if(!$sq)die('Eno_such_sq');
+
+ $data = sqlib_scoreboard::get_scoreboard_uid($sqlc, $msqlc, $sqid, $sboard_id, null, $sq->start_time, $sq->end_time, $uid);
+
+ return $data[0];
+}
+
+function process_pro_stat($obj)
+{
+ $ret = array();
+ foreach($obj->problem as $pro)
+ {
+ $ps = new stdClass();
+ $ps->proid = $pro->proid;
+ $ps->is_ac = $pro->is_ac;
+ $ps->best_score = $pro->best_score;
+ //$ps->rank_score = $pro->rank_score;
+ $ps->tried = ($pro->tries > 0);
+ //array_push($ret, $ps);
+ $ret[$pro->proid] = $ps;
+ }
+ return $ret;
+}
+
+function get_setting($sqid)
+{
+ $sqdir = '/srv/http/toj/center/sq/'.$sqid.'/';
+ $cont = file_get_contents($sqdir.'setting');
+ $data = json_decode($cont);
+ return $data;
+}
+
+function get_term($data, $sqid)
+{
+ return $data->term;
+}
+
+function calc_score($stat, $data, $sqid)
+{
+ $prolist = $data->pro;
+ $ret = array();
+ foreach($prolist as $pro)
+ {
+ $proid = $pro->proid;
+ $np = new stdClass();
+ if($stat)$np = clone $stat[$proid];
+ //else continue;
+ if(!$stat)
+ {
+ $np->proid = $proid;
+ $np->best_score = 0;
+ $np->tried = false;
+ $np->is_ac = false;
+ array_push($ret, $np);
+ continue;
+ }
+ $method = $pro->method;
+ //$np->full_score = $pro->score;
+ if($method == 'normal')
+ {
+ $np->best_score = $stat[$proid]->best_score / 100 * $pro->score;
+ }
+ if($method == 'max')
+ {
+ $score = 0;
+ $tis_ac = false;
+ foreach($pro->config as $conf)
+ {
+ //$np->best_score = json_encode($conf);
+ $nowscore = 0;
+ $is_ac = true;
+ foreach($conf as $unit)
+ {
+ $nowscore += $stat[$unit[0]]->best_score / 100 * $unit[1];
+ $np->tried = $np->tried || $stat[$unit[0]]->tried;
+ if(!$stat[$unit[0]]->is_ac)$is_ac = false;
+ }
+ $score = max($score, $nowscore);
+ if($is_ac)$tis_ac = true;
+ }
+ $np->is_ac = $tis_ac;
+ $np->best_score = $score;// / 100 * $pro->score;
+ }
+ //$np->best_score = json_encode($np);
+ array_push($ret, $np);
+ }
+ //$stat[0]->best_score = json_encode($ret[0]);
+ return $ret;
+}
+
+function process_pro_list($list, $data, $sqid)
+{
+ $prol = $data->pro;
+ $ret = array();
+ foreach($prol as $pro)
+ {
+ $proid = $pro->proid;
+ $np = null;
+ foreach($list as $op)
+ {
+ if($op->proid == $proid)
+ {
+ $np = clone $op;
+ break;
+ }
+ }
+ $np->prono = $pro->prono;
+ $np->full_score = $pro->score;
+ if($pro->proname)$np->proname = $pro->proname;
+ array_push($ret, $np);
+ }
+ return $ret;
+}
+
+function get_base_line($data, $sqid, $isteam)
+{
+ $ret = new stdClass();
+ if($isteam)
+ {
+ $ret->total_score = $data->total_score;
+ $ret->pass_score = $data->pass_score_team;
+ $ret->good_score = $data->good_score_team;
+ }
+ else
+ {
+ $ret->total_score = $data->total_score;
+ $ret->pass_score = $data->pass_score;
+ $ret->good_score = $data->good_score;
+ }
+
+ return $ret;
+}
+
+?>
diff --git a/toj/sqmod/sqmod_test/sqmod_test.js b/toj/sqmod/sqmod_test/sqmod_test.js
new file mode 100755
index 0000000..6d01881
--- /dev/null
+++ b/toj/sqmod/sqmod_test/sqmod_test.js
@@ -0,0 +1,259 @@
+var sqmod_test = {
+ init:function(that,j_page){
+ var pro_tab = new class_sqmod_test_pro_tab(that);
+
+ that.export_urlchange = function(direct){
+ var _in = function(){
+ that.fadein(j_page);
+
+ that.addtab('pro',pro_tab);
+ index.addtab('pro','/toj/sq/' + that.sqid + '/','題目');
+
+ _change();
+ };
+ var _out = function(){
+ that.fadeout(j_page);
+ index.emptytab();
+ that.tab_urlchange(null);
+ };
+ var _change = function(){
+ var tabname;
+
+ tabname = common.geturlpart()[2];
+ if(!(tabname in that.tab_list)){
+ tabname = 'pro';
+ common.replaceurl('/toj/sq/' + that.sqid + '/pro/');
+ }
+ that.tab_urlchange(tabname);
+ }
+
+ if(direct == 'in'){
+ _in();
+ }else if(direct == 'out'){
+ _out();
+ }else if(direct == 'same'){
+ _change();
+ }
+ }
+ }
+};
+
+var class_sqmod_test_pro_tab = function(paobj){
+ var that = this;
+ var j_tab = $('#index_page > [page="sq"] > [tab="pro"]');
+ var promap = null;
+
+ var pro_listset = function(j_item,proo){
+ var i;
+
+ var bscore;
+ var fscore;
+ var ratio;
+ var j_a;
+ var j_team;
+
+ if(proo != null){
+ j_item.attr('proid',proo.proid);
+
+ j_item.find('td.no').text(proo.prono);
+ j_a = j_item.find('td.name > a.link');
+ j_a.attr('href','/toj/pro/' + proo.proid + '/');
+ j_a.text(proo.proname);
+
+ bscore = proo.bscore;
+ fscore = proo.full_score;
+ j_item.find('td.bscore').text(bscore + ' / ' + fscore);
+
+ if(proo.tried == false){
+ j_item.css('border-color','#1C1C1C');
+ }else{
+ ratio = bscore / fscore;
+
+ if(ratio < 0.6){
+ j_item.css('border-color','#FF0000');
+ }else if(ratio < 0.8){
+ j_item.css('border-color','#00FF00');
+ }else if(ratio < 1){
+ j_item.css('border-color','#FFFF00');
+ }else{
+ j_item.css('border-color','#FFFFFF');
+ }
+ }
+
+ j_team = j_item.find('td.team');
+ j_team.hide();
+ for(i = 0;i < proo.tscore.length;i++){
+ $(j_team[i]).text(proo.tscore[i]);
+ $(j_team[i]).show();
+ }
+ }
+ };
+ var pro_listnew = function(proo){
+ var j_item;
+
+ j_item = $('<tr class="item"><td class="no"></td><td class="name"><a class="link"></a></td><td class="bscore"></td><td class="team"></td><td class="team"></td><td class="team"></td><td class="team"></td></tr>');
+ pro_listset(j_item,proo);
+
+ return j_item;
+ };
+ var prog_set = function(j_progbox,baseline,totalscore){
+ var off;
+ var ratio;
+ var j_prog;
+
+ off = 0;
+ ratio = baseline.pass_score * 100 / baseline.total_score;
+ j_prog = j_progbox.find('div.pass');
+ j_prog.css('width',ratio + '%');
+ j_prog.html(baseline.pass_score + '&nbsp');
+ off += ratio;
+ ratio = (baseline.good_score - baseline.pass_score) * 100 / baseline.total_score;
+ j_prog = j_progbox.find('div.good');
+ j_prog.css('left',off + '%');
+ j_prog.css('width',ratio + '%');
+ j_prog.html(baseline.good_score + '&nbsp');
+ off += ratio;
+ ratio = 100 - off;
+ j_prog = j_progbox.find('div.total');
+ j_prog.css('left',off + '%');
+ j_prog.css('width',ratio + '%');
+ j_prog.html(baseline.total_score + '&nbsp');
+
+ ratio = totalscore * 100 / baseline.total_score;
+ j_prog = j_progbox.find('div.prog');
+ j_prog.css('width',ratio + '%');
+ j_prog.html(totalscore + '&nbsp');
+ if(totalscore < baseline.pass_score){
+ ratio = totalscore / baseline.pass_score;
+ j_prog.css('background-color','rgba(255,' + Math.round(64 * ratio) + ',0,0.8)');
+ }else if(totalscore < baseline.good_score){
+ ratio = (totalscore - baseline.pass_score) / (baseline.good_score - baseline.pass_score);
+ j_prog.css('background-color','rgba(' + Math.round(128 * ratio) + ',255,0,0.8)');
+ }else if(totalscore < baseline.total_score){
+ ratio = (totalscore - baseline.good_score) / (baseline.total_score - baseline.good_score);
+ j_prog.css('background-color','rgba(255,255,' + Math.round(128 * ratio) + ',0.8)');
+ }else{
+ j_prog.css('background-color','rgba(255,255,255,0.8)');
+ }
+ }
+ var prostat_refresh = function(){
+ if(refresh_flag == false){
+ return;
+ }
+
+ $.post('/toj/sqmod/sqmod_test/sqmod_test.php',{'action':'get_user_stat','data':JSON.stringify({'sqid':paobj.sqid,'display_team':true})},function(res){
+ var i;
+ var j;
+
+ var reto;
+ var team;
+ var teamo;
+ var prostat;
+ var prostato;
+ var proo;
+ var user_total;
+ var team_total;
+ var maxscore;
+ var j_list;
+ var j_team;
+ var j_a;
+ var j_item;
+
+ if(res[0] != 'E'){
+ reto = JSON.parse(res);
+ team = reto.team;
+ prostat = reto.prostat;
+
+ j_list = j_tab.find('table.prolist');
+ if(team != undefined){
+ j_team = j_list.find('th.team');
+ for(i = 0;i < team.length;i++){
+ teamo = team[i];
+
+ j_a = j_team.find('a.link');
+ $(j_a[i]).attr('href','/toj/user/' + teamo.uid + '/')
+ $(j_a[i]).text(teamo.name);
+
+ for(j = 0;j < teamo.prostat.length;j++){
+ if(teamo.prostat[j].tried == true){
+ promap[teamo.prostat[j].proid].tscore[i] = teamo.prostat[j].best_score;
+ }else{
+ promap[teamo.prostat[j].proid].tscore[i] = 0;
+ }
+ }
+
+ j_team.show();
+ }
+
+ j_tab.find('table.stat tr.team_prog').show();
+ }
+
+ user_total = 0;
+ team_total = 0;
+ for(i = 0;i < prostat.length;i++){
+ prostato = prostat[i];
+ proo = promap[prostato.proid];
+ proo.bscore = prostato.best_score;
+ proo.tried = prostato.tried;
+ user_total += prostato.best_score;
+ j_item = j_list.find('[proid = "' + prostato.proid + '"]');
+ if(j_item.length > 0){
+ pro_listset(j_item,proo);
+ }
+
+ maxscore = proo.bscore;
+ for(j = 0;j < proo.tscore.length;j++){
+ maxscore = Math.max(maxscore,proo.tscore[j]);
+ }
+ team_total += maxscore;
+ }
+
+ prog_set(j_tab.find('table.stat div.user_prog'),reto.base_line,user_total);
+ prog_set(j_tab.find('table.stat div.team_prog'),reto.team_base_line,team_total);
+
+ setTimeout(prostat_refresh,2000);
+ }
+ });
+ };
+
+ that.__super(paobj);
+
+ that.urlchange = function(direct){
+ if(direct == 'in'){
+ that.fadein(j_tab);
+ refresh_flag = true;
+
+ $.post('/toj/sqmod/sqmod_test/sqmod_test.php',{'action':'get_prolist','data':JSON.stringify({'sqid':paobj.sqid})},function(res){
+ var i;
+ var reto;
+ var proo;
+ var j_list;
+ var j_item;
+
+ if(res[0] != 'E'){
+ reto = JSON.parse(res);
+
+ promap = new Array;
+ j_list = j_tab.find('table.prolist');
+ for(i = 0;i < reto.length;i++){
+ proo = reto[i];
+ proo.bscore = 0;
+ proo.tscore = new Array;
+ proo.tried = false;
+ if(proo.hidden == false){
+ promap[proo.proid] = proo;
+ j_item = pro_listnew(proo);
+ j_list.append(j_item);
+ }
+ }
+
+ prostat_refresh();
+ }
+ });
+
+ }else if(direct == 'out'){
+ that.fadeout(j_tab);
+ refresh_flag = false;
+ }
+ };
+}; __extend(class_sqmod_test_pro_tab,class_common_tab);
diff --git a/toj/sqmod/sqmod_test/sqmod_test.php b/toj/sqmod/sqmod_test/sqmod_test.php
new file mode 100755
index 0000000..40093e2
--- /dev/null
+++ b/toj/sqmod/sqmod_test/sqmod_test.php
@@ -0,0 +1,84 @@
+<?php
+//ini_set("display_errors", "On");
+
+require_once('../../php/common.inc.php');
+require_once('../../php/user.inc.php');
+require_once('sqmod_test.inc.php');
+require_once('team.inc.php');
+require_once('../../php/sqlib_scoreboard.inc.php');
+
+$sqlc = db_connect();
+$msqlc = db_connect('toj_mod');
+
+$action = $_POST['action'];
+$data = $_POST['data'];
+
+if(strlen($action)==0)
+ die('Eno_action');
+if($action == 'get_prolist')
+{
+ $dt = json_decode($data);
+ $sqid = intval($dt->sqid);
+ if(square::get_sqmod($sqlc, $sqid) != SQMODNAME)
+ die('Eerror_sqid_this_mod');
+ if(!sec_is_login())
+ die('Enot_login');
+ $uid = intval($_COOKIE['uid']);
+ if(square::get_user_relationship($sqlc, $uid, $sqid) != SQUARE_USER_ACTIVE)
+ die('Ecannot_view_sq');
+
+ $list = square::get_pro_list($sqlc, $sqid);
+ if(!$list)
+ die('Eno_problem');
+ $data = get_setting($sqid);
+ $nlist = process_pro_list($list, $data, $sqid);
+ echo(json_encode($nlist));
+}
+if($action == 'get_user_stat')
+{
+ $dt = json_decode($data);
+ $sqid = intval($dt->sqid);
+ $display_team = $dt->display_team;
+ if(square::get_sqmod($sqlc, $sqid) != SQMODNAME)
+ die('Eerror_sqid_this_mod');
+ if(!sec_is_login())
+ die('Enot_login');
+ $uid = intval($_COOKIE['uid']);
+ if(square::get_user_relationship($sqlc, $uid, $sqid) != SQUARE_USER_ACTIVE)
+ die('Ecannot_view_sq');
+
+ $data = get_setting($sqid);
+
+ $ret = new stdClass();
+ $prostat = get_pro_stat_uid($sqlc, $msqlc, $sqid, SCOREBOARD_ID_PROBSTAT, $uid);
+ $tmpstat = process_pro_stat($prostat);
+ $ret->prostat = calc_score($tmpstat, $data, $sqid);
+ $ret->base_line = get_base_line($data, $sqid, false);
+
+ if($display_team)
+ {
+ $term = get_term($data, $sqid);
+ $teamid = intval(get_teamid($msqlc, $term, $uid));
+ if($teamid)
+ {
+ $ret->team_base_line = get_base_line($data, $sqid, true);
+ $members = get_team_member($msqlc, $term, $teamid);
+ $arr = array();
+ foreach($members as $mem)
+ {
+ if($mem->uid == $uid)continue;
+ $tmpstat = process_pro_stat(get_pro_stat_uid($sqlc, $msqlc, $sqid, SCOREBOARD_ID_PROBSTAT, $mem->uid));
+ $mem->prostat = calc_score($tmpstat, $data, $sqid);
+ array_push($arr, $mem);
+ }
+ $ret->team = $arr;
+ $ret->teamid = $teamid;
+ }
+ }
+ echo(json_encode($ret));
+}
+
+db_close($sqlc);
+db_close($msqlc);
+
+?>
diff --git a/toj/sqmod/sqmod_test/team.inc.php b/toj/sqmod/sqmod_test/team.inc.php
new file mode 100644
index 0000000..3effc0e
--- /dev/null
+++ b/toj/sqmod/sqmod_test/team.inc.php
@@ -0,0 +1,37 @@
+<?php
+
+require_once('../../php/common.inc.php');
+
+const TEAM_TYPE_BOY = 1;
+const TEAM_TYPE_GIRL = 2;
+const TEAM_TYPE_COL = 3;
+const TEAM_TYPE_TEA = 4;
+
+function get_teamid($msqlc, $term, $uid)
+{
+ //Return the teamid of $uid. False if not exists.
+ $sqlstr = 'SELECT "teamid" FROM "sqmod_sprout_team" WHERE "term"=$1 AND "uid"=$2;';
+ $sqlarr = array($term, $uid);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $teamid = pg_fetch_result($res, 0);
+ return $teamid;
+}
+
+function get_team_member($msqlc, $term, $teamid)
+{
+ //Return all team member uid, level of team $teamid. False if not exists.
+ $sqlstr = 'SELECT "sqmod_sprout_team"."uid", "sqmod_sprout_team"."level", "sqmod_sprout_student"."name" FROM "sqmod_sprout_team" INNER JOIN "sqmod_sprout_student" ON "sqmod_sprout_team"."uid"="sqmod_sprout_student"."uid" WHERE "sqmod_sprout_team"."term"=$1 AND "sqmod_sprout_team"."teamid"=$2 ORDER BY "sqmod_sprout_team"."level" DESC, "sqmod_sprout_team"."uid";';
+ $sqlarr = array($term, $teamid);
+ $res = pg_query_params($msqlc, $sqlstr, $sqlarr);
+ $ret = array();
+ while($obj = pg_fetch_object($res))
+ {
+ $obj->uid = intval($obj->uid);
+ $obj->level = intval($obj->level);
+ array_push($ret, $obj);
+ }
+ return $ret;
+}
+
+
+?>