Example #1
0
 /**
  * Displays detail description of given problem
  *
  * @param int $assignment_id
  * @param int $problem_id
  */
 public function index($assignment_id = NULL, $problem_id = 1)
 {
     // If no assignment is given, use selected assignment
     if ($assignment_id === NULL) {
         $assignment_id = $this->user->selected_assignment['id'];
     }
     if ($assignment_id == 0) {
         show_error('No assignment selected.');
     }
     $assignment = $this->assignment_model->assignment_info($assignment_id);
     $data = array('all_assignments' => $this->all_assignments, 'all_problems' => $this->assignment_model->all_problems($assignment_id), 'description_assignment' => $assignment, 'can_submit' => TRUE);
     if (!is_numeric($problem_id) || $problem_id < 1 || $problem_id > $data['description_assignment']['problems']) {
         show_404();
     }
     $languages = explode(',', $data['all_problems'][$problem_id]['allowed_languages']);
     $assignments_root = rtrim($this->settings_model->get_setting('assignments_root'), '/');
     $problem_dir = "{$assignments_root}/assignment_{$assignment_id}/p{$problem_id}";
     $data['problem'] = array('id' => $problem_id, 'description' => '<p>Description not found</p>', 'allowed_languages' => $languages, 'has_pdf' => glob("{$problem_dir}/*.pdf") != FALSE);
     $path = "{$problem_dir}/desc.html";
     if (file_exists($path)) {
         $data['problem']['description'] = file_get_contents($path);
     }
     if ($assignment['id'] == 0 or $this->user->level == 0 && !$assignment['open'] or shj_now() < strtotime($assignment['start_time']) or shj_now() > strtotime($assignment['finish_time']) + $assignment['extra_time'] or !$this->assignment_model->is_participant($assignment['participants'], $this->user->username)) {
         $data['can_submit'] = FALSE;
     }
     $this->twig->display('pages/problems.twig', $data);
 }
Example #2
0
 /**
  * Returns server time (uses time zone in settings table)
  */
 function shj_now_str()
 {
     if (!defined('SHJ_NOW_STR')) {
         define('SHJ_NOW_STR', date("Y-m-d H:i:s", shj_now()));
     }
     return SHJ_NOW_STR;
 }
Example #3
0
 /**
  * Compressing and downloading final codes of an assignment to the browser
  */
 public function download_submissions($type = FALSE, $assignment_id = FALSE)
 {
     if ($type !== 'by_user' && $type !== 'by_problem') {
         show_404();
     }
     if ($assignment_id === FALSE || !is_numeric($assignment_id)) {
         show_404();
     }
     if ($this->user->level == 0) {
         // permission denied
         show_404();
     }
     $this->load->model('submit_model');
     $items = $this->submit_model->get_final_submissions($assignment_id, $this->user->level, $this->user->username);
     $this->load->library('zip');
     $assignments_root = rtrim($this->settings_model->get_setting('assignments_root'), '/');
     foreach ($items as $item) {
         $file_path = $assignments_root . "/assignment_{$item['assignment']}/p{$item['problem']}/{$item['username']}/{$item['file_name']}." . filetype_to_extension($item['file_type']);
         if (!file_exists($file_path)) {
             continue;
         }
         $file = file_get_contents($file_path);
         if ($type === 'by_user') {
             $this->zip->add_data("{$item['username']}/p{$item['problem']}." . filetype_to_extension($item['file_type']), $file);
         } elseif ($type === 'by_problem') {
             $this->zip->add_data("problem_{$item['problem']}/{$item['username']}." . filetype_to_extension($item['file_type']), $file);
         }
     }
     $this->zip->download("assignment{$assignment_id}_submissions_{$type}_" . date('Y-m-d_H-i', shj_now()) . '.zip');
 }
 public function mcqproblems($assignment_id = NULL)
 {
     // If no assignment is given, use selected assignment
     if ($assignment_id === NULL) {
         $assignment_id = $this->user->selected_assignment['id'];
     }
     if ($assignment_id == 0) {
         show_error('No assignment selected.');
     }
     $assignment = $this->assignment_model->assignment_time($assignment_id);
     //if assignment not started the donot show any data of the assignment
     if ($this->user->level == 0 && shj_now() < strtotime($assignment['start_time'])) {
         $this->twig->display('pages/notstarted.twig', array('all_assignments' => $this->all_assignments));
         return;
     }
     $assignments_root = rtrim($this->settings_model->get_setting('assignments_root'), '/');
     $filename = "{$assignments_root}/assignment_{$assignment_id}/mcq/mcq_without_answer.json";
     if (!file_exists($filename)) {
         show_404();
     }
     $data = array('all_assignments' => $this->assignment_model->all_assignments(), 'assignment' => $assignment_id);
     $this->twig->display("pages/mcqquestion.twig", $data);
 }
Example #5
0
 /**
  * Saves submitted code and adds it to queue for judging
  */
 private function _upload()
 {
     $now = shj_now();
     foreach ($this->problems as $item) {
         if ($item['id'] == $this->input->post('problem')) {
             $this->problem = $item;
             break;
         }
     }
     $this->filetype = $this->_language_to_type(strtolower(trim($this->input->post('language'))));
     $this->ext = substr(strrchr($_FILES['userfile']['name'], '.'), 1);
     // uploaded file extension
     $this->file_name = basename($_FILES['userfile']['name'], ".{$this->ext}");
     // uploaded file name without extension
     if ($this->queue_model->in_queue($this->user->username, $this->problem['id'])) {
         show_error('You have already submitted for this problem. Your last submission is still in queue.');
     }
     if ($this->user->level == 0 && !$this->problem['open']) {
         show_error('Selected problem has been closed.');
     }
     $filetypes = explode(",", $this->problem['allowed_languages']);
     foreach ($filetypes as &$filetype) {
         $filetype = $this->_language_to_type(strtolower(trim($filetype)));
     }
     if ($_FILES['userfile']['error'] == 4) {
         show_error('No file chosen.');
     }
     if (!in_array($this->filetype, $filetypes)) {
         show_error('This file type is not allowed for this problem.');
     }
     if (!$this->_match($this->filetype, $this->ext)) {
         show_error('This file type does not match your selected language.');
     }
     if (!preg_match('/^[a-zA-Z0-9_\\-()]+$/', $this->file_name)) {
         show_error('Invalid characters in file name.');
     }
     $user_dir = rtrim($this->problem_root, '/') . '/p' . $this->problem['id'] . '/user/';
     if (!file_exists($user_dir)) {
         mkdir($user_dir, 0700);
     }
     $user_dir = rtrim($this->problem_root, '/') . '/p' . $this->problem['id'] . '/user/' . $this->user->username;
     if (!file_exists($user_dir)) {
         mkdir($user_dir, 0700);
     }
     $config['upload_path'] = $user_dir;
     $config['allowed_types'] = '*';
     $config['max_size'] = $this->settings_model->get_setting('file_size_limit');
     $config['file_name'] = $this->file_name . "-" . ($this->problem['total_submits'] + 1) . "." . $this->ext;
     $config['max_file_name'] = 20;
     $config['remove_spaces'] = TRUE;
     $this->upload->initialize($config);
     if ($this->upload->do_upload('userfile')) {
         $result = $this->upload->data();
         $this->load->model('submit_model');
         $submit_info = array('submit_id' => $this->problem_model->increase_total_submits($this->problem['id']), 'username' => $this->user->username, 'problem' => $this->problem['id'], 'file_name' => $result['raw_name'], 'main_file_name' => $this->file_name, 'file_type' => $this->filetype, 'pre_score' => 0, 'time' => shj_now_str());
         $this->probleminfo_model->update_last_submissions($this->problem['id'], $submit_info['time']);
         $this->probleminfo_model->update_total_submissions($problem_id, 1);
         if ($this->problem['is_upload_only'] == 0) {
             $this->queue_model->add_to_queue($submit_info);
             process_the_queue();
         } else {
             $this->submit_model->add_upload_only($submit_info);
         }
         return TRUE;
     }
     return FALSE;
 }
 /**
  * Used by ajax request (for selecting final submission)
  */
 public function select()
 {
     if (!$this->input->is_ajax_request()) {
         show_404();
     }
     // Students cannot change their final submission after finish_time + extra_time
     if ($this->user->level === 0) {
         if (shj_now() > strtotime($this->user->selected_assignment['finish_time']) + $this->user->selected_assignment['extra_time']) {
             $json_result = array('done' => 0, 'message' => 'This assignment is finished. You cannot change your final submissions.');
             $this->output->set_header('Content-Type: application/json; charset=utf-8');
             echo json_encode($json_result);
             return;
         }
     }
     $this->form_validation->set_rules('submit_id', 'Submit ID', 'integer|greater_than[0]');
     $this->form_validation->set_rules('problem', 'problem', 'integer|greater_than[0]');
     $this->form_validation->set_rules('username', 'Username', 'required|min_length[3]|max_length[20]|alpha_numeric');
     if ($this->form_validation->run()) {
         $username = $this->input->post('username');
         if ($this->user->level === 0) {
             $username = $this->user->username;
         }
         $res = $this->submit_model->set_final_submission($username, $this->user->selected_assignment['id'], $this->input->post('problem'), $this->input->post('submit_id'));
         if ($res) {
             // each time a user changes final submission, we should update scoreboard of that assignment
             $this->load->model('scoreboard_model');
             $this->scoreboard_model->update_scoreboard($this->user->selected_assignment['id']);
             $json_result = array('done' => 1);
         } else {
             $json_result = array('done' => 0, 'message' => 'Selecting Final Submission Failed');
         }
     } else {
         $json_result = array('done' => 0, 'message' => 'Input Error');
     }
     $this->output->set_header('Content-Type: application/json; charset=utf-8');
     echo json_encode($json_result);
 }
Example #7
0
 /**
  * Saves submitted code and adds it to queue for judging
  */
 private function _upload()
 {
     $now = shj_now();
     foreach ($this->problems as $item) {
         if ($item['id'] == $this->input->post('problem')) {
             $this->problem = $item;
             break;
         }
     }
     $this->filetype = $this->_language_to_type(strtolower(trim($this->input->post('language'))));
     $submitcode = $this->input->post("submitcode");
     $this->ext = substr(strrchr($_FILES['userfile']['name'], '.'), 1);
     // uploaded file extension
     $this->file_name = basename($_FILES['userfile']['name'], ".{$this->ext}");
     // uploaded file name without extension
     if ($this->queue_model->in_queue($this->user->username, $this->user->selected_assignment['id'], $this->problem['id'])) {
         show_error('You have already submitted for this problem. Your last submission is still in queue.');
     }
     if ($this->user->level == 0 && !$this->user->selected_assignment['open']) {
         show_error('Selected assignment has been closed.');
     }
     if ($now < strtotime($this->user->selected_assignment['start_time'])) {
         show_error('Selected assignment has not started.');
     }
     if ($now > strtotime($this->user->selected_assignment['finish_time']) + $this->user->selected_assignment['extra_time']) {
         show_error('Selected assignment has finished.');
     }
     if (!$this->assignment_model->is_participant($this->user->selected_assignment['participants'], $this->user->username)) {
         show_error('You are not registered for submitting.');
     }
     $filetypes = explode(",", $this->problem['allowed_languages']);
     foreach ($filetypes as &$filetype) {
         $filetype = $this->_language_to_type(strtolower(trim($filetype)));
     }
     $user_dir = rtrim($this->assignment_root, '/') . '/assignment_' . $this->user->selected_assignment['id'] . '/p' . $this->problem['id'] . '/' . $this->user->username;
     if (!file_exists($user_dir)) {
         mkdir($user_dir, 0700);
     }
     $done = false;
     if ($submitcode == "" || $this->filetype == 'zip' || $this->filetype == 'pdf') {
         if ($_FILES['userfile']['error'] == 4) {
             show_error('No file chosen.');
         }
         if (!in_array($this->filetype, $filetypes)) {
             show_error('This file type is not allowed for this problem.');
         }
         if (!$this->_match($this->filetype, $this->ext)) {
             show_error('This file type does not match your selected language.');
         }
         if (!preg_match('/^[a-zA-Z0-9_\\-()]+$/', $this->file_name)) {
             show_error('Invalid characters in file name.');
         }
         $config['upload_path'] = $user_dir;
         $config['allowed_types'] = '*';
         $config['max_size'] = $this->settings_model->get_setting('file_size_limit');
         $config['file_name'] = $this->file_name . "-" . ($this->user->selected_assignment['total_submits'] + 1) . "." . $this->ext;
         $config['max_file_name'] = 20;
         $config['remove_spaces'] = TRUE;
         $this->upload->initialize($config);
         if ($this->upload->do_upload('userfile')) {
             $result = $this->upload->data();
             $done = true;
         }
     } else {
         $this->load->helper('file');
         $this->ext = $this->_retext($this->filetype);
         $this->file_name = "code";
         $file_name = "code-" . ($this->user->selected_assignment['total_submits'] + 1) . "." . $this->ext;
         $upload_path = $user_dir;
         $max_size = $this->settings_model->get_setting('file_size_limit');
         $fp = fopen($upload_path . "/" . $file_name, 'w');
         //show_error($max_size);
         $wr = fwrite($fp, $submitcode, $max_size * 1024);
         if (!$wr) {
             show_error("Code is too large");
         }
         fclose($fp);
         $result['raw_name'] = "code-" . ($this->user->selected_assignment['total_submits'] + 1);
         $done = true;
     }
     if ($done) {
         $this->load->model('submit_model');
         $submit_info = array('submit_id' => $this->assignment_model->increase_total_submits($this->user->selected_assignment['id']), 'username' => $this->user->username, 'assignment' => $this->user->selected_assignment['id'], 'problem' => $this->problem['id'], 'file_name' => $result['raw_name'], 'main_file_name' => $this->file_name, 'file_type' => $this->filetype, 'coefficient' => $this->coefficient, 'pre_score' => 0, 'time' => shj_now_str());
         if ($this->problem['is_upload_only'] == 0) {
             $this->queue_model->add_to_queue($submit_info);
             process_the_queue();
         } else {
             $this->submit_model->add_upload_only($submit_info);
         }
         $val = $submit_info;
         return $val;
     }
     return FALSE;
 }
 private function _judge_mcq($assignment_id)
 {
     $res = $this->assignment_model->assignment_time($assignment_id);
     if (shj_now() < strtotime($res['finish_time']) + $res['extra_time']) {
         //assignment not yet finished
         return FALSE;
     } else {
         return TRUE;
     }
 }
 public function images($assignment_id = NULL, $imagename = NULL)
 {
     $assignments_root = rtrim($this->settings_model->get_setting('assignments_root'), '/');
     $filename = "{$assignments_root}/assignment_{$assignment_id}/images/{$imagename}";
     $assignment = $this->assignment_model->assignment_info($assignment_id);
     if ($this->user->level == 0 && shj_now() < strtotime($assignment['start_time'])) {
         show_404();
     }
     if (file_exists($filename)) {
         header('Content-Length: ' . filesize($filename));
         //<-- sends filesize header
         $mime = $this->_getmime(pathinfo($filename, PATHINFO_EXTENSION));
         header("Content-Type: {$mime}");
         //<-- send mime-type header
         header('Content-Disposition: inline; filename="' . $filename . '";');
         //<-- sends filename header
         readfile($filename);
         //<--reads and outputs the file onto the output buffer
         die;
         //<--cleanup
         exit;
         //and exit
     } else {
         show_404();
     }
 }
Example #10
0
 /**
  * The function is polled for new updates aboud the assignment.
  * @return boolean [description]
  */
 public function is_update()
 {
     if (!$this->input->is_ajax_request()) {
         show_404();
     }
     $assignment_id = $this->input->post('assignment');
     if ($assignment_id == 0) {
         show_404();
     }
     $assignments_root = rtrim($this->settings_model->get_setting('assignments_root'), '/');
     $assignment_info = $this->assignment_model->assignment_time($assignment_id);
     if (shj_now() > strtotime($assignment_info['finish_time']) + $assignment_info['extra_time']) {
         exit("Assignment Finished");
     }
     $filename = "{$assignments_root}/assignment_{$assignment_id}/mcq/mcq_without_answer.json";
     exit(date("Y m d H:i:s", filemtime($filename)));
 }
 public function is_public($assignment_id)
 {
     $assignment = $this->assignment_time($assignment_id);
     return $assignment['public'] && shj_now() > strtotime($assignment['finish_time']) + $assignment['extra_time'];
 }
Example #12
0
 /**
  * Password Reset Key Is Valid
  *
  * Returns TRUE if the given password reset key is valid
  * And returns an error message if key is invalid
  *
  * @param $passchange_key
  * @return bool|string
  */
 public function passchange_is_valid($passchange_key)
 {
     $query = $this->db->select('passchange_time')->get_where('users', array('passchange_key' => $passchange_key));
     if ($query->num_rows() != 1) {
         return 'Invalid password reset link.';
     }
     $time = strtotime($query->row()->passchange_time);
     $now = shj_now();
     if ($now - $time > 3600 or $now - $time < 0) {
         // reset link is valid for 1 hour
         return 'The link is expired.';
     }
     return TRUE;
 }