diff options
Diffstat (limited to 'web/pmod')
-rw-r--r-- | web/pmod/pmod_test/pmod_test.css | 102 | ||||
-rw-r--r-- | web/pmod/pmod_test/pmod_test.html | 106 | ||||
-rw-r--r-- | web/pmod/pmod_test/pmod_test.inc.php | 29 | ||||
-rw-r--r-- | web/pmod/pmod_test/pmod_test.js | 244 | ||||
-rw-r--r-- | web/pmod/pmod_test/pmod_test.php | 110 |
5 files changed, 505 insertions, 86 deletions
diff --git a/web/pmod/pmod_test/pmod_test.css b/web/pmod/pmod_test/pmod_test.css index f8a48a6..c238c44 100644 --- a/web/pmod/pmod_test/pmod_test.css +++ b/web/pmod/pmod_test/pmod_test.css @@ -1,48 +1,126 @@ -div.pmod_test > div.info{ +div.pmod_test > div.pro_pbox > div.info{ width:240px; float:left; } -div.pmod_test > div.info > table.statlist{ +div.pmod_test > div.pro_pbox > div.info > table.statlist{ width:100%; text-align:left; border-collapse:collapse; } -div.pmod_test > div.info > table.statlist td.name{ +div.pmod_test > div.pro_pbox > div.info > table.statlist td.name{ width:76px; } -div.pmod_test > div.info > table.statlist td.value{ +div.pmod_test > div.pro_pbox > div.info > table.statlist td.value{ width:auto; padding:0px 0px 0px 6px; } -div.pmod_test > div.info > table.limitlist{ +div.pmod_test > div.pro_pbox > div.info > table.limitlist{ width:100%; text-align:left; border-collapse:collapse; } -div.pmod_test > div.info > table.limitlist td.name{ +div.pmod_test > div.pro_pbox > div.info > table.limitlist td.name{ width:76px; } -div.pmod_test > div.info > table.limitlist td.value{ +div.pmod_test > div.pro_pbox > div.info > table.limitlist td.value{ width:auto; padding:0px 0px 0px 6px; } -div.pmod_test > div.info > table.scorelist{ +div.pmod_test > div.pro_pbox > div.info > table.scorelist{ width:100%; text-align:left; border-collapse:collapse; } -div.pmod_test > div.info > table.scorelist th.no,div.pmod_test > div.info > table.scorelist td.no{ +div.pmod_test > div.pro_pbox > div.info > table.scorelist th.no,div.pmod_test > div.pro_pbox > div.info > table.scorelist td.no{ width:76px; } -div.pmod_test > div.info > table.scorelist th.score,div.pmod_test > div.info > table.scorelist td.score{ +div.pmod_test > div.pro_pbox > div.info > table.scorelist th.score,div.pmod_test > div.pro_pbox > div.info > table.scorelist td.score{ width:auto; padding:0px 0px 0px 6px; } -div.pmod_test > div.content{ +div.pmod_test > div.pro_pbox > div.content{ width:978px; margin:0px 0px 0px 6px; float:left; } -div.pmod_test p{ +div.pmod_test > div.pro_pbox p{ text-indent:32px; } + + + +div.pmod_test > div.edit_pbox > div.edit_box{ + width:976px; + margin:0px 0px 0px 246px; + padding:0px 0px 32px 0px; +} +div.pmod_test > div.edit_pbox > div.edit_box input{ + width:228px; + margin:0px 0px 16px 0px; +} +div.pmod_test > div.edit_pbox > div.edit_box > div.contentbox{ + width:100%; + height:512px; + padding:0px 0px 32px 0px; +} +div.pmod_test > div.edit_pbox > div.testdata_box{ + width:976px; + margin:0px 0px 0px 246px; + padding:0px 0px 32px 0px; +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table{ + margin:32px 0px 32px 0px; + border-collapse:collapse; + text-align:left; +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table tr.head{ + height:64px +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table tr.item{ + height:64px +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table th,div.pmod_test > div.edit_pbox > div.testdata_box > table.table td{ + width:76px; + padding:0px 0px 0px 6px; +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table th.no,div.pmod_test > div.edit_pbox > div.testdata_box > table.table td.no{ + padding:0px 0px 0px 0px; +} + +div.pmod_test > div.edit_pbox > div.testdata_box > table.table td.score > input{ + width:35px; +} +div.pmod_test > div.edit_pbox > div.testdata_box > table.table th.file,div.pmod_test > div.edit_pbox > div.testdata_box > table.table td.file{ + width:322px; +} + +div.pmod_test > div.edit_pbox div.prog_box{ + width:486px; + height:16px; + margin:0px 0px 16px 0px; + 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.pmod_test > div.edit_pbox div.prog_box > div.total{ + width:0%; + height:16px; + position:absolute; + top:0px; + left:0%; + overflow:hidden; +} +div.pmod_test > div.edit_pbox div.prog_box > div.prog{ + width:0%; + height:16px; + background-color:#3A8FB7; + font-weight:bold; + position:absolute; + top:0px; + left:0px; + overflow:hidden; +} diff --git a/web/pmod/pmod_test/pmod_test.html b/web/pmod/pmod_test/pmod_test.html index 7f1a1b8..a04c2a6 100644 --- a/web/pmod/pmod_test/pmod_test.html +++ b/web/pmod/pmod_test/pmod_test.html @@ -1,38 +1,76 @@ -<div class="info"> - <h2 class="proid">ProID:</h2> - <button class="submit">上傳</button> +<div class="com_pbox pro_pbox"> + <div class="info"> + <h2 class="proid">ProID:</h2> + <button class="submit">上傳</button> - <h3>狀態</h3> - <table class="statlist"> - <tr> - <td class="name">最佳分數</td> - <td class="value bscore"></td> - </tr> - <tr> - <td class="name">解題狀態</td> - <td class="value stat"></td> - </tr> - </table> + <h3>狀態</h3> + <table class="statlist"> + <tr> + <td class="name">最佳分數</td> + <td class="value bscore"></td> + </tr> + <tr> + <td class="name">解題狀態</td> + <td class="value stat"></td> + </tr> + </table> - <h3>限制</h3> - <table class="limitlist"> - <tr> - <td class="name">執行時間</td> - <td class="value timelimit"></td> - </tr> - <tr> - <td class="name">記憶體</td> - <td class="value memlimit"></td> - </tr> - </table> + <h3>限制</h3> + <table class="limitlist"> + <tr> + <td class="name">執行時間</td> + <td class="value timelimit"></td> + </tr> + <tr> + <td class="name">記憶體</td> + <td class="value memlimit"></td> + </tr> + </table> - <h3>配分</h3> - <table class="scorelist"> - <tr class="head"> - <th class="no">#</th> - <th class="score">Score</th> - </tr> - </table> + <h3>配分</h3> + <table class="scorelist"> + <tr class="head"> + <th class="no">#</th> + <th class="score">Score</th> + </tr> + </table> + </div> + <div class="content"></div> + <div style="width:100%; height:32px; clear:both;"></div> +</div> +<div class="com_pbox edit_pbox"> + <div class="edit_box"> + <h2>限制</h2> + <label>執行時間限制(ms)</label> + <input name="timelimit" type="textbox" placeholder="1000"> + <label>記憶體限制(KB)</label> + <input name="memlimit" type="textbox" placeholder="65536"> + + <h2>內容</h2> + <div class="contentbox"></div> + <button class="submit">更新資料</button> + <button class="cancel">取消</button> + </div> + <div class="testdata_box"> + <h2>測試資料</h2> + <label>數量</label> + <input name="count" type="textbox" placeholder="10"> + <table class="table"> + <thead> + <tr class="head"> + <th class="no">#</th> + <th class="score">配分</th> + <th class="file in">輸入檔</th> + <th class="file ans">輸出檔</th> + </tr> + </thead> + <tbody></tbody> + </table> + <div class="prog_box testdata_prog" style="display:none;"> + <div class="total"></div> + <div class="prog"></div> + </div> + <button class="submit">更新測試資料</button> + <button class="cancel">取消</button> + </div> </div> -<div class="content"></div> -<div style="width:100%; height:32px; clear:both;"></div> diff --git a/web/pmod/pmod_test/pmod_test.inc.php b/web/pmod/pmod_test/pmod_test.inc.php new file mode 100644 index 0000000..a433404 --- /dev/null +++ b/web/pmod/pmod_test/pmod_test.inc.php @@ -0,0 +1,29 @@ +<?php +require_once('problem.inc.php'); +require_once('user.inc.php'); + +function event_create($proid) +{ + $sqlc = db_connect(); + + $proid = intval($proid); + $prodir = '/srv/http/toj/center/pro/'.$proid.'/'; + + mkdir($prodir); + mkdir($prodir.'public/'); + mkdir($prodir.'private/'); + + $set = new stdClass(); + $set->timelimit = 0; + $set->memlimit = 0; + $set->count = 0; + $set->score = array(); + $newstr = "jmod_test\njmod_test_check\n=====\n\n".json_encode($set); + + file_put_contents($prodir.'public/content', ''); + file_put_contents($prodir.'setting', $newstr); + + db_close($sqlc); +} + +?> diff --git a/web/pmod/pmod_test/pmod_test.js b/web/pmod/pmod_test/pmod_test.js index 3f1e577..f21c5b0 100644 --- a/web/pmod/pmod_test/pmod_test.js +++ b/web/pmod/pmod_test/pmod_test.js @@ -1,10 +1,69 @@ -var pmod_test = function(that,j_pbox){ - that.node.url_chg = function(direct,url_upart,url_dpart){ - if(direct == 'in'){ - that.fadein(j_pbox); +var pmod_test = function(that,j_page){ + var j_pro_pbox = j_page.find('div.pro_pbox'); + var j_edit_pbox = j_page.find('div.edit_pbox'); + var edit_pbox = new vus.node('edit'); - j_pbox.find('div.info > h2.proid').text('ProID:' + that.proid); - $.post('/toj/pmod/pmod_test/pmod_test.php',{'proid':JSON.stringify(that.proid)},function(res){ + var contentbox = CodeMirror(j_edit_pbox.find('div.contentbox')[0],{ + mode:'text/html', + theme:'lesser-dark', + lineNumbers:true, + matchBrackets:true, + indentUnit:4 + }); + + var testdata_update = function(count,scorelist){ + var i; + var count; + var trs; + var j_table; + var _testdata_listnew = function(idx,score){ + var j_item = $('<tr class="item"><td class="no"></td><td class="score"><input name="score" type="textbox"></td><td class="file ans"><input name="infile" type="file"></td><td class="file ans"><input name="ansfile" type="file"></td></tr>'); + + j_item.find('td.no').text(idx + 1); + j_item.find('[name="score"]').val(score); + + return j_item; + }; + + trs = j_edit_pbox.find('div.testdata_box > table.table tr.item'); + j_table = j_edit_pbox.find('div.testdata_box > table.table'); + for(i = count;i < trs.length;i++){ + $(trs[i]).remove(); + } + if(scorelist != null){ + for(i = trs.length;i < count;i++){ + j_table.append(_testdata_listnew(i,scorelist[i])); + } + }else{ + for(i = trs.length;i < count;i++){ + j_table.append(_testdata_listnew(i,'0')); + } + } + }; + + that.node.url_chg = function(direct,url_upart,url_dpart,param){ + var _out = function(){ + index.tab_ll('pro'); + that.fadeout(j_pro_pbox); + index.content_empty(); + }; + + if(direct == 'in' || direct == 'same'){ + if(direct == 'in' && user.level == -1){ + index.tab_add('pro','/toj/pro/' + that.proid + '/','題目'); + index.tab_add('edit','/toj/pro/' + that.proid + '/edit/','設定'); + } + + if(url_dpart.length > 0){ + _out(); + return 'cont'; + } + + index.tab_hl('pro'); + that.fadein(j_pro_pbox); + + j_pro_pbox.find('div.info > h2.proid').text('ProID:' + that.proid); + $.post('/toj/pmod/pmod_test/pmod_test.php',{'action':'get_pro_data','data':JSON.stringify({'proid':that.proid})},function(res){ var i; var reto; var seto; @@ -15,42 +74,48 @@ var pmod_test = function(that,j_pbox){ reto = JSON.parse(res); seto = reto.set; index.content_set($('<span>' + that.proname + '</span>')); - j_pbox.find('div.content').html(reto.content); + + if(seto == null){ + j_pro_pbox.find('div.content').html('<h2>題目未設定</h2>'); + return; + } + + j_pro_pbox.find('div.content').html(reto.content); $.post('/toj/php/problem.php',{'action':'get_pro_stat','data':JSON.stringify({'proid':that.proid})},function(res){ var reto if(res[0] != 'E'){ reto = JSON.parse(res); - j_pbox.find('div.info > table.statlist td.bscore').text(reto.score); + j_pro_pbox.find('div.info > table.statlist td.bscore').text(reto.score); if(reto.tried == false){ - j_pbox.find('div.info > table.statlist td.bscore').css('color','#1C1C1C'); - j_pbox.find('div.info > table.statlist td.stat').text('未嘗試'); + j_pro_pbox.find('div.info > table.statlist td.bscore').css('color','#1C1C1C'); + j_pro_pbox.find('div.info > table.statlist td.stat').text('未嘗試'); }else{ if(reto.score < 60){ - j_pbox.find('div.info > table.statlist td.bscore').css('color','#FF0000'); + j_pro_pbox.find('div.info > table.statlist td.bscore').css('color','#FF0000'); }else if(reto.score < 80){ - j_pbox.find('div.info > table.statlist td.bscore').css('color','#00FF00'); + j_pro_pbox.find('div.info > table.statlist td.bscore').css('color','#00FF00'); }else if(reto.score < 100){ - j_pbox.find('div.info > table.statlist td.bscore').css('color','#FFFF00'); + j_pro_pbox.find('div.info > table.statlist td.bscore').css('color','#FFFF00'); }else{ - j_pbox.find('div.info > table.statlist td.bscore').css('color','#FFFFFF'); + j_pro_pbox.find('div.info > table.statlist td.bscore').css('color','#FFFFFF'); } if(reto.is_ac == true){ - j_pbox.find('div.info > table.statlist td.stat').text('已通過'); + j_pro_pbox.find('div.info > table.statlist td.stat').text('已通過'); }else{ - j_pbox.find('div.info > table.statlist td.stat').text('已嘗試'); + j_pro_pbox.find('div.info > table.statlist td.stat').text('已嘗試'); } } } }); - j_pbox.find('div.info > table.limitlist td.timelimit').text(seto.timelimit + ' ms'); - j_pbox.find('div.info > table.limitlist td.memlimit').text(seto.memlimit + ' KB'); + j_pro_pbox.find('div.info > table.limitlist td.timelimit').text(seto.timelimit + ' ms'); + j_pro_pbox.find('div.info > table.limitlist td.memlimit').text(seto.memlimit + ' KB'); - j_table = j_pbox.find('table.scorelist'); + j_table = j_pro_pbox.find('table.scorelist'); j_table.find('tr.item').remove(); for(i = 0;i < seto.count;i++){ j_item = $('<tr class="item"><td class="no"></td><td class="score"></td></tr>'); @@ -59,17 +124,152 @@ var pmod_test = function(that,j_pbox){ j_table.append(j_item); } - MathJax.Hub.Queue(["Typeset",MathJax.Hub,j_pbox[0]]); + MathJax.Hub.Queue(["Typeset",MathJax.Hub,j_pro_pbox[0]]); } }); }else if(direct == 'out'){ - that.fadeout(j_pbox); + _out(); } return 'cont'; }; - j_pbox.find('div.info > button.submit').on('click',function(e){ + j_pro_pbox.find('div.info > button.submit').on('click',function(e){ that.submit(); }); + j_edit_pbox.find('div.edit_box > button.submit').on('click',function(e){ + timelimit = parseInt(j_edit_pbox.find('div.edit_box > [name="timelimit"]').val()); + memlimit = parseInt(j_edit_pbox.find('div.edit_box > [name="memlimit"]').val()); + content = contentbox.getValue(); + + $.post('/toj/pmod/pmod_test/pmod_test.php',{'action':'set_pro_data','data':JSON.stringify({'proid':that.proid,'timelimit':timelimit,'memlimit':memlimit,'content':content})},function(res){ + com.url_push_back(); + }); + }); + j_edit_pbox.find('div.edit_box > button.cancel').on('click',function(e){ + com.url_push_back(); + }); + + j_edit_pbox.find('div.testdata_box > [name="count"]').on('change',function(e){ + testdata_update(parseInt($(this).val()),null); + }); + j_edit_pbox.find('div.testdata_box > button.submit').on('click',function(e){ + var i; + + var count; + var score; + var inputs + + var formdata; + var inputs; + var file; + + var j_progbox; + var j_total; + var j_prog; + + count = parseInt(j_edit_pbox.find('div.testdata_box > [name="count"]').val()); + + inputs = j_edit_pbox.find('div.testdata_box > table.table [name="score"]'); + score = Array(); + for(i = 0;i < count;i++){ + score[i] = parseInt($(inputs[i]).val()); + } + + formdata = new FormData(); + formdata.append('action','update_pro_testdata'); + formdata.append('data',JSON.stringify({'proid':that.proid,'count':count,'score':score})); + + inputs = j_edit_pbox.find('div.testdata_box > table.table [name="infile"]'); + for(i = 0;i < inputs.length;i++){ + if((file = inputs[i].files[0]) != undefined){ + formdata.append('infile_' + i,file); + } + } + inputs = j_edit_pbox.find('div.testdata_box > table.table [name="ansfile"]'); + for(i = 0;i < inputs.length;i++){ + if((file = inputs[i].files[0]) != undefined){ + formdata.append('ansfile_' + i,file); + } + } + + j_progbox = j_edit_pbox.find('div.testdata_box > div.testdata_prog'); + j_total = j_progbox.find('div.total'); + j_prog = j_progbox.find('div.prog'); + + j_total.css('width','100%'); + j_total.text('上傳中...'); + j_prog.css('width','0%'); + j_prog.text('0%'); + + j_progbox.show(); + + $.ajax({ + url:'/toj/pmod/pmod_test/pmod_test.php', + type:'POST', + xhr:function(){ + req = $.ajaxSettings.xhr(); + + req.upload.addEventListener('progress',function(e){ + console.log(); + j_prog.css('width',(e.loaded * 100 / e.total) + '%'); + j_prog.text(Math.round(e.loaded * 100 / e.total) + ' %'); + },false); + + return req; + }, + data:formdata, + contentType:false, + processData:false, + success:function(){ + com.url_push_back(); + } + }); + }); + j_edit_pbox.find('div.testdata_box > button.cancel').on('click',function(e){ + com.url_push_back(); + }); + + if(user.level == -1){ + edit_pbox.url_chg = function(direct,url_upart,url_dpart,param){ + if(direct == 'in'){ + index.tab_hl('edit'); + that.fadein(j_edit_pbox); + + contentbox.refresh(); + + $.post('/toj/pmod/pmod_test/pmod_test.php',{'action':'get_pro_data','data':JSON.stringify({'proid':that.proid})},function(res){ + var reto; + + if(res[0] != 'E'){ + reto = JSON.parse(res); + set = reto.set; + + j_edit_pbox.find('div.edit_box > [name="timelimit"]').val(set.timelimit); + j_edit_pbox.find('div.edit_box > [name="memlimit"]').val(set.memlimit); + + if(reto.content != false){ + contentbox.setValue(reto.content); + } + + j_edit_pbox.find('div.testdata_box > [name="count"]').val(set.count); + testdata_update(set.count,set.score); + } + }); + }else if(direct == 'out'){ + index.tab_ll('edit'); + that.fadeout(j_edit_pbox); + + j_edit_pbox.find('div.testdata_box > div.testdata_prog').hide(); + } + + return 'cont'; + }; + that.node.child_set(edit_pbox); + + contentbox.getWrapperElement().style.width = '100%'; + contentbox.getWrapperElement().style.height = '100%'; + contentbox.getScrollerElement().style.width = '100%'; + contentbox.getScrollerElement().style.height = '100%'; + } }; diff --git a/web/pmod/pmod_test/pmod_test.php b/web/pmod/pmod_test/pmod_test.php index 27eecf2..a472630 100644 --- a/web/pmod/pmod_test/pmod_test.php +++ b/web/pmod/pmod_test/pmod_test.php @@ -1,9 +1,32 @@ <?php -require_once('../../php/problem.inc.php'); +require_once('problem.inc.php'); +require_once('user.inc.php'); const PMODNAME = 'pmod_test'; -$proid = json_decode($_POST['proid']); +function get_setting($prodir) +{ + $fd = fopen($prodir.'setting','r'); + $prestr = array(); + while($line = fgets($fd)){ + if($line[0] == '='){ + break; + } + array_push($prestr, $line); + } + $set = ''; + while(($line = fgets($fd))){ + $set = $set.$line; + } + fclose($fd); + + return array($prestr, json_decode($set)); +} + +$action = $_POST['action']; +$data = json_decode($_POST['data']); + +$proid = intval($data->proid); if(gettype($proid) != 'integer' || $proid < 1){ exit('Eproid'); } @@ -17,26 +40,77 @@ $pro = problem::get($sqlc, $proid); if($pro->pmodname != PMODNAME) exit('Ewrong_pmod'); -db_close($sqlc); - $prodir = '/srv/http/toj/center/pro/'.$proid.'/'; -$fd = fopen($prodir.'setting','r'); -while($line = fgets($fd)){ - if($line[0] == '='){ - break; - } +if($action=='get_pro_data') +{ + $content = file_get_contents($prodir.'public/content'); + + echo(json_encode(array( + 'set' => get_setting($prodir)[1], + 'content' => $content + ))); } -$set = ''; -while(($line = fgets($fd))){ - $set = $set.$line; +if($action=='set_pro_data') +{ + if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN)) + die('Epermission_denied'); + + $obj = get_setting($prodir); + $prestr = $obj[0]; + $set = $obj[1]; + $set->timelimit = $data->timelimit; + $set->memlimit = $data->memlimit; + file_put_contents($prodir.'public/content', $data->content); + + $newstr = ''; + foreach($prestr as $s) + { + $newstr = $newstr.$s; + } + $newstr = $newstr."=====\n\n"; + $newstr = $newstr.json_encode($set); + file_put_contents($prodir.'setting', $newstr); } -fclose($fd); +if($action=='update_pro_testdata') +{ + if(!sec_check_level($sqlc, USER_LEVEL_SUPERADMIN)) + die('Epermission_denied'); + + $count = $data->count; + $score = $data->score; + + $obj = get_setting($prodir); + $prestr = $obj[0]; + $set = $obj[1]; + $set->count = $count; + $set->score = $score; + + $newstr = ''; + foreach($prestr as $s) + { + $newstr = $newstr.$s; + } + $newstr = $newstr."=====\n\n"; + $newstr = $newstr.json_encode($set); + file_put_contents($prodir.'setting', $newstr); -$content = file_get_contents($prodir.'public/content'); + $tddir = $prodir.'/private/'; + for($idx = 0;$idx < $count;$idx++){ + $dst = $tddir.strval($idx + 1); + mkdir($dst); -echo(json_encode(array( - 'set' => json_decode($set), - 'content' => $content -))); + $key = 'infile_'.strval($idx); + if(array_key_exists($key,$_FILES)){ + move_uploaded_file($_FILES[$key]["tmp_name"],$dst.'/in'); + } + + $key = 'ansfile_'.strval($idx); + if(array_key_exists($key,$_FILES)){ + move_uploaded_file($_FILES[$key]["tmp_name"],$dst.'/ans'); + } + } +} + +db_close($sqlc); ?> |