# HG changeset patch # User Nattee Niparnan # Date 2018-03-12 06:36:08 # Node ID f26733606a767767e0fa000f994518af84b371f2 # Parent 55afb135c5f9c62a6844998e319fba5b125c4a9a # Parent 757ebc0ccd63c64ecdfd3e322949693ba8ef8984 merge diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -97,7 +97,7 @@ prepare_list_information render :action => 'list' and return end - redirect_to :action => 'list' + redirect_to edit_submission_path(@submission) end def source diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -165,7 +165,7 @@ redirect_to :controller => 'main', :action => 'list' return end - @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id) + @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id) #stat summary range =65 @@ -209,6 +209,10 @@ end flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0 flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0 + elsif params.has_key? 'add_tags' + get_problems_from_params.each do |p| + p.tag_ids += params[:tag_ids] + end end redirect_to :action => 'manage' @@ -300,7 +304,7 @@ private def problem_params - params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description) + params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description, tag_ids:[]) end end diff --git a/app/controllers/report_controller.rb b/app/controllers/report_controller.rb --- a/app/controllers/report_controller.rb +++ b/app/controllers/report_controller.rb @@ -52,6 +52,8 @@ #set up range from param @since_id = params.fetch(:from_id, 0).to_i @until_id = params.fetch(:to_id, 0).to_i + @since_id = nil if @since_id == 0 + @until_id = nil if @until_id == 0 #calculate the routine @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -41,6 +41,8 @@ # DELETE /tags/1 def destroy + #remove any association + ProblemTag.where(tag_id: @tag.id).destroy_all @tag.destroy redirect_to tags_url, notice: 'Tag was successfully destroyed.' end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -85,11 +85,10 @@ end def format_short_time(time) - now = Time.now.gmtime + now = Time.zone.now st = '' - if (time.yday != now.yday) or - (time.year != now.year) - st = time.strftime("%x ") + if (time.yday != now.yday) or (time.year != now.year) + st = time.strftime("%d/%m/%y ") end st + time.strftime("%X") end @@ -100,6 +99,10 @@ return Time.at(d).gmtime.strftime("%X") end + def format_full_time_ago(time) + st = time_ago_in_words(time) + ' ago (' + format_short_time(time) + ')' + end + def read_textfile(fname,max_size=2048) begin File.open(fname).read(max_size) diff --git a/app/models/submission.rb b/app/models/submission.rb --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -34,8 +34,8 @@ def self.find_in_range_by_user_and_problem(user_id, problem_id,since_id,until_id) records = Submission.where(problem_id: problem_id,user_id: user_id) - records = records.where('id >= ?',since_id) if since_id > 0 - records = records.where('id <= ?',until_id) if until_id > 0 + records = records.where('id >= ?',since_id) if since_id and since_id > 0 + records = records.where('id <= ?',until_id) if until_id and until_id > 0 records.all end diff --git a/app/views/application/_submission_short.html.haml b/app/views/application/_submission_short.html.haml --- a/app/views/application/_submission_short.html.haml +++ b/app/views/application/_submission_short.html.haml @@ -1,13 +1,15 @@ - - if submission.nil? = "-" - else + %strong= "Submission ID:" + = submission.id + %br - unless submission.graded_at - = t 'main.submitted_at' - = format_short_time(submission.submitted_at.localtime) + %strong= t 'main.submitted_at:' + = format_full_time_ago(submission.submitted_at.localtime) - else - %strong= t 'main.graded_at' - = "#{format_short_time(submission.graded_at.localtime)} " + %strong= t 'main.graded_at:' + = format_full_time_ago(submission.graded_at.localtime) %br - if GraderConfiguration['ui.show_score'] %strong=t 'main.score' @@ -17,10 +19,10 @@ = submission.grader_comment = "]" %br - %strong View: - - if GraderConfiguration.show_grading_result - = link_to '[detailed result]', :action => 'result', :id => submission.id - = link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'} + %strong View: + - if GraderConfiguration.show_grading_result + = link_to '[detailed result]', :action => 'result', :id => submission.id + = link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'} if submission.graded_at = link_to "#{t 'main.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info' = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info' diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -46,6 +46,7 @@ %ul.dropdown-menu = add_menu( 'Announcements', 'announcements', 'index') = add_menu( 'Problems', 'problems', 'index') + = add_menu( 'Tags', 'tags', 'index') = add_menu( 'Users', 'user_admin', 'index') = add_menu( 'User Groups', 'groups', 'index') = add_menu( 'Graders', 'graders', 'list') diff --git a/app/views/problems/_form.html.haml b/app/views/problems/_form.html.haml --- a/app/views/problems/_form.html.haml +++ b/app/views/problems/_form.html.haml @@ -12,6 +12,9 @@ %label{:for => "problem_full_score"} Full score = text_field 'problem', 'full_score', class: 'form-control' .form-group + %label{:for => "problem_full_score"} Tags + = collection_select(:problem, :tag_ids, Tag.all, :id, :name, {}, {multiple: true, class: 'form-control select2'}) +.form-group %label{:for => "problem_date_added"} Date added = date_select 'problem', 'date_added', class: 'form-control' - # TODO: these should be put in model Problem, but I can't think of diff --git a/app/views/problems/index.html.haml b/app/views/problems/index.html.haml --- a/app/views/problems/index.html.haml +++ b/app/views/problems/index.html.haml @@ -21,6 +21,7 @@ %th Name %th Full name %th.text-right Full score + %th Tags %th Submit %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Admin can always submit to any problem' } [?] @@ -44,6 +45,10 @@ = problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1 = link_to_description_if_any "[#{t 'main.problem_desc'}] ".html_safe, problem %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1 + %td + - problem.tags.each do |t| + - #%button.btn.btn-default.btn-xs= t.name + %span.label.label-default= t.name %td= link_to "Submit", direct_edit_problem_submissions_path(problem,@current_user.id), class: 'btn btn-xs btn-primary' %td= problem.date_added %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}") diff --git a/app/views/problems/manage.html.haml b/app/views/problems/manage.html.haml --- a/app/views/problems/manage.html.haml +++ b/app/views/problems/manage.html.haml @@ -49,7 +49,7 @@ (You can shift-click to select a range of problems) %ul.form-inline %li - Change date added to + Change "Date added" to .input-group.date = text_field_tag :date_added, class: 'form-control' %span.input-group-addon @@ -58,44 +58,53 @@     = submit_tag 'Change', :name => 'change_date_added', class: 'btn btn-primary btn-sm' %li - Set available to + Set "Available" to = submit_tag 'True', :name => 'enable_problem', class: 'btn btn-primary btn-sm' = submit_tag 'False', :name => 'disable_problem', class: 'btn btn-primary btn-sm' - if GraderConfiguration.multicontests? %li - Add to + Add selected problems to contest = select("contest","id",Contest.all.collect {|c| [c.title, c.id]}) = submit_tag 'Add', :name => 'add_to_contest', class: 'btn btn-primary btn-sm' %li - Add problems to group + Add selected problems to user group = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2' - = submit_tag 'Add', name: 'add_group', class: 'btn btn-default' - + = submit_tag 'Add', name: 'add_group', class: 'btn btn-primary' + %li + Add the following tags to the selected problems + = select_tag "tag_ids", options_from_collection_for_select( Tag.all, 'id','name'), id: 'tags_name',class: 'select2', multiple: true, data: {placeholder: 'Select tags by clicking', width: "200px"} + = submit_tag 'Add', name: 'add_tags', class: 'btn btn-primary' - %table.table.table-hover - %tr{style: "text-align: left;"} - %th= check_box_tag 'select_all' - %th Name - %th Full name - %th Available - %th Date added - - if GraderConfiguration.multicontests? - %th Contests + %table.table.table-hover.datatable + %thead + %tr{style: "text-align: left;"} + %th= check_box_tag 'select_all' + %th Name + %th Full name + %th Tags + %th Available + %th Date added + - if GraderConfiguration.multicontests? + %th Contests - - num = 0 - - for problem in @problems - - num += 1 - %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"} - %td= check_box_tag "prob-#{problem.id}-#{num}" - %td= problem.name - %td= problem.full_name - %td= problem.available - %td= problem.date_added - - if GraderConfiguration.multicontests? + %tbody + - num = 0 + - for problem in @problems + - num += 1 + %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"} + %td= check_box_tag "prob-#{problem.id}-#{num}" + %td= problem.name + %td= problem.full_name %td - - problem.contests.each do |contest| - = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])" + - problem.tags.each do |t| + %span.label.label-default= t.name + %td= problem.available + %td= problem.date_added + - if GraderConfiguration.multicontests? + %td + - problem.contests.each do |contest| + = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])" :javascript $('.input-group.date').datetimepicker({ @@ -104,4 +113,6 @@ widgetPositioning: {horizontal: 'auto', vertical: 'bottom'}, }); - + $('.datatable').DataTable({ + paging: false + }); diff --git a/app/views/problems/stat.html.haml b/app/views/problems/stat.html.haml --- a/app/views/problems/stat.html.haml +++ b/app/views/problems/stat.html.haml @@ -32,6 +32,7 @@ %th Login %th Name %th Submitted_at + %th language %th Points %th comment %th IP @@ -45,6 +46,7 @@ %td= link_to sub.user.login, stat_user_path(sub.user) %td= sub.user.full_name %td{data: {order: sub.submitted_at}}= time_ago_in_words(sub.submitted_at) + " ago" + %td= sub.language.name %td= sub.points %td.fix-width= sub.grader_comment %td= sub.ip_address diff --git a/app/views/report/_score_table.html.haml b/app/views/report/_score_table.html.haml --- a/app/views/report/_score_table.html.haml +++ b/app/views/report/_score_table.html.haml @@ -12,6 +12,9 @@ %th.text-right Total %th.text-right Passed %tbody + - sum = Array.new(@scorearray[0].count,0) + - nonzero = Array.new(@scorearray[0].count,0) + - full = Array.new(@scorearray[0].count,0) - @scorearray.each do |sc| %tr - total,num_passed = 0,0 @@ -27,8 +30,40 @@ %td.text-right= sc[i][0] - total += sc[i][0] - num_passed += 1 if sc[i][1] + - sum[i] += sc[i][0] + - nonzero[i] += 1 if sc[i][0] > 0 + - full[i] += 1 if sc[i][1] %td.text-right= total %td.text-right= num_passed + %tfoot + %tr + %td Summation + %td + %td + - sum.each.with_index do |s,i| + - next if i == 0 + %td.text-right= number_with_delimiter(s) + %td + %td + %tr + %td partial solver + %td + %td + - nonzero.each.with_index do |s,i| + - next if i == 0 + %td.text-right= number_with_delimiter(s) + %td + %td + %tr + %td Full solver + %td + %td + - full.each.with_index do |s,i| + - next if i == 0 + %td.text-right= number_with_delimiter(s) + %td + %td + :javascript $.bootstrapSortable(true,'reversed') diff --git a/app/views/report/max_score.html.haml b/app/views/report/max_score.html.haml --- a/app/views/report/max_score.html.haml +++ b/app/views/report/max_score.html.haml @@ -33,11 +33,11 @@ .panel-body .radio %label - = radio_button_tag 'users', 'all', true + = radio_button_tag 'users', 'all', (params[:users] == "all") All users .radio %label - = radio_button_tag 'users', 'enabled' + = radio_button_tag 'users', 'enabled', (params[:users] == "enabled") Only enabled users .row .col-md-12 diff --git a/app/views/sites/edit.html.haml b/app/views/sites/edit.html.haml --- a/app/views/sites/edit.html.haml +++ b/app/views/sites/edit.html.haml @@ -31,5 +31,6 @@ :javascript $('.input-group.date').datetimepicker({ format: 'DD/MMM/YYYY HH:mm', + showTodayButton: true, }); diff --git a/app/views/submissions/edit.html.haml b/app/views/submissions/edit.html.haml --- a/app/views/submissions/edit.html.haml +++ b/app/views/submissions/edit.html.haml @@ -27,14 +27,15 @@ = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit', data: {confirm: "Submitting this source code for task #{@problem.long_name}?"} - # latest submission status - .panel.panel-info + .panel{class: (@submission && @submission.graded_at) ? "panel-info" : "panel-warning"} .panel-heading Latest Submission Status = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission .panel-body - - if @submission - = render :partial => 'submission_short', - :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id } + %div#latest_status + - if @submission + = render :partial => 'submission_short', + :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id } .row .col-md-12 %h2 Console diff --git a/app/views/submissions/get_latest_submission_status.js.haml b/app/views/submissions/get_latest_submission_status.js.haml --- a/app/views/submissions/get_latest_submission_status.js.haml +++ b/app/views/submissions/get_latest_submission_status.js.haml @@ -1,2 +1,2 @@ :plain - $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name}})}") + $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name, problem_id: @problem.id}})}") diff --git a/config/application.rb.SAMPLE b/config/application.rb.SAMPLE --- a/config/application.rb.SAMPLE +++ b/config/application.rb.SAMPLE @@ -65,7 +65,7 @@ config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] %w( announcements submissions configurations contests contest_management graders heartbeat login main messages problems report site sites sources tasks - test user_admin users ).each do |controller| + test user_admin users testcases).each do |controller| config.assets.precompile += ["#{controller}.js", "#{controller}.css"] end end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -18,6 +18,6 @@ Rails.application.config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css'] %w( announcements submissions configurations contests contest_management graders heartbeat login main messages problems report site sites sources tasks groups - test user_admin users tags).each do |controller| + test user_admin users tags testcases).each do |controller| Rails.application.config.assets.precompile += ["#{controller}.js", "#{controller}.css"] end diff --git a/lib/grader_script.rb b/lib/grader_script.rb --- a/lib/grader_script.rb +++ b/lib/grader_script.rb @@ -33,6 +33,7 @@ GraderScript.call_grader "#{env} test_request -err-log &" end + #call the import problem script def self.call_import_problem(problem_name, problem_dir, time_limit=1, diff --git a/lib/testdata_importer.rb b/lib/testdata_importer.rb --- a/lib/testdata_importer.rb +++ b/lib/testdata_importer.rb @@ -8,8 +8,9 @@ @problem = problem end - def import_from_file(tempfile, - time_limit, + #Create or update problem according to the parameter + def import_from_file(tempfile, + time_limit, memory_limit, checker_name='text', import_to_db=false) @@ -52,6 +53,7 @@ return filename.slice(i..len) end + # extract an archive file located at +tempfile+ to the +raw_dir+ def extract(tempfile) testdata_filename = save_testdata_file(tempfile) ext = TestdataImporter.long_ext(tempfile.original_filename)