Description:
merge bootstrap back to algo
Commit status:
[Not Reviewed]
References:
merge algo
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r704:4afa0e9c66d2 - - 103 files changed: 1590 inserted, 681 deleted

@@ -0,0 +1,6
1 + #js for announcement
2 + $ ->
3 + $(document).ajaxError (event, jqxhr, settings, exception) ->
4 + if jqxhr.status
5 + alert 'We\'re sorry, but something went wrong (' + jqxhr.status + ')'
6 + return
new file 100644
new file 100644
new file 100644
@@ -0,0 +1,52
1 + $(document).on 'change', '.btn-file :file', ->
2 + input = $(this)
3 + numFiles = if input.get(0).files then input.get(0).files.length else 1
4 + label = input.val().replace(/\\/g, '/').replace(/.*\//, '')
5 + input.trigger 'fileselect', [
6 + numFiles
7 + label
8 + ]
9 + return
10 +
11 +
12 + # document ready
13 +
14 + $ ->
15 + $(".select2").select2()
16 + #$(".bootstrap-switch").bootstrapSwitch()
17 + #$(".bootstrap-toggle").bootstrapToggle()
18 + $('.btn-file :file').on 'fileselect', (event, numFiles, label) ->
19 + input = $(this).parents('.input-group').find(':text')
20 + log = if numFiles > 1 then numFiles + ' files selected' else label
21 + if input.length
22 + input.val log
23 + else
24 + if log
25 + alert log
26 + return
27 + $(".go-button").on 'click', (event) ->
28 + link = $(this).attr("data-source")
29 + url = $(link).val()
30 + if url
31 + window.location.href = url
32 + return
33 + $('.ajax-toggle').on 'click', (event) ->
34 + target = $(event.target)
35 + target.removeClass 'btn-default'
36 + target.removeClass 'btn-success'
37 + target.addClass 'btn-warning'
38 + target.text '...'
39 + return
40 +
41 +
42 + #ace editor
43 + if $("#editor").length > 0
44 + e = ace.edit("editor")
45 + e.setTheme('ace/theme/merbivore')
46 + e.getSession().setTabSize(2)
47 + e.getSession().setUseSoftTabs(true)
48 +
49 + #best in place
50 + jQuery(".best_in_place").best_in_place()
51 +
52 + return
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
@@ -0,0 +1,32
1 + # Place all the behaviors and hooks related to the matching controller here.
2 + # All this logic will automatically be available in application.js.
3 + # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
4 +
5 +
6 + $ ->
7 + $("#live_submit").on "click", (event) ->
8 + h = $("#editor_text")
9 + e = ace.edit("editor")
10 + h.val(e.getValue())
11 +
12 + $("#language_id").on "change", (event) ->
13 + text = $("#language_id option:selected").text()
14 + mode = 'ace/mode/c_cpp'
15 + switch text
16 + when 'Pascal' then mode = 'ace/mode/pascal'
17 + when 'C++','C' then mode = 'ace/mode/c_cpp'
18 + when 'Ruby' then mode = 'ace/mode/ruby'
19 + when 'Python' then mode = 'ace/mode/python'
20 + when 'Java' then mode = 'ace/mode/java'
21 + editor = ace.edit('editor')
22 + editor.getSession().setMode(mode)
23 +
24 + e = ace.edit("editor")
25 + e.setValue($("#text_haha").val())
26 + e.gotoLine(1)
27 + $("#language_id").trigger('change')
28 +
29 +
30 +
31 +
32 + return
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
new file 100644
@@ -0,0 +1,4
1 + // Place all the styles related to the sources controller here.
2 + // They will automatically be included in application.css.
3 + // You can use Sass (SCSS) here: http://sass-lang.com/
4 +
new file 100644
new file 100644
new file 100644
new file 100644
@@ -0,0 +1,27
1 + class SourcesController < ApplicationController
2 + before_filter :authenticate
3 +
4 + def direct_edit
5 + @problem = Problem.find(params[:pid])
6 + @source = ''
7 + end
8 +
9 + def direct_edit_submission
10 + @submission = Submission.find(params[:sid])
11 + @source = @submission.source.to_s
12 + @problem = @submission.problem
13 + @lang_id = @submission.language.id
14 + render 'direct_edit'
15 + end
16 +
17 + def get_latest_submission_status
18 + @problem = Problem.find(params[:pid])
19 + @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
20 + puts User.find(params[:uid]).login
21 + puts Problem.find(params[:pid]).name
22 + puts 'nil' unless @submission
23 + respond_to do |format|
24 + format.js
25 + end
26 + end
27 + end
@@ -0,0 +1,2
1 + module SourcesHelper
2 + end
@@ -0,0 +1,37
1 + %h1 Listing announcements
2 +
3 + = link_to '+ Add announcement', new_announcement_path, class: 'btn btn-success'
4 + %br
5 + %br
6 +
7 + %table.table.table-striped
8 + %thead
9 + %th Updated
10 + %th Announcement
11 + %th Author
12 + %th{style: 'width: 100px'} Published?
13 + %th{style: 'width: 100px'}Front?
14 + %th
15 + %th
16 + - for announcement in @announcements
17 + %tr
18 + - @announcement = announcement
19 + %td= time_ago_in_words announcement.updated_at
20 + %td
21 + - if !announcement.title.blank?
22 + %b Title:
23 + = h announcement.title
24 + %br/
25 + - if !announcement.notes.blank?
26 + %b
27 + Notes: #{h announcement.notes}
28 + %br/
29 + = h announcement.body
30 + %td= h announcement.author
31 + %td= toggle_button(announcement.published?, toggle_announcement_url(@announcement), "announcement_toggle_#{@announcement.id}", {size: 'btn-sm'})
32 + %td= toggle_button(announcement.frontpage?, toggle_front_announcement_url(@announcement), "announcement_toggle_front_#{@announcement.id}", {size: 'btn-sm'})
33 + %td= link_to 'Edit', edit_announcement_path(announcement), class: 'btn btn-block btn-sm btn-info'
34 + %td= link_to 'Destroy', announcement, :confirm => 'Are you sure?', :method => :delete, class: "btn btn-block btn-sm btn-danger"
35 + %br
36 +
37 + = link_to '+ Add announcement', new_announcement_path, class: 'btn btn-success'
@@ -0,0 +1,26
1 +
2 + - if submission.nil?
3 + = "-"
4 + - else
5 + - if submission.graded_at.nil?
6 + =t 'main.submitted_at'
7 + = format_short_time(submission.submitted_at.localtime)
8 + - else
9 + = t 'main.graded_at'
10 + = "#{format_short_time(submission.graded_at.localtime)}, "
11 + - if GraderConfiguration['ui.show_score']
12 + = t 'main.score'
13 + = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 + = " ["
15 + %tt
16 + = submission.grader_comment
17 + = "]"
18 + - if GraderConfiguration.show_grading_result
19 + = " | "
20 + = link_to '[detailed result]', :action => 'result', :id => submission.id
21 + = " | "
22 + = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
23 + = " | "
24 + = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
25 + //= " | "
26 + //= link_to "[#{t 'main.submissions_link'}]", main_submission_path(submission.problem.id)
@@ -0,0 +1,7
1 + :plain
2 + var t = $("#{button_id}");
3 + t.removeClass('btn-default');
4 + t.removeClass('btn-success');
5 + t.removeClass('btn-warning');
6 + t.addClass("btn-#{button_on ? 'success' : 'default'}");
7 + t.text("#{button_on ? 'Yes' : 'No'}");
@@ -0,0 +1,84
1 + %header.navbar.navbar-default.navbar-fixed-top
2 + %nav
3 + .container-fluid
4 + .navbar-header
5 + %a.navbar-brand{href: main_list_path}
6 + %span.glyphicon.glyphicon-home
7 + MAIN
8 + .collapse.navbar-collapse
9 + %ul.nav.navbar-nav
10 + - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
11 + //= add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
12 + %li.dropdown
13 + %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
14 + = "#{I18n.t 'menu.submissions'}"
15 + %span.caret
16 + %ul.dropdown-menu
17 + = add_menu("View", 'main', 'submission')
18 + = add_menu("Self Test", 'test', 'index')
19 + - if GraderConfiguration['right.user_hall_of_fame']
20 + = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
21 + / display MODE button (with countdown in contest mode)
22 + - if GraderConfiguration.analysis_mode?
23 + %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
24 + - elsif GraderConfiguration.time_limit_mode?
25 + - if @current_user.contest_finished?
26 + %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
27 + - elsif !@current_user.contest_started?
28 + %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
29 + - else
30 + %div.navbar-btn.btn.btn-primary#countdown asdf
31 + :javascript
32 + $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
33 + / admin section
34 + - if (@current_user!=nil) and (session[:admin])
35 + %li.dropdown
36 + %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
37 + Manage
38 + %span.caret
39 + %ul.dropdown-menu
40 + = add_menu( 'Announcements', 'announcements', 'index')
41 + = add_menu( 'Problems', 'problems', 'index')
42 + = add_menu( 'Users', 'user_admin', 'index')
43 + = add_menu( 'Graders', 'graders', 'list')
44 + = add_menu( 'Message ', 'messages', 'console')
45 + %li.divider{role: 'separator'}
46 + = add_menu( 'System config', 'configurations', 'index')
47 + %li.divider{role: 'separator'}
48 + = add_menu( 'Sites', 'sites', 'index')
49 + = add_menu( 'Contests', 'contest_management', 'index')
50 + %li.dropdown
51 + %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
52 + Report
53 + %span.caret
54 + %ul.dropdown-menu
55 + = add_menu( 'Results', 'user_admin', 'user_stat')
56 + = add_menu( 'Report', 'report', 'multiple_login')
57 + - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
58 + =link_to "#{ungraded} backlogs!",
59 + grader_list_path,
60 + class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
61 +
62 + %ul.nav.navbar-nav.navbar-right
63 + = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
64 + = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
65 + - if GraderConfiguration['system.user_setting_enabled']
66 + = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
67 + = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
68 +
69 + /
70 + - if (@current_user!=nil) and (session[:admin])
71 + %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
72 + .container-fluid
73 + .collapse.navbar-collapse
74 + %ul.nav.navbar-nav
75 + = add_menu( '[Announcements]', 'announcements', 'index')
76 + = add_menu( '[Msg console]', 'messages', 'console')
77 + = add_menu( '[Problems]', 'problems', 'index')
78 + = add_menu( '[Users]', 'user_admin', 'index')
79 + = add_menu( '[Results]', 'user_admin', 'user_stat')
80 + = add_menu( '[Report]', 'report', 'multiple_login')
81 + = add_menu( '[Graders]', 'graders', 'list')
82 + = add_menu( '[Contests]', 'contest_management', 'index')
83 + = add_menu( '[Sites]', 'sites', 'index')
84 + = add_menu( '[System config]', 'configurations', 'index')
@@ -0,0 +1,15
1 + <!DOCTYPE html>
2 + %html
3 + %head
4 + %title= GraderConfiguration['contest.name']
5 + = stylesheet_link_tag "application", params[:controller], :media => "all"
6 + = javascript_include_tag "application", params[:controller]
7 + = csrf_meta_tags
8 + = content_for :header
9 + = yield :head
10 +
11 + %body
12 + = render 'layouts/header'
13 +
14 + = content_tag(:p,flash[:notice],class: 'alert alert-success') if flash[:notice]!=nil
15 + = yield
@@ -0,0 +1,17
1 + %tr
2 + %td
3 + = "#{problem.name}"
4 + %td
5 + = "#{problem.full_name}"
6 + = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, problem
7 + %td
8 + = @prob_submissions[problem.id][:count]
9 + = link_to "[subs]", main_submission_path(problem.id)
10 + %td
11 + = render :partial => 'submission_short',
12 + :locals => {:submission => @prob_submissions[problem.id][:submission], :problem_name => problem.name }
13 + %td
14 + - if @prob_submissions[problem.id][:submission]
15 + = link_to 'Edit', direct_edit_submission_path(@prob_submissions[problem.id][:submission]), class: 'btn btn-success'
16 + - else
17 + = link_to 'New', direct_edit_path(problem.id), class: 'btn btn-success'
@@ -0,0 +1,20
1 + = form_tag({:action => 'submit'}, :multipart => true, class: 'form') do
2 + - if @submission and @submission.errors.any?
3 + #error_explanation
4 + .alert.alert-danger
5 + %h3= "#{pluralize(@submission.errors.count, "error")} prohibited this user from being saved:"
6 + %ul
7 + - @submission.errors.full_messages.each do |msg|
8 + %li= msg
9 + .form-group
10 + = label_tag :submission, 'Problem:'
11 + = select 'submission', 'problem_id', [[(t 'main.specified_in_header'),'-1']] + @problems.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]}, {:selected => '-1'}, { class: 'select2 form-control' }
12 + .form-group
13 + = label_tag :file, 'File:'
14 + .input-group
15 + %span.input-group-btn
16 + %span.btn.btn-default.btn-file
17 + Browse
18 + = file_field_tag 'file'
19 + = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
20 + = submit_tag 'Submit', class: 'btn btn-default'
@@ -0,0 +1,50
1 + - content_for :head do
2 + = stylesheet_link_tag 'problems'
3 + %h1 Listing problems
4 + %p
5 + = link_to 'New problem', new_problem_path, class: 'btn btn-default btn-sm'
6 + = link_to 'Manage problems', { action: 'manage'}, class: 'btn btn-default btn-sm'
7 + = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-default btn-sm'
8 + = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
9 + = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
10 + .submitbox
11 + = form_tag :action => 'quick_create' do
12 + %b Quick New:
13 + %label{:for => "problem_name"} Name
14 + = text_field 'problem', 'name'
15 + |
16 + %label{:for => "problem_full_name"} Full name
17 + = text_field 'problem', 'full_name'
18 + = submit_tag "Create"
19 + %table.table.table-condense.table-hover
20 + %thead
21 + %th Name
22 + %th Full name
23 + %th.text-right Full score
24 + %th Date added
25 + %th.text-center
26 + Avail?
27 + %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
28 + %th.text-center
29 + Test?
30 + %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
31 + - if GraderConfiguration.multicontests?
32 + %th Contests
33 + - for problem in @problems
34 + %tr{:class => "#{(problem.available) ? "success" : "danger"}", :id => "prob-#{problem.id}", :name => "prob-#{problem.id}"}
35 + - @problem=problem
36 + %td= in_place_editor_field :problem, :name, {}, :rows=>1
37 + %td= in_place_editor_field :problem, :full_name, {}, :rows=>1
38 + %td.text-right= in_place_editor_field :problem, :full_score, {}, :rows=>1
39 + %td= problem.date_added
40 + %td= toggle_button(@problem.available?, toggle_problem_url(@problem), "problem-avail-#{@problem.id}")
41 + %td= toggle_button(@problem.test_allowed?, toggle_test_problem_url(@problem), "problem-test-#{@problem.id}")
42 + - if GraderConfiguration.multicontests?
43 + %td
44 + = problem.contests.collect { |c| c.name }.join(', ')
45 + %td= link_to 'Stat', {:action => 'stat', :id => problem.id}, class: 'btn btn-info btn-xs btn-block'
46 + %td= link_to 'Show', {:action => 'show', :id => problem}, class: 'btn btn-info btn-xs btn-block'
47 + %td= link_to 'Edit', {:action => 'edit', :id => problem}, class: 'btn btn-info btn-xs btn-block'
48 + %td= link_to 'Destroy', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :post, class: 'btn btn-danger btn-xs btn-block'
49 + %br/
50 + = link_to '[New problem]', :action => 'new'
@@ -0,0 +1,8
1 + = render partial: 'toggle_button',
2 + locals: {button_id: "#problem-avail-#{@problem.id}",button_on: @problem.available }
3 + :plain
4 + r = $("#prob-#{@problem.id}");
5 + r.removeClass('success');
6 + r.removeClass('danger');
7 + r.addClass("#{@problem.available? ? 'success' : 'danger'}");
8 +
@@ -0,0 +1,2
1 + = render partial: 'toggle_button',
2 + locals: {button_id: "#problem-test-#{@problem.id}",button_on: @problem.test_allowed?}
@@ -0,0 +1,24
1 + %h1 Editing site
2 + = error_messages_for :site
3 + = form_for(@site) do |f|
4 + %p
5 + %b Name
6 + %br/
7 + = f.text_field :name
8 + %p
9 + %b Password
10 + %br/
11 + = f.text_field :password
12 + %p
13 + %b Started
14 + %br/
15 + = f.check_box :started
16 + %p
17 + %b Start time
18 + %br/
19 + = f.datetime_select :start_time, :include_blank => true
20 + %p
21 + = f.submit "Update"
22 + = link_to 'Show', @site
23 + |
24 + = link_to 'Back', sites_path
@@ -0,0 +1,24
1 + %h1 Listing sites
2 + %table.table.table-striped
3 + %tr
4 + %th Name
5 + %th Password
6 + %th Started
7 + %th Start time
8 + %th
9 + %th
10 + %th
11 + - for site in @sites
12 + - background = "white"
13 + - background = "grey" if (site.started==true) and (site.finished? == true)
14 + - background = "lightgreen" if (site.started==true) and (site.finished? != true)
15 + %tr{:style => "background: #{background};"}
16 + %td= h site.name
17 + %td= h site.password
18 + %td= h site.started
19 + %td= h site.start_time
20 + %td= link_to 'Show', site, class: 'btn btn-default'
21 + %td= link_to 'Edit', edit_site_path(site), class: 'btn btn-default'
22 + %td= link_to 'Destroy', site, :confirm => 'Are you sure?', :method => :delete, class: 'btn btn-default'
23 + %br/
24 + = link_to '+ New site', new_site_path, class: 'btn btn-success'
@@ -0,0 +1,22
1 + %h1 New site
2 + = error_messages_for :site
3 + = form_for(@site) do |f|
4 + %p
5 + %b Name
6 + %br/
7 + = f.text_field :name
8 + %p
9 + %b Password
10 + %br/
11 + = f.text_field :password
12 + %p
13 + %b Started
14 + %br/
15 + = f.check_box :started
16 + %p
17 + %b Start time
18 + %br/
19 + = f.datetime_select :start_time
20 + %p
21 + = f.submit "Create"
22 + = link_to 'Back', sites_path
@@ -0,0 +1,15
1 + %p
2 + %b Name:
3 + = h @site.name
4 + %p
5 + %b Password:
6 + = h @site.password
7 + %p
8 + %b Started:
9 + = h @site.started
10 + %p
11 + %b Start time:
12 + = h @site.start_time
13 + = link_to 'Edit', edit_site_path(@site)
14 + |
15 + = link_to 'Back', sites_path
@@ -0,0 +1,264
1 + %h2 Live submit
2 + %br
3 +
4 + %textarea#text_haha{style: "display:none"}~ @source
5 + .container
6 + .row
7 + .col-md-12
8 + .alert.alert-info
9 + Write your code in the following box, choose language, and click submit button when finished
10 + .row
11 + .col-md-8
12 + %div#editor{style: 'height: 500px; border-radius: 7px; font-size: 14px;'}
13 + .col-md-4
14 + = form_tag({controller: :main, :action => 'submit'}, :multipart => true, class: 'form') do
15 +
16 + = hidden_field_tag 'editor_text', @source
17 + = hidden_field_tag 'submission[problem_id]', @problem.id
18 + .form-group
19 + = label_tag "Task:"
20 + = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true
21 +
22 + .form-group
23 + = label_tag 'Language'
24 + = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px"
25 + .form-group
26 + = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit',
27 + data: {confirm: "Submitting this source code for task #{@problem.long_name}?"}
28 + .panel.panel-info
29 + .panel-heading
30 + Latest Submission Status
31 + .panel-body
32 + - if @submission
33 + = render :partial => 'submission_short',
34 + :locals => {:submission => @submission, :problem_name => @problem.name }
35 + .row
36 + .col-md-12
37 + %h2 Console
38 + %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20}
39 +
40 + :javascript
41 + $(document).ready(function() {
42 + brython();
43 + });
44 +
45 +
46 + %script#__main__{type:'text/python3'}
47 + :plain
48 + import sys
49 + import traceback
50 +
51 + from browser import document as doc
52 + from browser import window, alert, console
53 +
54 + _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
55 + for supporting Python development. See www.python.org for more information."""
56 +
57 + _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
58 + All Rights Reserved.
59 +
60 + Copyright (c) 2001-2013 Python Software Foundation.
61 + All Rights Reserved.
62 +
63 + Copyright (c) 2000 BeOpen.com.
64 + All Rights Reserved.
65 +
66 + Copyright (c) 1995-2001 Corporation for National Research Initiatives.
67 + All Rights Reserved.
68 +
69 + Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
70 + All Rights Reserved."""
71 +
72 + _license = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
73 + All rights reserved.
74 +
75 + Redistribution and use in source and binary forms, with or without
76 + modification, are permitted provided that the following conditions are met:
77 +
78 + Redistributions of source code must retain the above copyright notice, this
79 + list of conditions and the following disclaimer. Redistributions in binary
80 + form must reproduce the above copyright notice, this list of conditions and
81 + the following disclaimer in the documentation and/or other materials provided
82 + with the distribution.
83 + Neither the name of the <ORGANIZATION> nor the names of its contributors may
84 + be used to endorse or promote products derived from this software without
85 + specific prior written permission.
86 +
87 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
88 + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
89 + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
90 + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
91 + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
92 + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
93 + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
94 + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
95 + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
96 + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
97 + POSSIBILITY OF SUCH DAMAGE.
98 + """
99 +
100 + def credits():
101 + print(_credits)
102 + credits.__repr__ = lambda:_credits
103 +
104 + def copyright():
105 + print(_copyright)
106 + copyright.__repr__ = lambda:_copyright
107 +
108 + def license():
109 + print(_license)
110 + license.__repr__ = lambda:_license
111 +
112 + def write(data):
113 + doc['console'].value += str(data)
114 +
115 +
116 + sys.stdout.write = sys.stderr.write = write
117 + history = []
118 + current = 0
119 + _status = "main" # or "block" if typing inside a block
120 +
121 + # execution namespace
122 + editor_ns = {'credits':credits,
123 + 'copyright':copyright,
124 + 'license':license,
125 + '__name__':'__main__'}
126 +
127 + def cursorToEnd(*args):
128 + pos = len(doc['console'].value)
129 + doc['console'].setSelectionRange(pos, pos)
130 + doc['console'].scrollTop = doc['console'].scrollHeight
131 +
132 + def get_col(area):
133 + # returns the column num of cursor
134 + sel = doc['console'].selectionStart
135 + lines = doc['console'].value.split('\n')
136 + for line in lines[:-1]:
137 + sel -= len(line) + 1
138 + return sel
139 +
140 +
141 + def myKeyPress(event):
142 + global _status, current
143 + if event.keyCode == 9: # tab key
144 + event.preventDefault()
145 + doc['console'].value += " "
146 + elif event.keyCode == 13: # return
147 + src = doc['console'].value
148 + if _status == "main":
149 + currentLine = src[src.rfind('>>>') + 4:]
150 + elif _status == "3string":
151 + currentLine = src[src.rfind('>>>') + 4:]
152 + currentLine = currentLine.replace('\n... ', '\n')
153 + else:
154 + currentLine = src[src.rfind('...') + 4:]
155 + if _status == 'main' and not currentLine.strip():
156 + doc['console'].value += '\n>>> '
157 + event.preventDefault()
158 + return
159 + doc['console'].value += '\n'
160 + history.append(currentLine)
161 + current = len(history)
162 + if _status == "main" or _status == "3string":
163 + try:
164 + _ = editor_ns['_'] = eval(currentLine, editor_ns)
165 + if _ is not None:
166 + write(repr(_)+'\n')
167 + doc['console'].value += '>>> '
168 + _status = "main"
169 + except IndentationError:
170 + doc['console'].value += '... '
171 + _status = "block"
172 + except SyntaxError as msg:
173 + if str(msg) == 'invalid syntax : triple string end not found' or \
174 + str(msg).startswith('Unbalanced bracket'):
175 + doc['console'].value += '... '
176 + _status = "3string"
177 + elif str(msg) == 'eval() argument must be an expression':
178 + try:
179 + exec(currentLine, editor_ns)
180 + except:
181 + traceback.print_exc()
182 + doc['console'].value += '>>> '
183 + _status = "main"
184 + elif str(msg) == 'decorator expects function':
185 + doc['console'].value += '... '
186 + _status = "block"
187 + else:
188 + traceback.print_exc()
189 + doc['console'].value += '>>> '
190 + _status = "main"
191 + except:
192 + traceback.print_exc()
193 + doc['console'].value += '>>> '
194 + _status = "main"
195 + elif currentLine == "": # end of block
196 + block = src[src.rfind('>>>') + 4:].splitlines()
197 + block = [block[0]] + [b[4:] for b in block[1:]]
198 + block_src = '\n'.join(block)
199 + # status must be set before executing code in globals()
200 + _status = "main"
201 + try:
202 + _ = exec(block_src, editor_ns)
203 + if _ is not None:
204 + print(repr(_))
205 + except:
206 + traceback.print_exc()
207 + doc['console'].value += '>>> '
208 + else:
209 + doc['console'].value += '... '
210 +
211 + cursorToEnd()
212 + event.preventDefault()
213 +
214 + def myKeyDown(event):
215 + global _status, current
216 + if event.keyCode == 37: # left arrow
217 + sel = get_col(doc['console'])
218 + if sel < 5:
219 + event.preventDefault()
220 + event.stopPropagation()
221 + elif event.keyCode == 36: # line start
222 + pos = doc['console'].selectionStart
223 + col = get_col(doc['console'])
224 + doc['console'].setSelectionRange(pos - col + 4, pos - col + 4)
225 + event.preventDefault()
226 + elif event.keyCode == 38: # up
227 + if current > 0:
228 + pos = doc['console'].selectionStart
229 + col = get_col(doc['console'])
230 + # remove current line
231 + doc['console'].value = doc['console'].value[:pos - col + 4]
232 + current -= 1
233 + doc['console'].value += history[current]
234 + event.preventDefault()
235 + elif event.keyCode == 40: # down
236 + if current < len(history) - 1:
237 + pos = doc['console'].selectionStart
238 + col = get_col(doc['console'])
239 + # remove current line
240 + doc['console'].value = doc['console'].value[:pos - col + 4]
241 + current += 1
242 + doc['console'].value += history[current]
243 + event.preventDefault()
244 + elif event.keyCode == 8: # backspace
245 + src = doc['console'].value
246 + lstart = src.rfind('\n')
247 + if (lstart == -1 and len(src) < 5) or (len(src) - lstart < 6):
248 + event.preventDefault()
249 + event.stopPropagation()
250 +
251 +
252 + doc['console'].bind('keypress', myKeyPress)
253 + doc['console'].bind('keydown', myKeyDown)
254 + doc['console'].bind('click', cursorToEnd)
255 + v = sys.implementation.version
256 + doc['console'].value = "Brython %s.%s.%s on %s %s\n>>> " % (
257 + v[0], v[1], v[2], window.navigator.appName, window.navigator.appVersion)
258 + #doc['console'].value += 'Type "copyright", "credits" or "license" for more information.'
259 + doc['console'].focus()
260 + cursorToEnd()
261 +
262 +
263 +
264 +
@@ -0,0 +1,2
1 + :javascript
2 + $("#latest_status").html("#{j render({partial: 'submission_short', locals: {submission: @submission, problem_name: @problem.name}})}")
@@ -0,0 +1,100
1 + %h1 Listing users
2 +
3 + .panel.panel-primary
4 + .panel-title.panel-heading
5 + Quick Add
6 + .panel-body
7 + = form_tag( {method: 'post'}, {class: 'form-inline'}) do
8 + .form-group
9 + = label_tag 'user_login', 'Login'
10 + = text_field 'user', 'login', :size => 10,class: 'form-control'
11 + .form-group
12 + = label_tag 'user_full_name', 'Full Name'
13 + = text_field 'user', 'full_name', :size => 10,class: 'form-control'
14 + .form-group
15 + = label_tag 'user_password', 'Password'
16 + = text_field 'user', 'password', :size => 10,class: 'form-control'
17 + .form-group
18 + = label_tag 'user_password_confirmation', 'Confirm'
19 + = text_field 'user', 'password_confirmation', :size => 10,class: 'form-control'
20 + .form-group
21 + = label_tag 'user_email', 'email'
22 + = text_field 'user', 'email', :size => 10,class: 'form-control'
23 + =submit_tag "Create", class: 'btn btn-primary'
24 +
25 + .panel.panel-primary
26 + .panel-title.panel-heading
27 + Import from site management
28 + .panel-body
29 + = form_tag({:action => 'import'}, :multipart => true,class: 'form form-inline') do
30 + .form-group
31 + = label_tag :file, 'File:'
32 + .input-group
33 + %span.input-group-btn
34 + %span.btn.btn-default.btn-file
35 + Browse
36 + = file_field_tag 'file'
37 + = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
38 + = submit_tag 'Submit', class: 'btn btn-default'
39 +
40 +
41 + %p
42 + = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
43 + = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
44 + = link_to 'View administrators',{ :action => 'admin'}, { class: 'btn btn-default '}
45 + = link_to 'Random passwords',{ :action => 'random_all_passwords'}, { class: 'btn btn-default '}
46 + = link_to 'View active users',{ :action => 'active'}, { class: 'btn btn-default '}
47 + = link_to 'Mass mailing',{ :action => 'mass_mailing'}, { class: 'btn btn-default '}
48 +
49 + - if GraderConfiguration.multicontests?
50 + %br/
51 + %b Multi-contest:
52 + = link_to '[Manage bulk users in contests]', :action => 'contest_management'
53 + View users in:
54 + - @contests.each do |contest|
55 + = link_to "[#{contest.name}]", :action => 'contests', :id => contest.id
56 + = link_to "[no contest]", :action => 'contests', :id => 'none'
57 +
58 + Total #{@user_count} users |
59 + - if !@paginated
60 + Display all users.
61 + \#{link_to '[show in pages]', :action => 'index', :page => '1'}
62 + - else
63 + Display in pages.
64 + \#{link_to '[display all]', :action => 'index', :page => 'all'} |
65 + \#{will_paginate @users, :container => false}
66 +
67 +
68 + %table.table.table-hover.table-condense
69 + %thead
70 + %th Login
71 + %th Full name
72 + %th email
73 + %th Remark
74 + %th
75 + Activated
76 + %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'User has already confirmed the email?' } [?]
77 + %th
78 + Enabled
79 + %sup{class: 'text-primary',data: {toggle: 'tooltip', placement: 'top'}, title: 'Allow the user to login?' } [?]
80 + %th Last IP
81 + %th
82 + %th
83 + %th
84 + %th
85 + - for user in @users
86 + %tr
87 + %td= link_to user.login, controller: :users, :action => 'profile', :id => user
88 + %td= user.full_name
89 + %td= user.email
90 + %td= user.remark
91 + %td= toggle_button(user.activated?, toggle_activate_user_url(user),"toggle_activate_user_#{user.id}")
92 + %td= toggle_button(user.enabled?, toggle_enable_user_url(user),"toggle_enable_user_#{user.id}")
93 + %td= user.last_ip
94 + %td= link_to 'Clear IP', {:action => 'clear_last_ip', :id => user, :page=>params[:page]}, :confirm => 'This will reset last logging in ip of the user, are you sure?', class: 'btn btn-default btn-xs btn-block'
95 + %td= link_to 'Show', {:action => 'show', :id => user}, class: 'btn btn-default btn-xs btn-block'
96 + %td= link_to 'Edit', {:action => 'edit', :id => user}, class: 'btn btn-default btn-xs btn-block'
97 + %td= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post, class: 'btn btn-danger btn-xs btn-block'
98 + %br/
99 + = link_to '+ New user', { :action => 'new' }, { class: 'btn btn-success '}
100 + = link_to '+ New list of users', { :action => 'new_list' }, { class: 'btn btn-success '}
@@ -0,0 +1,3
1 + class ActiveRecord::ConnectionAdapters::Mysql2Adapter
2 + NATIVE_DATABASE_TYPES[:primary_key] = "int(11) auto_increment PRIMARY KEY"
3 + end
@@ -0,0 +1,12
1 + require 'spec_helper'
2 +
3 + describe SourcesController do
4 +
5 + describe "GET 'direct_edit'" do
6 + it "returns http success" do
7 + get 'direct_edit'
8 + response.should be_success
9 + end
10 + end
11 +
12 + end
@@ -0,0 +1,15
1 + require 'spec_helper'
2 +
3 + # Specs in this file have access to a helper object that includes
4 + # the SourcesHelper. For example:
5 + #
6 + # describe SourcesHelper do
7 + # describe "string concat" do
8 + # it "concats two strings with spaces" do
9 + # expect(helper.concat_strings("this","that")).to eq("this that")
10 + # end
11 + # end
12 + # end
13 + describe SourcesHelper do
14 + pending "add some examples to (or delete) #{__FILE__}"
15 + end
@@ -0,0 +1,5
1 + require 'spec_helper'
2 +
3 + describe "sources/direct_edit.html.haml" do
4 + pending "add some examples to (or delete) #{__FILE__}"
5 + end
@@ -1,16 +1,18
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 gem 'rails', '3.2.21'
3 gem 'rails', '3.2.21'
4
4
5 + gem 'select2-rails'
6 +
5 # Bundle edge Rails instead:
7 # Bundle edge Rails instead:
6 # gem 'rails', :git => 'git://github.com/rails/rails.git'
8 # gem 'rails', :git => 'git://github.com/rails/rails.git'
7
9
8 gem 'mysql2'
10 gem 'mysql2'
9
11
10 # Gems used only for assets and not required
12 # Gems used only for assets and not required
11 # in production environments by default.
13 # in production environments by default.
12 group :assets do
14 group :assets do
13 gem 'sass-rails', '~> 3.2.6'
15 gem 'sass-rails', '~> 3.2.6'
14 gem 'coffee-rails', '~> 3.2.2'
16 gem 'coffee-rails', '~> 3.2.2'
15
17
16 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
18 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
@@ -36,28 +38,43
36 # To use debugger
38 # To use debugger
37 # gem 'debugger'
39 # gem 'debugger'
38 #
40 #
39
41
40 #in-place editor
42 #in-place editor
41 gem 'best_in_place', '~> 3.0.1'
43 gem 'best_in_place', '~> 3.0.1'
42
44
43 # jquery addition
45 # jquery addition
44 gem 'jquery-rails'
46 gem 'jquery-rails'
45 gem 'jquery-ui-sass-rails'
47 gem 'jquery-ui-sass-rails'
46 gem 'jquery-timepicker-addon-rails'
48 gem 'jquery-timepicker-addon-rails'
47 gem 'jquery-tablesorter'
49 gem 'jquery-tablesorter'
50 + gem 'jquery-countdown-rails'
48
51
49 #syntax highlighter
52 #syntax highlighter
50 gem 'rouge'
53 gem 'rouge'
51
54
55 + #add bootstrap
56 + gem 'bootstrap-sass', '~> 3.2.0'
57 + gem 'bootstrap-switch-rails'
58 + gem 'bootstrap-toggle-rails'
59 + gem 'autoprefixer-rails'
60 +
61 + #bootstrap sortable
62 + gem 'momentjs-rails'
63 + gem 'rails_bootstrap_sortable'
64 +
65 + #ace editor
66 + gem 'ace-rails-ap'
67 +
52 gem 'haml'
68 gem 'haml'
69 + gem 'haml-rails'
53 gem 'mail'
70 gem 'mail'
54 gem 'rdiscount'
71 gem 'rdiscount'
55 gem 'test-unit'
72 gem 'test-unit'
56 gem 'will_paginate', '~> 3.0.7'
73 gem 'will_paginate', '~> 3.0.7'
57 gem 'dynamic_form'
74 gem 'dynamic_form'
58 gem 'in_place_editing'
75 gem 'in_place_editing'
59 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
76 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
60
77
61 group :test, :development do
78 group :test, :development do
62 gem 'rspec-rails', '~> 2.99.0'
79 gem 'rspec-rails', '~> 2.99.0'
63 end
80 end
@@ -1,23 +1,24
1 GIT
1 GIT
2 remote: https://github.com/sikachu/verification.git
2 remote: https://github.com/sikachu/verification.git
3 revision: 76eaf51b13276ecae54bd9cd115832595d2ff56d
3 revision: 76eaf51b13276ecae54bd9cd115832595d2ff56d
4 specs:
4 specs:
5 verification (1.0.3)
5 verification (1.0.3)
6 actionpack (>= 3.0.0, < 5.0)
6 actionpack (>= 3.0.0, < 5.0)
7 activesupport (>= 3.0.0, < 5.0)
7 activesupport (>= 3.0.0, < 5.0)
8
8
9 GEM
9 GEM
10 remote: https://rubygems.org/
10 remote: https://rubygems.org/
11 specs:
11 specs:
12 + ace-rails-ap (4.0.2)
12 actionmailer (3.2.21)
13 actionmailer (3.2.21)
13 actionpack (= 3.2.21)
14 actionpack (= 3.2.21)
14 mail (~> 2.5.4)
15 mail (~> 2.5.4)
15 actionpack (3.2.21)
16 actionpack (3.2.21)
16 activemodel (= 3.2.21)
17 activemodel (= 3.2.21)
17 activesupport (= 3.2.21)
18 activesupport (= 3.2.21)
18 builder (~> 3.0.0)
19 builder (~> 3.0.0)
19 erubis (~> 2.7.0)
20 erubis (~> 2.7.0)
20 journey (~> 1.0.4)
21 journey (~> 1.0.4)
21 rack (~> 1.4.5)
22 rack (~> 1.4.5)
22 rack-cache (~> 1.2)
23 rack-cache (~> 1.2)
23 rack-test (~> 0.6.1)
24 rack-test (~> 0.6.1)
@@ -28,85 +29,102
28 activerecord (3.2.21)
29 activerecord (3.2.21)
29 activemodel (= 3.2.21)
30 activemodel (= 3.2.21)
30 activesupport (= 3.2.21)
31 activesupport (= 3.2.21)
31 arel (~> 3.0.2)
32 arel (~> 3.0.2)
32 tzinfo (~> 0.3.29)
33 tzinfo (~> 0.3.29)
33 activeresource (3.2.21)
34 activeresource (3.2.21)
34 activemodel (= 3.2.21)
35 activemodel (= 3.2.21)
35 activesupport (= 3.2.21)
36 activesupport (= 3.2.21)
36 activesupport (3.2.21)
37 activesupport (3.2.21)
37 i18n (~> 0.6, >= 0.6.4)
38 i18n (~> 0.6, >= 0.6.4)
38 multi_json (~> 1.0)
39 multi_json (~> 1.0)
39 arel (3.0.3)
40 arel (3.0.3)
41 + autoprefixer-rails (6.0.3)
42 + execjs
43 + json
40 best_in_place (3.0.3)
44 best_in_place (3.0.3)
41 actionpack (>= 3.2)
45 actionpack (>= 3.2)
42 railties (>= 3.2)
46 railties (>= 3.2)
47 + bootstrap-sass (3.2.0.2)
48 + sass (~> 3.2)
49 + bootstrap-switch-rails (3.3.3)
50 + bootstrap-toggle-rails (2.2.1.0)
43 builder (3.0.4)
51 builder (3.0.4)
44 coffee-rails (3.2.2)
52 coffee-rails (3.2.2)
45 coffee-script (>= 2.2.0)
53 coffee-script (>= 2.2.0)
46 railties (~> 3.2.0)
54 railties (~> 3.2.0)
47 coffee-script (2.3.0)
55 coffee-script (2.3.0)
48 coffee-script-source
56 coffee-script-source
49 execjs
57 execjs
50 coffee-script-source (1.9.0)
58 coffee-script-source (1.9.0)
51 diff-lcs (1.2.5)
59 diff-lcs (1.2.5)
52 dynamic_form (1.1.4)
60 dynamic_form (1.1.4)
53 erubis (2.7.0)
61 erubis (2.7.0)
54 execjs (2.3.0)
62 execjs (2.3.0)
55 haml (4.0.6)
63 haml (4.0.6)
56 tilt
64 tilt
65 + haml-rails (0.4)
66 + actionpack (>= 3.1, < 4.1)
67 + activesupport (>= 3.1, < 4.1)
68 + haml (>= 3.1, < 4.1)
69 + railties (>= 3.1, < 4.1)
57 hike (1.2.3)
70 hike (1.2.3)
58 i18n (0.7.0)
71 i18n (0.7.0)
59 in_place_editing (1.2.0)
72 in_place_editing (1.2.0)
60 journey (1.0.4)
73 journey (1.0.4)
74 + jquery-countdown-rails (2.0.2)
61 jquery-rails (3.1.2)
75 jquery-rails (3.1.2)
62 railties (>= 3.0, < 5.0)
76 railties (>= 3.0, < 5.0)
63 thor (>= 0.14, < 2.0)
77 thor (>= 0.14, < 2.0)
64 jquery-tablesorter (1.13.4)
78 jquery-tablesorter (1.13.4)
65 railties (>= 3.1, < 5)
79 railties (>= 3.1, < 5)
66 jquery-timepicker-addon-rails (1.4.1)
80 jquery-timepicker-addon-rails (1.4.1)
67 railties (>= 3.1)
81 railties (>= 3.1)
68 jquery-ui-rails (4.0.3)
82 jquery-ui-rails (4.0.3)
69 jquery-rails
83 jquery-rails
70 railties (>= 3.1.0)
84 railties (>= 3.1.0)
71 jquery-ui-sass-rails (4.0.3.0)
85 jquery-ui-sass-rails (4.0.3.0)
72 jquery-rails
86 jquery-rails
73 jquery-ui-rails (= 4.0.3)
87 jquery-ui-rails (= 4.0.3)
74 railties (>= 3.1.0)
88 railties (>= 3.1.0)
75 json (1.8.2)
89 json (1.8.2)
76 mail (2.5.4)
90 mail (2.5.4)
77 mime-types (~> 1.16)
91 mime-types (~> 1.16)
78 treetop (~> 1.4.8)
92 treetop (~> 1.4.8)
79 mime-types (1.25.1)
93 mime-types (1.25.1)
94 + momentjs-rails (2.11.1)
95 + railties (>= 3.1)
80 multi_json (1.10.1)
96 multi_json (1.10.1)
81 mysql2 (0.3.20)
97 mysql2 (0.3.20)
82 polyglot (0.3.5)
98 polyglot (0.3.5)
83 power_assert (0.2.2)
99 power_assert (0.2.2)
84 prototype-rails (3.2.1)
100 prototype-rails (3.2.1)
85 rails (~> 3.2)
101 rails (~> 3.2)
86 rack (1.4.5)
102 rack (1.4.5)
87 rack-cache (1.2)
103 rack-cache (1.2)
88 rack (>= 0.4)
104 rack (>= 0.4)
89 rack-ssl (1.3.4)
105 rack-ssl (1.3.4)
90 rack
106 rack
91 rack-test (0.6.3)
107 rack-test (0.6.3)
92 rack (>= 1.0)
108 rack (>= 1.0)
93 rails (3.2.21)
109 rails (3.2.21)
94 actionmailer (= 3.2.21)
110 actionmailer (= 3.2.21)
95 actionpack (= 3.2.21)
111 actionpack (= 3.2.21)
96 activerecord (= 3.2.21)
112 activerecord (= 3.2.21)
97 activeresource (= 3.2.21)
113 activeresource (= 3.2.21)
98 activesupport (= 3.2.21)
114 activesupport (= 3.2.21)
99 bundler (~> 1.0)
115 bundler (~> 1.0)
100 railties (= 3.2.21)
116 railties (= 3.2.21)
117 + rails_bootstrap_sortable (2.0.0)
118 + momentjs-rails (~> 2, >= 2.8.3)
101 railties (3.2.21)
119 railties (3.2.21)
102 actionpack (= 3.2.21)
120 actionpack (= 3.2.21)
103 activesupport (= 3.2.21)
121 activesupport (= 3.2.21)
104 rack-ssl (~> 1.3.2)
122 rack-ssl (~> 1.3.2)
105 rake (>= 0.8.7)
123 rake (>= 0.8.7)
106 rdoc (~> 3.4)
124 rdoc (~> 3.4)
107 thor (>= 0.14.6, < 2.0)
125 thor (>= 0.14.6, < 2.0)
108 rake (10.4.2)
126 rake (10.4.2)
109 rdiscount (2.1.8)
127 rdiscount (2.1.8)
110 rdoc (3.12.2)
128 rdoc (3.12.2)
111 json (~> 1.4)
129 json (~> 1.4)
112 rouge (1.8.0)
130 rouge (1.8.0)
@@ -121,55 +139,67
121 activemodel (>= 3.0)
139 activemodel (>= 3.0)
122 activesupport (>= 3.0)
140 activesupport (>= 3.0)
123 railties (>= 3.0)
141 railties (>= 3.0)
124 rspec-collection_matchers
142 rspec-collection_matchers
125 rspec-core (~> 2.99.0)
143 rspec-core (~> 2.99.0)
126 rspec-expectations (~> 2.99.0)
144 rspec-expectations (~> 2.99.0)
127 rspec-mocks (~> 2.99.0)
145 rspec-mocks (~> 2.99.0)
128 sass (3.4.11)
146 sass (3.4.11)
129 sass-rails (3.2.6)
147 sass-rails (3.2.6)
130 railties (~> 3.2.0)
148 railties (~> 3.2.0)
131 sass (>= 3.1.10)
149 sass (>= 3.1.10)
132 tilt (~> 1.3)
150 tilt (~> 1.3)
151 + select2-rails (4.0.1)
152 + thor (~> 0.14)
133 sprockets (2.2.3)
153 sprockets (2.2.3)
134 hike (~> 1.2)
154 hike (~> 1.2)
135 multi_json (~> 1.0)
155 multi_json (~> 1.0)
136 rack (~> 1.0)
156 rack (~> 1.0)
137 tilt (~> 1.1, != 1.3.0)
157 tilt (~> 1.1, != 1.3.0)
138 test-unit (3.0.9)
158 test-unit (3.0.9)
139 power_assert
159 power_assert
140 thor (0.19.1)
160 thor (0.19.1)
141 tilt (1.4.1)
161 tilt (1.4.1)
142 treetop (1.4.15)
162 treetop (1.4.15)
143 polyglot
163 polyglot
144 polyglot (>= 0.3.1)
164 polyglot (>= 0.3.1)
145 tzinfo (0.3.43)
165 tzinfo (0.3.43)
146 uglifier (2.7.0)
166 uglifier (2.7.0)
147 execjs (>= 0.3.0)
167 execjs (>= 0.3.0)
148 json (>= 1.8.0)
168 json (>= 1.8.0)
149 will_paginate (3.0.7)
169 will_paginate (3.0.7)
150
170
151 PLATFORMS
171 PLATFORMS
152 ruby
172 ruby
153
173
154 DEPENDENCIES
174 DEPENDENCIES
175 + ace-rails-ap
176 + autoprefixer-rails
155 best_in_place (~> 3.0.1)
177 best_in_place (~> 3.0.1)
178 + bootstrap-sass (~> 3.2.0)
179 + bootstrap-switch-rails
180 + bootstrap-toggle-rails
156 coffee-rails (~> 3.2.2)
181 coffee-rails (~> 3.2.2)
157 dynamic_form
182 dynamic_form
158 haml
183 haml
184 + haml-rails
159 in_place_editing
185 in_place_editing
186 + jquery-countdown-rails
160 jquery-rails
187 jquery-rails
161 jquery-tablesorter
188 jquery-tablesorter
162 jquery-timepicker-addon-rails
189 jquery-timepicker-addon-rails
163 jquery-ui-sass-rails
190 jquery-ui-sass-rails
164 mail
191 mail
192 + momentjs-rails
165 mysql2
193 mysql2
166 prototype-rails
194 prototype-rails
167 rails (= 3.2.21)
195 rails (= 3.2.21)
196 + rails_bootstrap_sortable
168 rdiscount
197 rdiscount
169 rouge
198 rouge
170 rspec-rails (~> 2.99.0)
199 rspec-rails (~> 2.99.0)
171 sass-rails (~> 3.2.6)
200 sass-rails (~> 3.2.6)
201 + select2-rails
172 test-unit
202 test-unit
173 uglifier
203 uglifier
174 verification!
204 verification!
175 will_paginate (~> 3.0.7)
205 will_paginate (~> 3.0.7)
@@ -1,17 +1,44
1 // This is a manifest file that'll be compiled into application.js, which will include all the files
1 // This is a manifest file that'll be compiled into application.js, which will include all the files
2 // listed below.
2 // listed below.
3 //
3 //
4 // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
4 // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
5 // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 //
6 //
7 // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
7 // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 // the compiled file.
8 // the compiled file.
9 //
9 //
10 // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
10 // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 // GO AFTER THE REQUIRES BELOW.
11 // GO AFTER THE REQUIRES BELOW.
12 //
12 //
13 - //= require prototype
13 + //= require jquery
14 - //= require prototype_ujs
14 + //= require jquery_ujs
15 - //= require effects
15 + //= require jquery.ui.all
16 - //= require dragdrop
16 + //= require bootstrap-sprockets
17 - //= require controls
17 + //= require moment
18 + //= require bootstrap-sortable
19 + //= require select2
20 + //= require ace-rails-ap
21 + //= require ace/mode-c_cpp
22 + //= require ace/mode-python
23 + //= require ace/mode-ruby
24 + //= require ace/mode-pascal
25 + //= require ace/mode-javascript
26 + //= require ace/mode-java
27 + //= require ace/theme-merbivore
28 + //= require custom
29 + //= require jquery.countdown
30 + //-------------- addition from local_jquery -----------
31 + //= require jquery.ui.datepicker
32 + //= require jquery.ui.slider
33 + //= require jquery-ui-timepicker-addon
34 + //= require jquery-tablesorter
35 + //= require best_in_place
36 + //= require best_in_place.jquery-ui
37 + //= require brython
38 +
39 + // since this is after blank line, it is not downloaded
40 + //x= require prototype
41 + //x= require prototype_ujs
42 + //x= require effects
43 + //x= require dragdrop
44 + //x= require controls
@@ -1,3 +0,0
1 - # Place all the behaviors and hooks related to the matching controller here.
2 - # All this logic will automatically be available in application.js.
3 - # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
@@ -1,61 +1,192
1 + /*
2 + * This is a manifest file that'll be compiled into application.css, which will include all the files
3 + * listed below.
4 + *
5 + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7 + *
8 + * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 + * compiled file so the styles you add here take precedence over styles defined in any styles
10 + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11 + * file per style scope.
12 + *
13 + // bootstrap says that we should not do this, but @import each file instead
14 + # *= require_tree .
15 + # *= require_self
16 + */
1
17
18 + @import jquery.ui.all
2 @import jquery.ui.core
19 @import jquery.ui.core
3 @import jquery.ui.theme
20 @import jquery.ui.theme
4 @import jquery.ui.datepicker
21 @import jquery.ui.datepicker
5 @import jquery.ui.slider
22 @import jquery.ui.slider
6 @import jquery-ui-timepicker-addon
23 @import jquery-ui-timepicker-addon
7 @import jquery-tablesorter/theme.metro-dark
24 @import jquery-tablesorter/theme.metro-dark
25 + @import jquery.countdown
8 @import tablesorter-theme.cafe
26 @import tablesorter-theme.cafe
9
27
28 + //bootstrap
29 + @import bootstrap-sprockets
30 + @import bootstrap
31 + @import select2
32 + @import select2-bootstrap
33 + //@import bootstrap3-switch
34 + @import bootstrap-toggle
35 + @import bootstrap-sortable
36 +
37 + //bootstrap navbar color (from)
38 + $bgDefault : #19197b
39 + $bgHighlight : #06064b
40 + $colDefault : #8e8eb4
41 + $colHighlight : #ffffff
42 + $dropDown : false
43 + .navbar-default
44 + background-color: $bgDefault
45 + border-color: $bgHighlight
46 + .navbar-brand
47 + color: $colDefault
48 + &:hover, &:focus
49 + color: $colHighlight
50 + .navbar-text
51 + color: $colDefault
52 + .navbar-nav
53 + > li
54 + > a
55 + color: $colDefault
56 + &:hover, &:focus
57 + color: $colHighlight
58 + @if $dropDown
59 + > .dropdown-menu
60 + background-color: $bgDefault
61 + > li
62 + > a
63 + color: $colDefault
64 + &:hover, &:focus
65 + color: $colHighlight
66 + background-color: $bgHighlight
67 + > .divider
68 + background-color: $bgHighlight
69 + @if $dropDown
70 + .open .dropdown-menu > .active
71 + > a, > a:hover, > a:focus
72 + color: $colHighlight
73 + background-color: $bgHighlight
74 + > .active
75 + > a, > a:hover, > a:focus
76 + color: $colHighlight
77 + background-color: $bgHighlight
78 + > .open
79 + > a, > a:hover, > a:focus
80 + color: $colHighlight
81 + background-color: $bgHighlight
82 + .navbar-toggle
83 + border-color: $bgHighlight
84 + &:hover, &:focus
85 + background-color: $bgHighlight
86 + .icon-bar
87 + background-color: $colDefault
88 + .navbar-collapse,
89 + .navbar-form
90 + border-color: $colDefault
91 + .navbar-link
92 + color: $colDefault
93 + &:hover
94 + color: $colHighlight
95 + @media (max-width: 767px)
96 + .navbar-default .navbar-nav .open .dropdown-menu
97 + > li > a
98 + color: $colDefault
99 + &:hover, &:focus
100 + color: $colHighlight
101 + > .active
102 + > a, > a:hover, > a:focus
103 + color: $colHighlight
104 + background-color: $bgHighlight
105 +
106 + .secondnavbar
107 + top: 50px
108 +
109 +
110 + // --------------- bootstrap file upload ----------------------
111 + .btn-file
112 + position: relative
113 + overflow: hidden
114 +
115 + .btn-file input[type=file]
116 + position: absolute
117 + top: 0
118 + right: 0
119 + min-width: 100%
120 + min-height: 100%
121 + font-size: 100px
122 + text-align: right
123 + filter: alpha(opacity=0)
124 + opacity: 0
125 + outline: none
126 + background: white
127 + cursor: inherit
128 + display: block
129 +
10 body
130 body
11 background: white image-url("topbg.jpg") repeat-x top center
131 background: white image-url("topbg.jpg") repeat-x top center
12 - font-size: 13px
132 + //font-size: 13px
13 - font-family: Tahoma, "sans-serif"
133 + //font-family: Tahoma, "sans-serif"
14 margin: 10px
134 margin: 10px
15 padding: 10px
135 padding: 10px
136 + padding-top: 60px
16
137
138 + // ------------------ bootstrap sortable --------------------
139 + table.sortable th
140 + padding-right: 20px !important
141 + span.sign
142 + right: -15px !important
143 + &.text-right
144 + padding-left: 20px !important
145 + padding-right: 8px !important
146 + &:after, span.sign
147 + left: -15px !important
17
148
18 input
149 input
19 font-family: Tahoma, "sans-serif"
150 font-family: Tahoma, "sans-serif"
20
151
21
152
22 h1
153 h1
23 font-size: 24px
154 font-size: 24px
24 color: #334488
155 color: #334488
25 line-height: 2em
156 line-height: 2em
26
157
27
158
28 h2
159 h2
29 font-size: 18px
160 font-size: 18px
30 color: #5566bb
161 color: #5566bb
31 line-height: 1.5em
162 line-height: 1.5em
32
163
33
164
34 hr
165 hr
35 border-top: 1px solid #dddddd
166 border-top: 1px solid #dddddd
36 border-bottom: 1px solid #eeeeee
167 border-bottom: 1px solid #eeeeee
37
168
38
169
39 - a
170 + //#a
40 - color: #6666cc
171 + // color: #6666cc
41 - text-decoration: none
172 + // text-decoration: none
42 -
173 + //
43 - &:link, &:visited
174 + // &:link, &:visited
44 - color: #6666cc
175 + // color: #6666cc
45 - text-decoration: none
176 + // text-decoration: none
46 -
177 + //
47 - &:hover, &:focus
178 + // &:hover, &:focus
48 - color: #111166
179 + // color: #111166
49 - text-decoration: none
180 + // text-decoration: none
50
181
51
182
52 div
183 div
53 &.userbar
184 &.userbar
54 line-height: 1.5em
185 line-height: 1.5em
55 text-align: right
186 text-align: right
56 font-size: 12px
187 font-size: 12px
57
188
58 &.title
189 &.title
59 padding: 10px 0px
190 padding: 10px 0px
60 line-height: 1.5em
191 line-height: 1.5em
61 font-size: 13px
192 font-size: 13px
@@ -1,41 +1,43
1 /*************
1 /*************
2 Metro Dark Theme
2 Metro Dark Theme
3 *************/
3 *************/
4 /* overall */
4 /* overall */
5 .tablesorter-cafe {
5 .tablesorter-cafe {
6 - // font: 12px/18px 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif;
6 + /* font: 12px/18px 'Segoe UI Semilight', 'Open Sans', Verdana, Arial, Helvetica, sans-serif; */
7 color: #000;
7 color: #000;
8 background-color: #777;
8 background-color: #777;
9 margin: 10px 0 15px;
9 margin: 10px 0 15px;
10 text-align: left;
10 text-align: left;
11 border-collapse: collapse;
11 border-collapse: collapse;
12 border: #555 1px solid;
12 border: #555 1px solid;
13 }
13 }
14
14
15 .tablesorter-cafe tr.dark-row th, .tablesorter-cafe tr.dark-row td {
15 .tablesorter-cafe tr.dark-row th, .tablesorter-cafe tr.dark-row td {
16 background-color: #222;
16 background-color: #222;
17 color: #fff;
17 color: #fff;
18 text-align: left;
18 text-align: left;
19 font-size: 14px;
19 font-size: 14px;
20 }
20 }
21
21
22 /* header/footer */
22 /* header/footer */
23 .tablesorter-cafe caption,
23 .tablesorter-cafe caption,
24 .tablesorter-cafe th,
24 .tablesorter-cafe th,
25 .tablesorter-cafe thead td,
25 .tablesorter-cafe thead td,
26 .tablesorter-cafe tfoot th,
26 .tablesorter-cafe tfoot th,
27 .tablesorter-cafe tfoot td {
27 .tablesorter-cafe tfoot td {
28 + /*
28 //font-weight: 300;
29 //font-weight: 300;
29 //font-size: 15px;
30 //font-size: 15px;
31 + */
30 color: #fff;
32 color: #fff;
31 background-color: #777;
33 background-color: #777;
32 padding: 2px;
34 padding: 2px;
33 border: #555 1px solid;
35 border: #555 1px solid;
34 }
36 }
35
37
36 .tablesorter-cafe .header,
38 .tablesorter-cafe .header,
37 .tablesorter-cafe .tablesorter-header {
39 .tablesorter-cafe .tablesorter-header {
38 background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAGFBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u5jNePWAAAACHRSTlMAMxIHKwEgMWD59H4AAABSSURBVAjXY2BgYFJgAAHzYhDJ6igSAKTYBAUTgJSioKAQAwNzoaCguAFDiCAQuDIkgigxBgiA8cJAVCpQt6AgSL+JoKAzA0gjUBsQqBcBCYhFAAE/CV4zeSzxAAAAAElFTkSuQmCC);
40 background-image: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQBAMAAADQT4M0AAAAGFBMVEUAAADu7u7u7u7u7u7u7u7u7u7u7u7u7u5jNePWAAAACHRSTlMAMxIHKwEgMWD59H4AAABSSURBVAjXY2BgYFJgAAHzYhDJ6igSAKTYBAUTgJSioKAQAwNzoaCguAFDiCAQuDIkgigxBgiA8cJAVCpQt6AgSL+JoKAzA0gjUBsQqBcBCYhFAAE/CV4zeSzxAAAAAElFTkSuQmCC);
39 background-position: center right;
41 background-position: center right;
40 background-repeat: no-repeat;
42 background-repeat: no-repeat;
41 cursor: pointer;
43 cursor: pointer;
@@ -60,32 +60,52
60 end
60 end
61 end
61 end
62
62
63 # PUT /announcements/1
63 # PUT /announcements/1
64 # PUT /announcements/1.xml
64 # PUT /announcements/1.xml
65 def update
65 def update
66 @announcement = Announcement.find(params[:id])
66 @announcement = Announcement.find(params[:id])
67
67
68 respond_to do |format|
68 respond_to do |format|
69 if @announcement.update_attributes(params[:announcement])
69 if @announcement.update_attributes(params[:announcement])
70 flash[:notice] = 'Announcement was successfully updated.'
70 flash[:notice] = 'Announcement was successfully updated.'
71 format.html { redirect_to(@announcement) }
71 format.html { redirect_to(@announcement) }
72 + format.js {}
72 format.xml { head :ok }
73 format.xml { head :ok }
73 else
74 else
74 format.html { render :action => "edit" }
75 format.html { render :action => "edit" }
76 + format.js {}
75 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
77 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
76 end
78 end
77 end
79 end
78 end
80 end
79
81
82 + def toggle
83 + @announcement = Announcement.find(params[:id])
84 + @announcement.update_attributes( published: !@announcement.published? )
85 + respond_to do |format|
86 + format.js { render partial: 'toggle_button',
87 + locals: {button_id: "#announcement_toggle_#{@announcement.id}",button_on: @announcement.published? } }
88 + end
89 + end
90 +
91 + def toggle_front
92 + @announcement = Announcement.find(params[:id])
93 + @announcement.update_attributes( frontpage: !@announcement.frontpage? )
94 + respond_to do |format|
95 + format.js { render partial: 'toggle_button',
96 + locals: {button_id: "#announcement_toggle_front_#{@announcement.id}",button_on: @announcement.frontpage? } }
97 + end
98 + end
99 +
80 # DELETE /announcements/1
100 # DELETE /announcements/1
81 # DELETE /announcements/1.xml
101 # DELETE /announcements/1.xml
82 def destroy
102 def destroy
83 @announcement = Announcement.find(params[:id])
103 @announcement = Announcement.find(params[:id])
84 @announcement.destroy
104 @announcement.destroy
85
105
86 respond_to do |format|
106 respond_to do |format|
87 format.html { redirect_to(announcements_url) }
107 format.html { redirect_to(announcements_url) }
88 format.xml { head :ok }
108 format.xml { head :ok }
89 end
109 end
90 end
110 end
91 end
111 end
@@ -1,18 +1,26
1 class ApplicationController < ActionController::Base
1 class ApplicationController < ActionController::Base
2 protect_from_forgery
2 protect_from_forgery
3
3
4 + before_filter :current_user
5 +
4 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
5 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
6
8
9 + # Returns the current logged-in user (if any).
10 + def current_user
11 + return nil unless session[:user_id]
12 + @current_user ||= User.find(session[:user_id])
13 + end
14 +
7 def admin_authorization
15 def admin_authorization
8 return false unless authenticate
16 return false unless authenticate
9 user = User.find(session[:user_id], :include => ['roles'])
17 user = User.find(session[:user_id], :include => ['roles'])
10 unless user.admin?
18 unless user.admin?
11 flash[:notice] = 'You are not authorized to view the page you requested'
19 flash[:notice] = 'You are not authorized to view the page you requested'
12 redirect_to :controller => 'main', :action => 'login' unless user.admin?
20 redirect_to :controller => 'main', :action => 'login' unless user.admin?
13 return false
21 return false
14 end
22 end
15 return true
23 return true
16 end
24 end
17
25
18 def authorization_by_roles(allowed_roles)
26 def authorization_by_roles(allowed_roles)
@@ -30,30 +38,35
30 def authenticate
38 def authenticate
31 unless session[:user_id]
39 unless session[:user_id]
32 flash[:notice] = 'You need to login'
40 flash[:notice] = 'You need to login'
33 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
41 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
34 flash[:notice] = 'You need to login but you cannot log in at this time'
42 flash[:notice] = 'You need to login but you cannot log in at this time'
35 end
43 end
36 redirect_to :controller => 'main', :action => 'login'
44 redirect_to :controller => 'main', :action => 'login'
37 return false
45 return false
38 end
46 end
39
47
40 # check if run in single user mode
48 # check if run in single user mode
41 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
49 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
42 - user = User.find(session[:user_id])
50 + user = User.find_by_id(session[:user_id])
43 if user==nil or (not user.admin?)
51 if user==nil or (not user.admin?)
44 flash[:notice] = 'You cannot log in at this time'
52 flash[:notice] = 'You cannot log in at this time'
45 redirect_to :controller => 'main', :action => 'login'
53 redirect_to :controller => 'main', :action => 'login'
46 return false
54 return false
47 end
55 end
56 + unless user.enabled?
57 + flash[:notice] = 'Your account is disabled'
58 + redirect_to :controller => 'main', :action => 'login'
59 + return false
60 + end
48 return true
61 return true
49 end
62 end
50
63
51 if GraderConfiguration.multicontests?
64 if GraderConfiguration.multicontests?
52 user = User.find(session[:user_id])
65 user = User.find(session[:user_id])
53 return true if user.admin?
66 return true if user.admin?
54 begin
67 begin
55 if user.contest_stat(true).forced_logout
68 if user.contest_stat(true).forced_logout
56 flash[:notice] = 'You have been automatically logged out.'
69 flash[:notice] = 'You have been automatically logged out.'
57 redirect_to :controller => 'main', :action => 'index'
70 redirect_to :controller => 'main', :action => 'index'
58 end
71 end
59 rescue
72 rescue
@@ -60,24 +60,32
60 def submit
60 def submit
61 user = User.find(session[:user_id])
61 user = User.find(session[:user_id])
62
62
63 @submission = Submission.new
63 @submission = Submission.new
64 @submission.problem_id = params[:submission][:problem_id]
64 @submission.problem_id = params[:submission][:problem_id]
65 @submission.user = user
65 @submission.user = user
66 @submission.language_id = 0
66 @submission.language_id = 0
67 if (params['file']) and (params['file']!='')
67 if (params['file']) and (params['file']!='')
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
70 @submission.source_filename = params['file'].original_filename
70 @submission.source_filename = params['file'].original_filename
71 end
71 end
72 +
73 + if (params[:editor_text])
74 + language = Language.find_by_id(params[:language_id])
75 + @submission.source = params[:editor_text]
76 + @submission.source_filename = "live_edit.#{language.ext}"
77 + @submission.language = language
78 + end
79 +
72 @submission.submitted_at = Time.new.gmtime
80 @submission.submitted_at = Time.new.gmtime
73 @submission.ip_address = request.remote_ip
81 @submission.ip_address = request.remote_ip
74
82
75 if GraderConfiguration.time_limit_mode? and user.contest_finished?
83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
76 @submission.errors.add(:base,"The contest is over.")
84 @submission.errors.add(:base,"The contest is over.")
77 prepare_list_information
85 prepare_list_information
78 render :action => 'list' and return
86 render :action => 'list' and return
79 end
87 end
80
88
81 if @submission.valid?
89 if @submission.valid?
82 if @submission.save == false
90 if @submission.save == false
83 flash[:notice] = 'Error saving your submission'
91 flash[:notice] = 'Error saving your submission'
@@ -114,26 +122,26
114 flash[:notice] = 'Error viewing source'
122 flash[:notice] = 'Error viewing source'
115 redirect_to :action => 'list'
123 redirect_to :action => 'list'
116 end
124 end
117 end
125 end
118
126
119 def submission
127 def submission
120 @user = User.find(session[:user_id])
128 @user = User.find(session[:user_id])
121 @problems = @user.available_problems
129 @problems = @user.available_problems
122 if params[:id]==nil
130 if params[:id]==nil
123 @problem = nil
131 @problem = nil
124 @submissions = nil
132 @submissions = nil
125 else
133 else
126 - @problem = Problem.find_by_name(params[:id])
134 + @problem = Problem.find_by_id(params[:id])
127 - if not @problem.available
135 + if (@problem == nil) or (not @problem.available)
128 redirect_to :action => 'list'
136 redirect_to :action => 'list'
129 flash[:notice] = 'Error: submissions for that problem are not viewable.'
137 flash[:notice] = 'Error: submissions for that problem are not viewable.'
130 return
138 return
131 end
139 end
132 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
140 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
133 end
141 end
134 end
142 end
135
143
136 def result
144 def result
137 if !GraderConfiguration.show_grading_result
145 if !GraderConfiguration.show_grading_result
138 redirect_to :action => 'list' and return
146 redirect_to :action => 'list' and return
139 end
147 end
@@ -1,79 +1,74
1 class ProblemsController < ApplicationController
1 class ProblemsController < ApplicationController
2
2
3 before_filter :authenticate, :authorization
3 before_filter :authenticate, :authorization
4
4
5 in_place_edit_for :problem, :name
5 in_place_edit_for :problem, :name
6 in_place_edit_for :problem, :full_name
6 in_place_edit_for :problem, :full_name
7 in_place_edit_for :problem, :full_score
7 in_place_edit_for :problem, :full_score
8
8
9 def index
9 def index
10 - list
10 + @problems = Problem.find(:all, :order => 'date_added DESC')
11 - render :action => 'list'
12 end
11 end
13
12
14 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
13 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
15 verify :method => :post, :only => [ :destroy,
14 verify :method => :post, :only => [ :destroy,
16 :create, :quick_create,
15 :create, :quick_create,
17 :do_manage,
16 :do_manage,
18 :do_import,
17 :do_import,
19 :update ],
18 :update ],
20 - :redirect_to => { :action => :list }
19 + :redirect_to => { :action => :index }
21 -
22 - def list
23 - @problems = Problem.find(:all, :order => 'date_added DESC')
24 - end
25
20
26 def show
21 def show
27 @problem = Problem.find(params[:id])
22 @problem = Problem.find(params[:id])
28 end
23 end
29
24
30 def new
25 def new
31 @problem = Problem.new
26 @problem = Problem.new
32 @description = nil
27 @description = nil
33 end
28 end
34
29
35 def create
30 def create
36 @problem = Problem.new(params[:problem])
31 @problem = Problem.new(params[:problem])
37 @description = Description.new(params[:description])
32 @description = Description.new(params[:description])
38 if @description.body!=''
33 if @description.body!=''
39 if !@description.save
34 if !@description.save
40 render :action => new and return
35 render :action => new and return
41 end
36 end
42 else
37 else
43 @description = nil
38 @description = nil
44 end
39 end
45 @problem.description = @description
40 @problem.description = @description
46 if @problem.save
41 if @problem.save
47 flash[:notice] = 'Problem was successfully created.'
42 flash[:notice] = 'Problem was successfully created.'
48 - redirect_to :action => 'list'
43 + redirect_to action: :index
49 else
44 else
50 render :action => 'new'
45 render :action => 'new'
51 end
46 end
52 end
47 end
53
48
54 def quick_create
49 def quick_create
55 @problem = Problem.new(params[:problem])
50 @problem = Problem.new(params[:problem])
56 @problem.full_name = @problem.name if @problem.full_name == ''
51 @problem.full_name = @problem.name if @problem.full_name == ''
57 @problem.full_score = 100
52 @problem.full_score = 100
58 @problem.available = false
53 @problem.available = false
59 @problem.test_allowed = true
54 @problem.test_allowed = true
60 @problem.output_only = false
55 @problem.output_only = false
61 @problem.date_added = Time.new
56 @problem.date_added = Time.new
62 if @problem.save
57 if @problem.save
63 flash[:notice] = 'Problem was successfully created.'
58 flash[:notice] = 'Problem was successfully created.'
64 - redirect_to :action => 'list'
59 + redirect_to action: :index
65 else
60 else
66 flash[:notice] = 'Error saving problem'
61 flash[:notice] = 'Error saving problem'
67 - redirect_to :action => 'list'
62 + redirect_to action: :index
68 end
63 end
69 end
64 end
70
65
71 def edit
66 def edit
72 @problem = Problem.find(params[:id])
67 @problem = Problem.find(params[:id])
73 @description = @problem.description
68 @description = @problem.description
74 end
69 end
75
70
76 def update
71 def update
77 @problem = Problem.find(params[:id])
72 @problem = Problem.find(params[:id])
78 @description = @problem.description
73 @description = @problem.description
79 if @description == nil and params[:description][:body]!=''
74 if @description == nil and params[:description][:body]!=''
@@ -112,49 +107,59
112 end
107 end
113 @problem.description_filename = "#{@problem.name}.pdf"
108 @problem.description_filename = "#{@problem.name}.pdf"
114 @problem.save
109 @problem.save
115 end
110 end
116 redirect_to :action => 'show', :id => @problem
111 redirect_to :action => 'show', :id => @problem
117 else
112 else
118 render :action => 'edit'
113 render :action => 'edit'
119 end
114 end
120 end
115 end
121
116
122 def destroy
117 def destroy
123 Problem.find(params[:id]).destroy
118 Problem.find(params[:id]).destroy
124 - redirect_to :action => 'list'
119 + redirect_to action: :index
125 end
120 end
126
121
127 def toggle
122 def toggle
128 @problem = Problem.find(params[:id])
123 @problem = Problem.find(params[:id])
129 - @problem.available = !(@problem.available)
124 + @problem.update_attributes(available: !(@problem.available) )
130 - @problem.save
125 + respond_to do |format|
126 + format.js { }
127 + end
128 + end
129 +
130 + def toggle_test
131 + @problem = Problem.find(params[:id])
132 + @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 + respond_to do |format|
134 + format.js { }
135 + end
131 end
136 end
132
137
133 def turn_all_off
138 def turn_all_off
134 Problem.find(:all,
139 Problem.find(:all,
135 :conditions => "available = 1").each do |problem|
140 :conditions => "available = 1").each do |problem|
136 problem.available = false
141 problem.available = false
137 problem.save
142 problem.save
138 end
143 end
139 - redirect_to :action => 'list'
144 + redirect_to action: :index
140 end
145 end
141
146
142 def turn_all_on
147 def turn_all_on
143 Problem.find(:all,
148 Problem.find(:all,
144 :conditions => "available = 0").each do |problem|
149 :conditions => "available = 0").each do |problem|
145 problem.available = true
150 problem.available = true
146 problem.save
151 problem.save
147 end
152 end
148 - redirect_to :action => 'list'
153 + redirect_to action: :index
149 end
154 end
150
155
151 def stat
156 def stat
152 @problem = Problem.find(params[:id])
157 @problem = Problem.find(params[:id])
153 unless @problem.available or session[:admin]
158 unless @problem.available or session[:admin]
154 redirect_to :controller => 'main', :action => 'list'
159 redirect_to :controller => 'main', :action => 'list'
155 return
160 return
156 end
161 end
157 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
162 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
158
163
159 #stat summary
164 #stat summary
160 range =65
165 range =65
@@ -3,24 +3,54
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize]
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize]
4
4
5 before_filter(only: [:problem_hof]) { |c|
5 before_filter(only: [:problem_hof]) { |c|
6 return false unless authenticate
6 return false unless authenticate
7
7
8 if GraderConfiguration["right.user_view_submission"]
8 if GraderConfiguration["right.user_view_submission"]
9 return true;
9 return true;
10 end
10 end
11
11
12 admin_authorization
12 admin_authorization
13 }
13 }
14
14
15 + def score
16 + if params[:commit] == 'download csv'
17 + @problems = Problem.all
18 + else
19 + @problems = Problem.find_available_problems
20 + end
21 + @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
22 + @scorearray = Array.new
23 + @users.each do |u|
24 + ustat = Array.new
25 + ustat[0] = u
26 + @problems.each do |p|
27 + sub = Submission.find_last_by_user_and_problem(u.id,p.id)
28 + if (sub!=nil) and (sub.points!=nil) and p and p.full_score
29 + ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
30 + else
31 + ustat << [0,false]
32 + end
33 + end
34 + @scorearray << ustat
35 + end
36 + if params[:commit] == 'download csv' then
37 + csv = gen_csv_from_scorearray(@scorearray,@problems)
38 + send_data csv, filename: 'last_score.csv'
39 + else
40 + render template: 'user_admin/user_stat'
41 + end
42 +
43 + end
44 +
15 def login_stat
45 def login_stat
16 @logins = Array.new
46 @logins = Array.new
17
47
18 date_and_time = '%Y-%m-%d %H:%M'
48 date_and_time = '%Y-%m-%d %H:%M'
19 begin
49 begin
20 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
50 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
21 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
51 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
22 rescue
52 rescue
23 @since_time = DateTime.new(1000,1,1)
53 @since_time = DateTime.new(1000,1,1)
24 end
54 end
25 begin
55 begin
26 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
56 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
@@ -64,30 +94,25
64 @until_time = DateTime.new(3000,1,1)
94 @until_time = DateTime.new(3000,1,1)
65 end
95 end
66
96
67 @submissions = {}
97 @submissions = {}
68
98
69 User.find_each do |user|
99 User.find_each do |user|
70 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
100 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
71 end
101 end
72
102
73 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
103 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
74 if @submissions[s.user_id]
104 if @submissions[s.user_id]
75 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
105 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
76 - a = nil
106 + a = Problem.find_by_id(s.problem_id)
77 - begin
78 - a = Problem.find(s.problem_id)
79 - rescue
80 - a = nil
81 - end
82 @submissions[s.user_id][:sub][s.problem_id] =
107 @submissions[s.user_id][:sub][s.problem_id] =
83 { prob_name: (a ? a.full_name : '(NULL)'),
108 { prob_name: (a ? a.full_name : '(NULL)'),
84 sub_ids: [s.id] }
109 sub_ids: [s.id] }
85 else
110 else
86 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
111 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
87 end
112 end
88 @submissions[s.user_id][:count] += 1
113 @submissions[s.user_id][:count] += 1
89 end
114 end
90 end
115 end
91 end
116 end
92
117
93 def problem_hof
118 def problem_hof
@@ -8,25 +8,24
8
8
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 verify :method => :post, :only => [ :destroy,
10 verify :method => :post, :only => [ :destroy,
11 :create, :create_from_list,
11 :create, :create_from_list,
12 :update,
12 :update,
13 :manage_contest,
13 :manage_contest,
14 :bulk_mail
14 :bulk_mail
15 ],
15 ],
16 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
17
17
18 def index
18 def index
19 list
19 list
20 - render :action => 'list'
21 end
20 end
22
21
23 def list
22 def list
24 @user_count = User.count
23 @user_count = User.count
25 if params[:page] == 'all'
24 if params[:page] == 'all'
26 @users = User.all
25 @users = User.all
27 @paginated = false
26 @paginated = false
28 else
27 else
29 @users = User.paginate :page => params[:page]
28 @users = User.paginate :page => params[:page]
30 @paginated = true
29 @paginated = true
31 end
30 end
32 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
31 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
@@ -47,35 +46,35
47 @user = User.find(params[:id])
46 @user = User.find(params[:id])
48 end
47 end
49
48
50 def new
49 def new
51 @user = User.new
50 @user = User.new
52 end
51 end
53
52
54 def create
53 def create
55 @user = User.new(params[:user])
54 @user = User.new(params[:user])
56 @user.activated = true
55 @user.activated = true
57 if @user.save
56 if @user.save
58 flash[:notice] = 'User was successfully created.'
57 flash[:notice] = 'User was successfully created.'
59 - redirect_to :action => 'list'
58 + redirect_to :action => 'index'
60 else
59 else
61 render :action => 'new'
60 render :action => 'new'
62 end
61 end
63 end
62 end
64
63
65 def clear_last_ip
64 def clear_last_ip
66 @user = User.find(params[:id])
65 @user = User.find(params[:id])
67 @user.last_ip = nil
66 @user.last_ip = nil
68 @user.save
67 @user.save
69 - redirect_to action: 'list', page: params[:page]
68 + redirect_to action: 'index', page: params[:page]
70 end
69 end
71
70
72 def create_from_list
71 def create_from_list
73 lines = params[:user_list]
72 lines = params[:user_list]
74
73
75 note = []
74 note = []
76
75
77 lines.split("\n").each do |line|
76 lines.split("\n").each do |line|
78 items = line.chomp.split(',')
77 items = line.chomp.split(',')
79 if items.length>=2
78 if items.length>=2
80 login = items[0]
79 login = items[0]
81 full_name = items[1]
80 full_name = items[1]
@@ -105,44 +104,44
105 user.save
104 user.save
106
105
107 if added_random_password
106 if added_random_password
108 note << "'#{login}' (+)"
107 note << "'#{login}' (+)"
109 else
108 else
110 note << login
109 note << login
111 end
110 end
112 end
111 end
113 end
112 end
114 flash[:notice] = 'User(s) ' + note.join(', ') +
113 flash[:notice] = 'User(s) ' + note.join(', ') +
115 ' were successfully created. ' +
114 ' were successfully created. ' +
116 '( (+) - created with random passwords.)'
115 '( (+) - created with random passwords.)'
117 - redirect_to :action => 'list'
116 + redirect_to :action => 'index'
118 end
117 end
119
118
120 def edit
119 def edit
121 @user = User.find(params[:id])
120 @user = User.find(params[:id])
122 end
121 end
123
122
124 def update
123 def update
125 @user = User.find(params[:id])
124 @user = User.find(params[:id])
126 if @user.update_attributes(params[:user])
125 if @user.update_attributes(params[:user])
127 flash[:notice] = 'User was successfully updated.'
126 flash[:notice] = 'User was successfully updated.'
128 redirect_to :action => 'show', :id => @user
127 redirect_to :action => 'show', :id => @user
129 else
128 else
130 render :action => 'edit'
129 render :action => 'edit'
131 end
130 end
132 end
131 end
133
132
134 def destroy
133 def destroy
135 User.find(params[:id]).destroy
134 User.find(params[:id]).destroy
136 - redirect_to :action => 'list'
135 + redirect_to :action => 'index'
137 end
136 end
138
137
139 def user_stat
138 def user_stat
140 if params[:commit] == 'download csv'
139 if params[:commit] == 'download csv'
141 @problems = Problem.all
140 @problems = Problem.all
142 else
141 else
143 @problems = Problem.find_available_problems
142 @problems = Problem.find_available_problems
144 end
143 end
145 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
144 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
146 @scorearray = Array.new
145 @scorearray = Array.new
147 @users.each do |u|
146 @users.each do |u|
148 ustat = Array.new
147 ustat = Array.new
@@ -191,25 +190,25
191
190
192 if params[:commit] == 'download csv' then
191 if params[:commit] == 'download csv' then
193 csv = gen_csv_from_scorearray(@scorearray,@problems)
192 csv = gen_csv_from_scorearray(@scorearray,@problems)
194 send_data csv, filename: 'max_score.csv'
193 send_data csv, filename: 'max_score.csv'
195 else
194 else
196 render template: 'user_admin/user_stat'
195 render template: 'user_admin/user_stat'
197 end
196 end
198 end
197 end
199
198
200 def import
199 def import
201 if params[:file]==''
200 if params[:file]==''
202 flash[:notice] = 'Error importing no file'
201 flash[:notice] = 'Error importing no file'
203 - redirect_to :action => 'list' and return
202 + redirect_to :action => 'index' and return
204 end
203 end
205 import_from_file(params[:file])
204 import_from_file(params[:file])
206 end
205 end
207
206
208 def random_all_passwords
207 def random_all_passwords
209 users = User.find(:all)
208 users = User.find(:all)
210 @prefix = params[:prefix] || ''
209 @prefix = params[:prefix] || ''
211 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
210 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
212 @changed = false
211 @changed = false
213 if request.request_method == 'POST'
212 if request.request_method == 'POST'
214 @non_admin_users.each do |user|
213 @non_admin_users.each do |user|
215 password = random_password
214 password = random_password
@@ -244,34 +243,34
244 end
243 end
245 flash[:notice] = 'User(s) ' + note.join(', ') +
244 flash[:notice] = 'User(s) ' + note.join(', ') +
246 " were successfully reassigned to #{contest.title}."
245 " were successfully reassigned to #{contest.title}."
247 redirect_to :action => 'contests', :id =>contest.id
246 redirect_to :action => 'contests', :id =>contest.id
248 end
247 end
249
248
250 def add_to_contest
249 def add_to_contest
251 user = User.find(params[:id])
250 user = User.find(params[:id])
252 contest = Contest.find(params[:contest_id])
251 contest = Contest.find(params[:contest_id])
253 if user and contest
252 if user and contest
254 user.contests << contest
253 user.contests << contest
255 end
254 end
256 - redirect_to :action => 'list'
255 + redirect_to :action => 'index'
257 end
256 end
258
257
259 def remove_from_contest
258 def remove_from_contest
260 user = User.find(params[:id])
259 user = User.find(params[:id])
261 contest = Contest.find(params[:contest_id])
260 contest = Contest.find(params[:contest_id])
262 if user and contest
261 if user and contest
263 user.contests.delete(contest)
262 user.contests.delete(contest)
264 end
263 end
265 - redirect_to :action => 'list'
264 + redirect_to :action => 'index'
266 end
265 end
267
266
268 def contest_management
267 def contest_management
269 end
268 end
270
269
271 def manage_contest
270 def manage_contest
272 contest = Contest.find(params[:contest][:id])
271 contest = Contest.find(params[:contest][:id])
273 if !contest
272 if !contest
274 flash[:notice] = 'You did not choose the contest.'
273 flash[:notice] = 'You did not choose the contest.'
275 redirect_to :action => 'contest_management' and return
274 redirect_to :action => 'contest_management' and return
276 end
275 end
277
276
@@ -124,24 +124,42
124 @histogram[:data][d.to_i] += 1 if d < range
124 @histogram[:data][d.to_i] += 1 if d < range
125
125
126 @summary[:count] += 1
126 @summary[:count] += 1
127 next unless sub.problem
127 next unless sub.problem
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 end
129 end
130
130
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @summary[:attempt] = problem.count
132 @summary[:attempt] = problem.count
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 end
134 end
135
135
136 + def toggle_activate
137 + @user = User.find(params[:id])
138 + @user.update_attributes( activated: !@user.activated? )
139 + respond_to do |format|
140 + format.js { render partial: 'toggle_button',
141 + locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 + end
143 + end
144 +
145 + def toggle_enable
146 + @user = User.find(params[:id])
147 + @user.update_attributes( enabled: !@user.enabled? )
148 + respond_to do |format|
149 + format.js { render partial: 'toggle_button',
150 + locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 + end
152 + end
153 +
136 protected
154 protected
137
155
138 def verify_online_registration
156 def verify_online_registration
139 if !GraderConfiguration['system.online_registration']
157 if !GraderConfiguration['system.online_registration']
140 redirect_to :controller => 'main', :action => 'login'
158 redirect_to :controller => 'main', :action => 'login'
141 end
159 end
142 end
160 end
143
161
144 def send_confirmation_email(user)
162 def send_confirmation_email(user)
145 contest_name = GraderConfiguration['contest.name']
163 contest_name = GraderConfiguration['contest.name']
146 activation_url = url_for(:action => 'confirm',
164 activation_url = url_for(:action => 'confirm',
147 :login => user.login,
165 :login => user.login,
@@ -183,13 +201,14
183 def profile_authorization
201 def profile_authorization
184 #if view admins' profile, allow only admin
202 #if view admins' profile, allow only admin
185 return false unless(params[:id])
203 return false unless(params[:id])
186 user = User.find(params[:id])
204 user = User.find(params[:id])
187 return false unless user
205 return false unless user
188 return admin_authorization if user.admin?
206 return admin_authorization if user.admin?
189 return true if GraderConfiguration["right.user_view_submission"]
207 return true if GraderConfiguration["right.user_view_submission"]
190
208
191 #finally, we allow only admin
209 #finally, we allow only admin
192 admin_authorization
210 admin_authorization
193 end
211 end
194
212
213 +
195 end
214 end
@@ -1,15 +1,47
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 + def navbar_user_header
5 + left_menu = ''
6 + right_menu = ''
7 + user = User.find(session[:user_id])
8 +
9 + if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
10 + left_menu << add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
11 + left_menu << add_menu("#{I18n.t 'menu.submissions'}", 'main', 'submission')
12 + left_menu << add_menu("#{I18n.t 'menu.test'}", 'test', 'index')
13 + end
14 +
15 + if GraderConfiguration['right.user_hall_of_fame']
16 + left_menu << add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
17 + end
18 +
19 + right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
20 + right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
21 + if GraderConfiguration['system.user_setting_enabled']
22 + right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
23 + end
24 + right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
25 +
26 +
27 + result = content_tag(:ul,left_menu.html_safe,class: 'nav navbar-nav') + content_tag(:ul,right_menu.html_safe,class: 'nav navbar-nav navbar-right')
28 + end
29 +
30 + def add_menu(title, controller, action,html_option = {})
31 + link_option = {controller: controller, action: action}
32 + html_option[:class] = (html_option[:class] || '') + " active" if current_page?(link_option)
33 + content_tag(:li, link_to(title,link_option),html_option)
34 + end
35 +
4 def user_header
36 def user_header
5 menu_items = ''
37 menu_items = ''
6 user = User.find(session[:user_id])
38 user = User.find(session[:user_id])
7
39
8 if (user!=nil) and (session[:admin])
40 if (user!=nil) and (session[:admin])
9 # admin menu
41 # admin menu
10 menu_items << "<b>Administrative task:</b> "
42 menu_items << "<b>Administrative task:</b> "
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
43 append_to menu_items, '[Announcements]', 'announcements', 'index'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
44 append_to menu_items, '[Msg console]', 'messages', 'console'
13 append_to menu_items, '[Problems]', 'problems', 'index'
45 append_to menu_items, '[Problems]', 'problems', 'index'
14 append_to menu_items, '[Users]', 'user_admin', 'index'
46 append_to menu_items, '[Users]', 'user_admin', 'index'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
47 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
@@ -66,24 +98,52
66 d = duration.to_f
98 d = duration.to_f
67 return Time.at(d).gmtime.strftime("%X")
99 return Time.at(d).gmtime.strftime("%X")
68 end
100 end
69
101
70 def read_textfile(fname,max_size=2048)
102 def read_textfile(fname,max_size=2048)
71 begin
103 begin
72 File.open(fname).read(max_size)
104 File.open(fname).read(max_size)
73 rescue
105 rescue
74 nil
106 nil
75 end
107 end
76 end
108 end
77
109
110 + def toggle_button(on,toggle_url,id, option={})
111 + btn_size = option[:size] || 'btn-xs'
112 + link_to (on ? "Yes" : "No"), toggle_url,
113 + {class: "btn btn-block #{btn_size} btn-#{on ? 'success' : 'default'} ajax-toggle",
114 + id: id,
115 + data: {remote: true, method: 'get'}}
116 + end
117 +
118 + def get_ace_mode(language)
119 + # return ace mode string from Language
120 +
121 + case language.pretty_name
122 + when 'Pascal'
123 + 'ace/mode/pascal'
124 + when 'C++','C'
125 + 'ace/mode/c_cpp'
126 + when 'Ruby'
127 + 'ace/mode/ruby'
128 + when 'Python'
129 + 'ace/mode/python'
130 + when 'Java'
131 + 'ace/mode/java'
132 + else
133 + 'ace/mode/c_cpp'
134 + end
135 + end
136 +
137 +
78 def user_title_bar(user)
138 def user_title_bar(user)
79 header = ''
139 header = ''
80 time_left = ''
140 time_left = ''
81
141
82 #
142 #
83 # if the contest is over
143 # if the contest is over
84 if GraderConfiguration.time_limit_mode?
144 if GraderConfiguration.time_limit_mode?
85 if user.contest_finished?
145 if user.contest_finished?
86 header = <<CONTEST_OVER
146 header = <<CONTEST_OVER
87 <tr><td colspan="2" align="center">
147 <tr><td colspan="2" align="center">
88 <span class="contest-over-msg">THE CONTEST IS OVER</span>
148 <span class="contest-over-msg">THE CONTEST IS OVER</span>
89 </td></tr>
149 </td></tr>
@@ -53,24 +53,28
53
53
54 def self.download_file_basedir
54 def self.download_file_basedir
55 return "#{Rails.root}/data/tasks"
55 return "#{Rails.root}/data/tasks"
56 end
56 end
57
57
58 def get_submission_stat
58 def get_submission_stat
59 result = Hash.new
59 result = Hash.new
60 #total number of submission
60 #total number of submission
61 result[:total_sub] = Submission.where(problem_id: self.id).count
61 result[:total_sub] = Submission.where(problem_id: self.id).count
62 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
62 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
63 end
63 end
64
64
65 + def long_name
66 + "[#{name}] #{full_name}"
67 + end
68 +
65 protected
69 protected
66
70
67 def self.to_i_or_default(st, default)
71 def self.to_i_or_default(st, default)
68 if st!=''
72 if st!=''
69 result = st.to_i
73 result = st.to_i
70 end
74 end
71 result ||= default
75 result ||= default
72 end
76 end
73
77
74 def self.to_f_or_default(st, default)
78 def self.to_f_or_default(st, default)
75 if st!=''
79 if st!=''
76 result = st.to_f
80 result = st.to_f
@@ -230,25 +230,25
230 stat = self.contest_stat
230 stat = self.contest_stat
231 return ((stat != nil) and (stat.started_at != nil))
231 return ((stat != nil) and (stat.started_at != nil))
232 elsif GraderConfiguration.contest_mode?
232 elsif GraderConfiguration.contest_mode?
233 return true if site==nil
233 return true if site==nil
234 return site.started
234 return site.started
235 else
235 else
236 return true
236 return true
237 end
237 end
238 end
238 end
239
239
240 def update_start_time
240 def update_start_time
241 stat = self.contest_stat
241 stat = self.contest_stat
242 - if stat == nil or stat.started_at == nil
242 + if (stat.nil?) or (stat.started_at.nil?)
243 stat ||= UserContestStat.new(:user => self)
243 stat ||= UserContestStat.new(:user => self)
244 stat.started_at = Time.now.gmtime
244 stat.started_at = Time.now.gmtime
245 stat.save
245 stat.save
246 end
246 end
247 end
247 end
248
248
249 def problem_in_user_contests?(problem)
249 def problem_in_user_contests?(problem)
250 problem_contests = problem.contests.all
250 problem_contests = problem.contests.all
251
251
252 if problem_contests.length == 0 # this is public contest
252 if problem_contests.length == 0 # this is public contest
253 return true
253 return true
254 end
254 end
@@ -1,30 +1,32
1 - - content_for :header do
1 + /- content_for :header do
2 - = javascript_include_tag 'local_jquery'
2 + / = javascript_include_tag 'local_jquery'
3
3
4 %h1 System configuration
4 %h1 System configuration
5
5
6 %table.info
6 %table.info
7 %tr.info-head
7 %tr.info-head
8 %th Key
8 %th Key
9 %th Type
9 %th Type
10 %th Value
10 %th Value
11 %th Description
11 %th Description
12 - @configurations.each do |conf|
12 - @configurations.each do |conf|
13 - @grader_configuration = conf
13 - @grader_configuration = conf
14 %tr{:class => cycle("info-odd", "info-even")}
14 %tr{:class => cycle("info-odd", "info-even")}
15 %td
15 %td
16 - = in_place_editor_field :grader_configuration, :key, {}, :rows=>1
16 + /= in_place_editor_field :grader_configuration, :key, {}, :rows=>1
17 + = @grader_configuration.key
17 %td
18 %td
18 - = in_place_editor_field :grader_configuration, :value_type, {}, :rows=>1
19 + /= in_place_editor_field :grader_configuration, :value_type, {}, :rows=>1
20 + = @grader_configuration.value_type
19 %td
21 %td
20 = best_in_place @grader_configuration, :value, ok_button: "ok", cancel_button: "cancel"
22 = best_in_place @grader_configuration, :value, ok_button: "ok", cancel_button: "cancel"
21 %td= conf.description
23 %td= conf.description
22
24
23 - if GraderConfiguration.config_cached?
25 - if GraderConfiguration.config_cached?
24 %br/
26 %br/
25 Your config is saved, but it does not automatically take effect.
27 Your config is saved, but it does not automatically take effect.
26 %br/
28 %br/
27 If you have one mongrel process running, you can
29 If you have one mongrel process running, you can
28 = link_to '[click]', :action => 'reload'
30 = link_to '[click]', :action => 'reload'
29 here to reload.
31 here to reload.
30 %br/
32 %br/
@@ -1,11 +1,11
1
1
2 %td= grader.host
2 %td= grader.host
3 %td= grader.pid
3 %td= grader.pid
4 %td= grader.mode
4 %td= grader.mode
5 - %td= grader.updated_at.strftime("%H:%M:%S") if grader.updated_at!=nil
5 + %td= grader.updated_at.strftime("%H:%M:%S") unless grader.updated_at.nil?
6 %td= grader.task_type
6 %td= grader.task_type
7 %td
7 %td
8 - - if grader.task_id==nil
8 + - if grader.task_id.nil?
9 idle
9 idle
10 - else
10 - else
11 = link_to "#{grader.task_id}", :action => 'view', :id => grader.task_id, :type => grader.task_type
11 = link_to "#{grader.task_id}", :action => 'view', :id => grader.task_id, :type => grader.task_type
@@ -1,25 +1,26
1 - if grader_list.length!=0
1 - if grader_list.length!=0
2 - %table.graders
2 + %table.table.table-striped.table-condensed
3 %tr
3 %tr
4 %th host
4 %th host
5 %th pid
5 %th pid
6 %th mode
6 %th mode
7 %th last updated
7 %th last updated
8 %th type
8 %th type
9 %th task
9 %th task
10 + %th
10 - grader_list.each do |grader|
11 - grader_list.each do |grader|
11 - if grader.active
12 - if grader.active
12 - c = 'active'
13 - c = 'active'
13 - else
14 - else
14 - c = 'inactive'
15 - c = 'inactive'
15 %tr{:class => c}
16 %tr{:class => c}
16 = render :partial => 'grader', :locals => {:grader => grader}
17 = render :partial => 'grader', :locals => {:grader => grader}
17 - if not grader.terminated
18 - if not grader.terminated
18 - if GraderScript.grader_control_enabled?
19 - if GraderScript.grader_control_enabled?
19 - %td= link_to 'stop', {:action => 'stop', :id => grader}
20 + %td= link_to 'stop', {:action => 'stop', :id => grader}, class: 'btn btn-danger btn-xs btn-block'
20 - else
21 - else
21 - %td= link_to 'clear', {:action => 'clear', :id => grader}
22 + %td= link_to 'clear', {:action => 'clear', :id => grader}, class: 'btn btn-danger btn-xs btn-block'
22 - else
23 - else
23 %ul
24 %ul
24 %li None
25 %li None
25
26
@@ -1,73 +1,81
1 - content_for :head do
1 - content_for :head do
2 - = stylesheet_link_tag 'graders'
3 - = javascript_include_tag 'local_jquery'
4 <meta http-equiv ="refresh" content="60"/>
2 <meta http-equiv ="refresh" content="60"/>
5
3
6 %h1 Grader information
4 %h1 Grader information
7
5
8 - = link_to '[Refresh]', :action => 'list'
6 + %p
9 - %br/
7 + = link_to 'Refresh', { :action => 'list' }, class: 'btn btn-info'
8 +
9 + .panel.panel-primary
10 + .panel-heading
11 + Grader control:
12 + .panel-body
13 + =link_to 'Start Graders in grading env', { action: 'start_grading'}, class: 'btn btn-default', method: 'post'
14 + =link_to 'Start Graders in exam env', { action: 'start_exam'}, class: 'btn btn-default', method: 'post'
15 + =link_to 'Stop all running Graders', { action: 'stop_all'}, class: 'btn btn-default', method: 'post'
16 + =link_to 'Clear all data', { action: 'clear_all'}, class: 'btn btn-default', method: 'post'
10
17
11 .submitbox
18 .submitbox
12 .item
19 .item
13 Grader control:
20 Grader control:
14 .item
21 .item
15 = form_for :clear, :url => {:action => 'start_grading'} do |f|
22 = form_for :clear, :url => {:action => 'start_grading'} do |f|
16 = submit_tag 'Start graders in grading env'
23 = submit_tag 'Start graders in grading env'
17 .item
24 .item
18 = form_for :clear, :url => {:action => 'start_exam'} do |f|
25 = form_for :clear, :url => {:action => 'start_exam'} do |f|
19 = submit_tag 'Start graders in exam env'
26 = submit_tag 'Start graders in exam env'
20 .item
27 .item
21 = form_for :clear, :url => {:action => 'stop_all'} do |f|
28 = form_for :clear, :url => {:action => 'stop_all'} do |f|
22 = submit_tag 'Stop all running graders'
29 = submit_tag 'Stop all running graders'
23 .item
30 .item
24 = form_for :clear, :url => {:action => 'clear_all'} do |f|
31 = form_for :clear, :url => {:action => 'clear_all'} do |f|
25 = submit_tag 'Clear all data'
32 = submit_tag 'Clear all data'
26 %br{:style => 'clear:both'}/
33 %br{:style => 'clear:both'}/
27
34
28 - %div{style: 'width:500px; float: left;'}
35 + .row
36 + .col-md-6
29 - if @last_task
37 - if @last_task
30 Last task:
38 Last task:
31 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
39 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
32
40
33 %br/
41 %br/
34
42
35 - if @last_test_request
43 - if @last_test_request
36 Last test_request:
44 Last test_request:
37 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
45 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
38
46
39 %h2 Current graders
47 %h2 Current graders
40
48
41 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
49 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
42
50
43 %h2 Stalled graders
51 %h2 Stalled graders
44
52
45 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
53 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
46
54
47 %h2 Terminated graders
55 %h2 Terminated graders
48
56
49 - = form_for :clear, :url => {:action => 'clear_terminated'} do |f|
57 + %p= link_to 'Clear data for terminated graders', { action: 'clear_terminated'}, class: 'btn btn-default', method: 'post'
50 - = submit_tag 'Clear data for terminated graders'
51
58
52 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
59 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
53 - %div{}
60 + .col-md-6
54 %h2 Last 20 submissions
61 %h2 Last 20 submissions
55 - %table.graders
62 + %table.table.table-striped.table-condensed
56 %thead
63 %thead
57 %th ID
64 %th ID
58 %th User
65 %th User
59 %th Problem
66 %th Problem
60 %th Submitted
67 %th Submitted
61 %th Graded
68 %th Graded
62 %th Result
69 %th Result
70 + %th
63 %tbody
71 %tbody
64 - @submission.each do |sub|
72 - @submission.each do |sub|
65 %tr.inactive
73 %tr.inactive
66 %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
74 %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
67 %td= sub.try(:user).try(:full_name)
75 %td= sub.try(:user).try(:full_name)
68 %td= sub.try(:problem).try(:full_name)
76 %td= sub.try(:problem).try(:full_name)
69 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
77 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
70 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
78 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
71 %td= sub.grader_comment
79 %td= sub.grader_comment
72
80
73
81
@@ -1,67 +1,90
1 - %style{type: "text/css"}
1 + //%style{type: "text/css"}
2 - = @css_style
2 + // = @css_style
3 - :css
4 - .field {
5 - font-weight: bold;
6 - text-align: right;
7 - padding: 3px;
8 - }
9 -
10
3
11 %h1= "Submission: #{@submission.id}"
4 %h1= "Submission: #{@submission.id}"
12
5
13 -
6 + %textarea#data{style: "display:none;"}
14 - %h2 Stat
7 + :preserve
8 + #{@submission.source}
15
9
16 - %table.info
10 + //%div.highlight{:style => "border: 1px solid black;"}
17 - %thead
11 + //=@formatted_code.html_safe
18 - %tr.info-head
12 + .containter
19 - %th Field
13 + .row
20 - %th Value
14 + .col-md-7
21 - %tbody
15 + %h2 Source Code
22 - %tr{class: cycle('info-even','info-odd')}
16 + .col-md-5
23 - %td.field User:
17 + %h2 Stat
24 - %td.value
18 + .row
19 + .col-md-7
20 + %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
21 + :javascript
22 + e = ace.edit("editor")
23 + e.setOptions({ maxLines: Infinity })
24 + e.setValue($("#data").text())
25 + e.gotoLine(1)
26 + e.getSession().setMode("#{get_ace_mode(@submission.language)}")
27 + e.setReadOnly(true)
28 + .col-md-5
29 + %table.table.table-striped
30 + %tr
31 + %td.text-right
32 + %strong User
33 + %td
25 - if @submission.user
34 - if @submission.user
26 = link_to "(#{@submission.user.login})", controller: "users", action: "profile", id: @submission.user
35 = link_to "(#{@submission.user.login})", controller: "users", action: "profile", id: @submission.user
27 = @submission.user.full_name
36 = @submission.user.full_name
28 - else
37 - else
29 = "(n/a)"
38 = "(n/a)"
30 - %tr{class: cycle('info-even','info-odd')}
39 + %tr
31 - %td.field Problem:
40 + %td.text-right
32 - %td.value
41 + %strong Task
42 + %td
33 - if @submission.problem!=nil
43 - if @submission.problem!=nil
34 = link_to "(#{@submission.problem.name})", controller: "problems", action: "stat", id: @submission.problem
44 = link_to "(#{@submission.problem.name})", controller: "problems", action: "stat", id: @submission.problem
35 = @submission.problem.full_name
45 = @submission.problem.full_name
36 - else
46 - else
37 = "(n/a)"
47 = "(n/a)"
38 - %tr{class: cycle('info-even','info-odd')}
48 + %tr
39 - %td.field Tries:
49 + %td.text-right
40 - %td.value= @submission.number
50 + %strong Tries
41 - %tr{class: cycle('info-even','info-odd')}
51 + %td= @submission.number
42 - %td.field Submitted:
52 + %tr
43 - %td.value #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
53 + %td.text-right
44 - %tr{class: cycle('info-even','info-odd')}
54 + %strong Language
45 - %td.field Graded:
55 + %td= @submission.language.pretty_name
46 - %td.value #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
56 + %tr
47 - %tr{class: cycle('info-even','info-odd')}
57 + %td.text-right
48 - %td.field Points:
58 + %strong Submitted
49 - %td.value #{@submission.points}/#{@submission.problem.full_score}
59 + %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
50 - %tr{class: cycle('info-even','info-odd')}
60 + %tr
51 - %td.field Comment:
61 + %td.text-right
52 - %td.value #{@submission.grader_comment}
62 + %strong Graded
53 - %tr{class: cycle('info-even','info-odd')}
63 + - if @submission.graded_at
54 - %td.field Runtime (s):
64 + %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
55 - %td.value #{@submission.max_runtime}
65 + - else
56 - %tr{class: cycle('info-even','info-odd')}
66 + %td -
57 - %td.field Memory (kb):
67 + %tr
58 - %td.value #{@submission.peak_memory}
68 + %td.text-right
69 + %strong Points
70 + %td #{@submission.points}/#{@submission.problem.full_score}
71 + %tr
72 + %td.text-right
73 + %strong Comment
74 + %td #{@submission.grader_comment}
75 + %tr
76 + %td.text-right
77 + %strong Runtime (s)
78 + %td #{@submission.max_runtime}
79 + %tr
80 + %td.text-right
81 + %strong Memory (kb)
82 + %td #{@submission.peak_memory}
59 - if session[:admin]
83 - if session[:admin]
60 - %tr{class: cycle('info-even','info-odd')}
84 + %tr
61 - %td.field IP:
85 + %td.text-right
62 - %td.value #{@submission.ip_address}
86 + %strong IP
87 + %td #{@submission.ip_address}
63
88
64 - %h2 Source code
65 - //%div.highlight{:style => "border: 1px solid black;"}
66 - =@formatted_code.html_safe
67
89
90 +
@@ -1,19 +1,13
1 - .announcement{:id => "announcement-#{announcement.id}", :style => "#{'display: none; opacity: 0' if (defined? announcement_effect) and announcement_effect }"}
1 + %li.list-group-item
2 - %div
2 + %strong
3 - .announcement-title
4 - -# .toggles
5 - -# %a{:href => '#', :onclick => "$(\"announcement-body-#{announcement.id}\").blindUp({duration: 0.2}); return false;"}
6 - -# [hide]
7 - -# %a{:href => '#', :onclick => "$(\"announcement-body-#{announcement.id}\").blindDown({duration: 0.2}); return false;"}
8 - -# [show]
9 = announcement.title
3 = announcement.title
10 - .announcement-body{:id => "announcement-body-#{announcement.id}"}
4 + %small= "(updated #{time_ago_in_words(announcement.updated_at)} ago on #{announcement.updated_at})"
5 +
6 + %br
11 = markdown(announcement.body)
7 = markdown(announcement.body)
12 - -#.pub-info
13 - -# %p= "#{announcement.author}, #{announcement.created_at}"
14 :javascript
8 :javascript
15 Announcement.updateRecentId(#{announcement.id});
9 Announcement.updateRecentId(#{announcement.id});
16 - if (defined? announcement_effect) and announcement_effect
10 - if (defined? announcement_effect) and announcement_effect
17 :javascript
11 :javascript
18 $("announcement-#{announcement.id}").blindDown({duration: 0.2});
12 $("announcement-#{announcement.id}").blindDown({duration: 0.2});
19 $("announcement-#{announcement.id}").appear({duration: 0.5, queue: 'end'});
13 $("announcement-#{announcement.id}").appear({duration: 0.5, queue: 'end'});
@@ -1,24 +1,26
1
1
2 - %tr{:class => ((submission_counter%2==0) ? "info-even" : "info-odd")}
2 + %tr
3 - %td.info{:align => "center"}
3 + %td{:align => "center"}
4 = submission_counter+1
4 = submission_counter+1
5 - %td.info{:align => "center"}
5 + %td{:align => "center"}
6 = link_to "##{submission.id}", controller: :graders, action: :submission, id: submission.id
6 = link_to "##{submission.id}", controller: :graders, action: :submission, id: submission.id
7 - %td.info
7 + %td
8 = l submission.submitted_at, format: :long
8 = l submission.submitted_at, format: :long
9 = "( #{time_ago_in_words(submission.submitted_at)} ago)"
9 = "( #{time_ago_in_words(submission.submitted_at)} ago)"
10 - %td.info{:align => "center"}
10 + %td
11 = submission.source_filename
11 = submission.source_filename
12 = " (#{submission.language.pretty_name}) "
12 = " (#{submission.language.pretty_name}) "
13 = link_to('[load]',{:action => 'source', :id => submission.id})
13 = link_to('[load]',{:action => 'source', :id => submission.id})
14 - %td.info
14 + %td
15 - - if submission.graded_at!=nil
15 + - if submission.graded_at
16 = "Graded at #{format_short_time(submission.graded_at)}."
16 = "Graded at #{format_short_time(submission.graded_at)}."
17 %br/
17 %br/
18 = "Score: #{(submission.points*100/submission.problem.full_score).to_i} " if GraderConfiguration['ui.show_score']
18 = "Score: #{(submission.points*100/submission.problem.full_score).to_i} " if GraderConfiguration['ui.show_score']
19 = " ["
19 = " ["
20 %tt
20 %tt
21 = submission.grader_comment
21 = submission.grader_comment
22 = "]"
22 = "]"
23 - %td.info
23 + %td
24 = render :partial => 'compiler_message', :locals => {:compiler_message => submission.compiler_message }
24 = render :partial => 'compiler_message', :locals => {:compiler_message => submission.compiler_message }
25 + %td
26 + = link_to 'Edit', direct_edit_submission_path(submission.id), class: 'btn btn-success'
@@ -1,26 +1,26
1
1
2 - - if submission==nil
2 + - if submission.nil?
3 = "-"
3 = "-"
4 - else
4 - else
5 - - if submission.graded_at==nil
5 + - if submission.graded_at.nil?
6 =t 'main.submitted_at'
6 =t 'main.submitted_at'
7 = format_short_time(submission.submitted_at.localtime)
7 = format_short_time(submission.submitted_at.localtime)
8 - else
8 - else
9 = t 'main.graded_at'
9 = t 'main.graded_at'
10 = "#{format_short_time(submission.graded_at.localtime)}, "
10 = "#{format_short_time(submission.graded_at.localtime)}, "
11 - if GraderConfiguration['ui.show_score']
11 - if GraderConfiguration['ui.show_score']
12 = t 'main.score'
12 = t 'main.score'
13 = "#{(submission.points*100/submission.problem.full_score).to_i} "
13 = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 = " ["
14 = " ["
15 %tt
15 %tt
16 = submission.grader_comment
16 = submission.grader_comment
17 = "]"
17 = "]"
18 - if GraderConfiguration.show_grading_result
18 - if GraderConfiguration.show_grading_result
19 = " | "
19 = " | "
20 = link_to '[detailed result]', :action => 'result', :id => submission.id
20 = link_to '[detailed result]', :action => 'result', :id => submission.id
21 = " | "
21 = " | "
22 = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
22 = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
23 = " | "
23 = " | "
24 = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
24 = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
25 - = " | "
25 + //= " | "
26 - = link_to "[#{t 'main.submissions_link'}]", :action => 'submission', :id => problem_name
26 + //= link_to "[#{t 'main.submissions_link'}]", main_submission_path(submission.problem.id)
@@ -1,53 +1,52
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag "announcement_refresh"
2 = javascript_include_tag "announcement_refresh"
3
3
4 = user_title_bar(@user)
4 = user_title_bar(@user)
5
5
6 - .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
7 - %span{:class => 'title'}
8 - Announcements
9 - #announcementbox-body
10 - = render :partial => 'announcement', :collection => @announcements
11 -
12 - - if GraderConfiguration.show_submitbox_to?(@user)
13 - .submitbox
14 - = error_messages_for 'submission'
15 - = render :partial => 'submission_box'
16 -
17 -
18 - %hr/
19 -
20 - if (GraderConfiguration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
6 - if (GraderConfiguration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
21 %p=t 'main.start_soon'
7 %p=t 'main.start_soon'
22
8
9 + .row
10 + .col-md-7
11 + - if GraderConfiguration.show_submitbox_to?(@user)
12 + .panel.panel-primary
13 + .panel-heading
14 + Submission
15 + .panel-body
16 + = render :partial => 'submission_box'
23 - if GraderConfiguration.show_tasks_to?(@user)
17 - if GraderConfiguration.show_tasks_to?(@user)
24 - if not GraderConfiguration.multicontests?
18 - if not GraderConfiguration.multicontests?
25 - %table.info
19 + %table.table.table-striped.table-condensed
26 - %tr.info-head
20 + %thead
27 - %th
21 + %tr
28 - %th Tasks name
22 + %th Task name
29 %th Full name
23 %th Full name
30 %th # of sub(s)
24 %th # of sub(s)
31 %th Results
25 %th Results
26 + %th
27 + %tbody
32 = render :partial => 'problem', :collection => @problems
28 = render :partial => 'problem', :collection => @problems
33 - else
29 - else
34 - @contest_problems.each do |cp|
30 - @contest_problems.each do |cp|
35 - if cp[:problems].length > 0
31 - if cp[:problems].length > 0
36 %h2{:class =>'contest-title'}
32 %h2{:class =>'contest-title'}
37 = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
33 = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
38 %table.info
34 %table.info
39 %tr.info-head
35 %tr.info-head
40 - %th
36 + %th Task name
41 - %th Tasks name
42 %th Full name
37 %th Full name
43 %th # of sub(s)
38 %th # of sub(s)
44 %th Results
39 %th Results
40 + %th
45 = render :partial => 'problem', :collection => cp[:problems]
41 = render :partial => 'problem', :collection => cp[:problems]
46 -
42 + .col-md-5
47 -
43 + .panel.panel-info
48 - %hr/
44 + .panel-heading
45 + Announcement
46 + %ul.list-group
47 + = render :partial => 'announcement', :collection => @announcements
49
48
50 %script{:type => 'text/javascript'}
49 %script{:type => 'text/javascript'}
51 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
50 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
52 Announcement.registerRefreshEventTimer();
51 Announcement.registerRefreshEventTimer();
53
52
@@ -1,25 +1,31
1 = user_title_bar(@user)
1 = user_title_bar(@user)
2
2
3 - .task-menu
3 + .panel.panel-info
4 - Task List
4 + .panel-heading
5 - %br/
5 + Select Problems
6 - - @problems.each do |problem|
6 + .panel-body
7 - = link_to problem.name, :action => 'submission', :id => problem.name
7 + .form-inline
8 + = select 'submission',
9 + 'problem_id',
10 + @problems.collect {|p| ["[#{p.name}] #{p.full_name}", main_submission_url(p.id)]},
11 + { selected: (@problem ? main_submission_url(@problem) : -1) },
12 + { class: 'select2 form-control'}
13 + %button.btn.btn-primary.btn-sm.go-button#problem_go{data: {source: '#submission_problem_id'}} Go
8
14
9 - if @problem!=nil
15 - if @problem!=nil
10 %h2= "Task: #{@problem.full_name} (#{@problem.name})"
16 %h2= "Task: #{@problem.full_name} (#{@problem.name})"
11
17
12 - if @submissions!=nil
18 - if @submissions!=nil
13 - if @submissions.length>0
19 - if @submissions.length>0
14 - %table.info
20 + %table.table
15 - %tr.info-head
21 + %thead
16 - %th.info No.
22 + %th No.
17 - %th.info #
23 + %th #
18 - %th.info At
24 + %th At
19 - %th.info Source
25 + %th Source
20 - %th.info Result
26 + %th Result
21 - %th.info{:width => "300px"}
27 + %th{:width => "300px"} Compiler message
22 - Compiler message
28 + %th
23 = render :partial => 'submission', :collection => @submissions
29 = render :partial => 'submission', :collection => @submissions
24 - else
30 - else
25 No submission
31 No submission
@@ -1,23 +1,12
1 - - content_for :header do
2 - = javascript_include_tag 'local_jquery'
3 -
4 - :javascript
5 - $(document).ready( function() {
6 - $("#mem_remark").hover( function() {
7 - $("#mem_remark_box").show();
8 - }, function() {
9 - $("#mem_remark_box").hide();
10 - });
11 - });
12 :css
1 :css
13 .hof_user { color: orangered; font-style: italic; }
2 .hof_user { color: orangered; font-style: italic; }
14 .hof_language { color: green; font-style: italic; }
3 .hof_language { color: green; font-style: italic; }
15 .hof_value { color: deeppink;font-style: italic; }
4 .hof_value { color: deeppink;font-style: italic; }
16 .info_param { font-weight: bold;text-align: right; }
5 .info_param { font-weight: bold;text-align: right; }
17 .tooltip {
6 .tooltip {
18 font-family: Verdana,sans-serif;
7 font-family: Verdana,sans-serif;
19 font-weight: normal;
8 font-weight: normal;
20 text-align: left;
9 text-align: left;
21 font-size: 1.0em;
10 font-size: 1.0em;
22 color: black;
11 color: black;
23 line-height: 1.1;
12 line-height: 1.1;
@@ -25,103 +14,123
25 min-width: 20em;
14 min-width: 20em;
26 position: absolute;
15 position: absolute;
27 left: 25px;
16 left: 25px;
28 bottom: 5px;
17 bottom: 5px;
29 border: 1px solid;
18 border: 1px solid;
30 padding: 5px;
19 padding: 5px;
31 background-color: #FFF;
20 background-color: #FFF;
32 word-wrap: break-word;
21 word-wrap: break-word;
33 z-index: 9999;
22 z-index: 9999;
34 overflow: auto;
23 overflow: auto;
35 }
24 }
36
25
37 - %h1 (#{Problem.find(params[:id]).name}) #{Problem.find(params[:id]).full_name}
38
26
39 - %h2 Problem Stat
27 + .container
40 - %table.info
28 + .row
29 + .col-md-4
30 + %h2 Overall Stat
31 + %table.table.table-hover
41 %thead
32 %thead
42 - %tr.info-head
33 + %tr
43 - %th Stat
34 + %th
44 - %th Value
35 + %th
45 %tbody
36 %tbody
46 - %tr{class: cycle('info-even','info-odd')}
37 + %tr
47 %td.info_param Submissions
38 %td.info_param Submissions
48 %td= @summary[:count]
39 %td= @summary[:count]
49 - %tr{class: cycle('info-even','info-odd')}
40 + %tr
50 %td.info_param Solved/Attempted User
41 %td.info_param Solved/Attempted User
51 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
42 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
52 - if @best
43 - if @best
53 - %tr{class: cycle('info-even','info-odd')}
44 + %tr
54 %td.info_param Best Runtime
45 %td.info_param Best Runtime
55 %td
46 %td
56 by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
47 by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
57 - using <span class="hof_language">#{@best[:runtime][:lang]}</span>
48 + %br
58 - with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
49 + using <span class="text-success">#{@best[:runtime][:lang]}</span>
50 + %br
51 + with <span class="text-success">#{@best[:runtime][:value] * 1000} milliseconds</span>
52 + %br
59 at submission
53 at submission
60 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
54 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
61
55
62 - %tr{class: cycle('info-even','info-odd')}
56 + %tr
63 %td.info_param
57 %td.info_param
64 Best Memory Usage
58 Best Memory Usage
65 - %sup{ id: "mem_remark", style: "position:relative; color: blue;"}
59 + %sup{ id: "xmem_remark",
60 + style: "position:relative; color: blue;",
61 + data: {toggle: 'tooltip', placement: 'top', animation: 'false', delay: 20},
62 + title: "This counts only for submission with 100% score. Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)"}
66 [?]
63 [?]
67 - %span.tooltip#mem_remark_box
68 - This counts only for submission with 100% score.
69 - Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
70 %td
64 %td
71 by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
65 by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
72 - using <span class="hof_language">#{@best[:memory][:lang]}</span>
66 + %br
73 - with <span class="hof_value">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
67 + using <span class="text-success">#{@best[:memory][:lang]}</span>
68 + %br
69 + with <span class="text-success">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
70 + %br
74 at submission
71 at submission
75 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
72 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
76
73
77 - %tr{class: cycle('info-even','info-odd')}
74 + %tr
78 %td.info_param Shortest Code
75 %td.info_param Shortest Code
79 %td
76 %td
80 by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
77 by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
81 - using <span class="hof_language">#{@best[:length][:lang]}</span>
78 + %br
82 - with <span class="hof_value">#{@best[:length][:value]} bytes</span>
79 + using <span class="text-success">#{@best[:length][:lang]}</span>
80 + %br
81 + with <span class="text-success">#{@best[:length][:value]} bytes</span>
82 + %br
83 at submission
83 at submission
84 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
84 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
85
85
86 - %tr{class: cycle('info-even','info-odd')}
86 + %tr
87 %td.info_param First solver
87 %td.info_param First solver
88 %td
88 %td
89 + - if @best[:first][:user] != '(NULL)'
89 #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
90 #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
90 - using <span class="hof_language">#{@best[:first][:lang]}</span>
91 + %br
91 - on <span class="hof_value">#{@best[:first][:value]}</span>
92 + using <span class="text-success">#{@best[:first][:lang]}</span>
93 + %br
94 + on <span class="text-success">#{@best[:first][:value]}</span>
95 + %br
92 at submission
96 at submission
93 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
97 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
94 -
98 + - else
99 + no first solver
100 + .col-md-8
95 - if @best
101 - if @best
96 - %h2 By language
102 + %h2 By Language
97 -
103 + %table.table.table-hover
98 - %table.info
99 %thead
104 %thead
100 - %tr.info-head
105 + %tr
101 %th Language
106 %th Language
102 %th Best runtime (ms)
107 %th Best runtime (ms)
103 %th Best memory (kbytes)
108 %th Best memory (kbytes)
104 %th Shortest Code (bytes)
109 %th Shortest Code (bytes)
105 %th First solver
110 %th First solver
106 %tbody
111 %tbody
107 - @by_lang.each do |lang,value|
112 - @by_lang.each do |lang,value|
108 - %tr{class: cycle('info-even','info-odd')}
113 + %tr
109 %td= lang
114 %td= lang
110 %td
115 %td
111 = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
116 = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
117 + %br
112 = "(#{(value[:runtime][:value] * 1000).to_i} @"
118 = "(#{(value[:runtime][:value] * 1000).to_i} @"
113 = "#{link_to("#" + value[:runtime][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:runtime][:sub_id])} )".html_safe
119 = "#{link_to("#" + value[:runtime][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:runtime][:sub_id])} )".html_safe
114 %td
120 %td
115 = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
121 = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
122 + %br
116 = "(#{number_with_delimiter(value[:memory][:value])} @"
123 = "(#{number_with_delimiter(value[:memory][:value])} @"
117 = "#{link_to("#" + value[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:memory][:sub_id])} )".html_safe
124 = "#{link_to("#" + value[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:memory][:sub_id])} )".html_safe
118 %td
125 %td
119 = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
126 = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
127 + %br
120 = "(#{value[:length][:value]} @"
128 = "(#{value[:length][:value]} @"
121 = "#{link_to("#" + value[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:length][:sub_id])} )".html_safe
129 = "#{link_to("#" + value[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:length][:sub_id])} )".html_safe
122 %td
130 %td
123 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
131 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
124 = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
132 = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
133 + %br
125 = "(#{value[:first][:value]} @"
134 = "(#{value[:first][:value]} @"
126 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
135 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
127
136
@@ -1,23 +1,29
1
1
2 /- if params[:id]
2 /- if params[:id]
3 / %h1 Tasks Hall of Fame
3 / %h1 Tasks Hall of Fame
4 / = link_to('[back to All-Time Hall of Fame]', action: 'problem_hof', id: nil )
4 / = link_to('[back to All-Time Hall of Fame]', action: 'problem_hof', id: nil )
5 /- else
5 /- else
6 / %h1 All-Time Hall of Fame
6 / %h1 All-Time Hall of Fame
7
7
8 + .panel.panel-info
9 + .panel-heading
10 + Select Task
11 + .panel-body
12 + .form-inline
13 + = select 'report',
14 + 'problem_id',
15 + @problems.collect {|p| ["[#{p.name}] #{p.full_name}", report_problem_hof_url(p.id)]},
16 + {:selected => report_problem_hof_url(@problem)},
17 + { class: 'select2 form-control' }
18 + %button.btn.btn-primary.btn-sm.go-button#problem_go{data: {source: "#report_problem_id"}} Go
8
19
9 - %h1 Hall of Fame
10 - .task-menu
11 - Tasks
12 - %br/
13 - - @problems.each do |prob|
14 - = link_to( "[#{prob.name}]", {id: prob.id})
15
20
16 - unless params[:id]
21 - unless params[:id]
17 /=render partial: 'all_time_hof'
22 /=render partial: 'all_time_hof'
18 Please select a problem.
23 Please select a problem.
19 - else
24 - else
20 - =render partial: 'task_hof'
25 + %h1 [#{Problem.find(params[:id]).name}] #{Problem.find(params[:id]).full_name}
21 %h2 Submission History
26 %h2 Submission History
22 =render partial: 'application/bar_graph', locals: { histogram: @histogram }
27 =render partial: 'application/bar_graph', locals: { histogram: @histogram }
28 + =render partial: 'task_hof'
23
29
@@ -1,59 +1,61
1 - - content_for :header do
1 + /- content_for :header do
2 - = javascript_include_tag 'local_jquery'
2 + / = javascript_include_tag 'local_jquery'
3 - = stylesheet_link_tag 'tablesorter-theme.cafe'
3 + / = stylesheet_link_tag 'tablesorter-theme.cafe'
4
4
5 %script{:type=>"text/javascript"}
5 %script{:type=>"text/javascript"}
6 $(function () {
6 $(function () {
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
9 - $('#my_table').tablesorter({widgets: ['zebra']});
9 + /$('#my_table').tablesorter({widgets: ['zebra']});
10 });
10 });
11
11
12 %h1 User grading results
12 %h1 User grading results
13 %h2= params[:action] == 'user_stat' ? "Show scores from latest submission" : "Show max scores in submission range"
13 %h2= params[:action] == 'user_stat' ? "Show scores from latest submission" : "Show max scores in submission range"
14
14
15
15
16 - if @problem and @problem.errors
16 - if @problem and @problem.errors
17 =error_messages_for 'problem'
17 =error_messages_for 'problem'
18
18
19 = render partial: 'submission_range'
19 = render partial: 'submission_range'
20
20
21 - if params[:action] == 'user_stat'
21 - if params[:action] == 'user_stat'
22 %h3 Latest score
22 %h3 Latest score
23 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat, commit: 'download csv'
23 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat, commit: 'download csv'
24 - else
24 - else
25 %h3 Max score
25 %h3 Max score
26 = link_to '[Show only latest submissions]', controller: :user_admin, action: :user_stat
26 = link_to '[Show only latest submissions]', controller: :user_admin, action: :user_stat
27 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat_max, commit: 'download csv'
27 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat_max, commit: 'download csv'
28
28
29 - %table.tablesorter-cafe#my_table
29 + %table.table.sortable.table-striped.table-bordered
30 %thead
30 %thead
31 %tr
31 %tr
32 - %th User
32 + %th Login
33 %th Name
33 %th Name
34 %th Activated?
34 %th Activated?
35 - %th Logged in
35 + %th Logged_in
36 %th Contest(s)
36 %th Contest(s)
37 %th Remark
37 %th Remark
38 - @problems.each do |p|
38 - @problems.each do |p|
39 - %th= p.name
39 + %th.text-right= p.name
40 - %th Total
40 + %th.text-right Total
41 - %th Passed
41 + %th.text-right Passed
42 %tbody
42 %tbody
43 - @scorearray.each do |sc|
43 - @scorearray.each do |sc|
44 - %tr{class: cycle('info-even','info-odd')}
44 + %tr
45 - total,num_passed = 0,0
45 - total,num_passed = 0,0
46 - sc.each_index do |i|
46 - sc.each_index do |i|
47 - if i == 0
47 - if i == 0
48 %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
48 %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
49 %td= sc[i].full_name
49 %td= sc[i].full_name
50 %td= sc[i].activated
50 %td= sc[i].activated
51 %td= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no'
51 %td= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no'
52 %td= sc[i].contests.collect {|c| c.name}.join(', ')
52 %td= sc[i].contests.collect {|c| c.name}.join(', ')
53 %td= sc[i].remark
53 %td= sc[i].remark
54 - else
54 - else
55 - %td= sc[i][0]
55 + %td.text-right= sc[i][0]
56 - total += sc[i][0]
56 - total += sc[i][0]
57 - num_passed += 1 if sc[i][1]
57 - num_passed += 1 if sc[i][1]
58 - %td= total
58 + %td.text-right= total
59 - %td= num_passed
59 + %td.text-right= num_passed
60 + :javascript
61 + $.bootstrapSortable(true,'reversed')
@@ -50,16 +50,21
50 # Enforce whitelist mode for mass assignment.
50 # Enforce whitelist mode for mass assignment.
51 # This will create an empty whitelist of attributes available for mass-assignment for all models
51 # This will create an empty whitelist of attributes available for mass-assignment for all models
52 # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
52 # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 # parameters by using an attr_accessible or attr_protected declaration.
53 # parameters by using an attr_accessible or attr_protected declaration.
54 config.active_record.whitelist_attributes = false
54 config.active_record.whitelist_attributes = false
55
55
56 # Enable the asset pipeline
56 # Enable the asset pipeline
57 config.assets.enabled = true
57 config.assets.enabled = true
58
58
59 # Version of your assets, change this if you want to expire all your assets
59 # Version of your assets, change this if you want to expire all your assets
60 config.assets.version = '1.0'
60 config.assets.version = '1.0'
61
61
62 - config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js','graders.css','problems.css']
62 + config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js']
63 config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css']
63 config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css']
64 + %w( announcements configurations contests contest_management graders heartbeat
65 + login main messages problems report site sites sources tasks
66 + test user_admin users ).each do |controller|
67 + config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
64 end
68 end
65 end
69 end
70 + end
@@ -27,14 +27,14
27
27
28 # Log the query plan for queries taking more than this (works
28 # Log the query plan for queries taking more than this (works
29 # with SQLite, MySQL, and PostgreSQL)
29 # with SQLite, MySQL, and PostgreSQL)
30 config.active_record.auto_explain_threshold_in_seconds = 0.5
30 config.active_record.auto_explain_threshold_in_seconds = 0.5
31
31
32 # Do not compress assets
32 # Do not compress assets
33 config.assets.compress = false
33 config.assets.compress = false
34
34
35 # Expands the lines which load the assets
35 # Expands the lines which load the assets
36 config.assets.debug = true
36 config.assets.debug = true
37
37
38 # Prevents assets from rendering twice
38 # Prevents assets from rendering twice
39 - config.serve_static_assets = false
39 + config.serve_static_assets = true
40 end
40 end
@@ -10,25 +10,25
10 password_label: 'Password'
10 password_label: 'Password'
11
11
12 go_ahead_to: "Go ahead to "
12 go_ahead_to: "Go ahead to "
13 go_back_to: "Go back to "
13 go_back_to: "Go back to "
14 login_page: "login page"
14 login_page: "login page"
15 home_page: "home page"
15 home_page: "home page"
16
16
17 menu:
17 menu:
18 main: 'Main'
18 main: 'Main'
19 messages: 'Messages'
19 messages: 'Messages'
20 tasks: 'Tasks'
20 tasks: 'Tasks'
21 submissions: 'Submissions'
21 submissions: 'Submissions'
22 - test: 'Test Interface'
22 + test: 'Test'
23 hall_of_fame: 'Hall of Fame'
23 hall_of_fame: 'Hall of Fame'
24 help: 'Help'
24 help: 'Help'
25 settings: 'Settings'
25 settings: 'Settings'
26 log_out: 'Log out'
26 log_out: 'Log out'
27
27
28 title_bar:
28 title_bar:
29 current_time: "Current time is"
29 current_time: "Current time is"
30 remaining_time: "Time left: "
30 remaining_time: "Time left: "
31 contest_not_started: "The contest has not started."
31 contest_not_started: "The contest has not started."
32
32
33 login:
33 login:
34 message: 'Please login to see the problem list'
34 message: 'Please login to see the problem list'
@@ -1,74 +1,63
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 - get "report/login"
2 + get "sources/direct_edit"
3 +
4 + root :to => 'main#login'
3
5
4 resources :contests
6 resources :contests
5
7
6 - resources :announcements
7 resources :sites
8 resources :sites
8
9
10 + resources :announcements do
11 + member do
12 + get 'toggle','toggle_front'
13 + end
14 + end
15 +
16 + resources :problems do
17 + member do
18 + get 'toggle'
19 + get 'toggle_test'
20 + end
21 + collection do
22 + get 'turn_all_off'
23 + get 'turn_all_on'
24 + get 'import'
25 + get 'manage'
26 + end
27 + end
28 +
9 resources :grader_configuration, controller: 'configurations'
29 resources :grader_configuration, controller: 'configurations'
10
30
11 - # The priority is based upon order of creation:
31 + resources :users do
12 - # first created -> highest priority.
32 + member do
13 -
33 + get 'toggle_activate', 'toggle_enable'
14 - # Sample of regular route:
34 + end
15 - # match 'products/:id' => 'catalog#view'
35 + end
16 - # Keep in mind you can assign values other than :controller and :action
17 -
18 - # Sample of named route:
19 - # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
20 - # This route can be invoked with purchase_url(:id => product.id)
21 -
22 - # Sample resource route (maps HTTP verbs to controller actions automatically):
23 - # resources :products
24 -
25 - # Sample resource route with options:
26 - # resources :products do
27 - # member do
28 - # get 'short'
29 - # post 'toggle'
30 - # end
31 - #
32 - # collection do
33 - # get 'sold'
34 - # end
35 - # end
36
36
37 - # Sample resource route with sub-resources:
37 + #source code edit
38 - # resources :products do
38 + get 'sources/direct_edit/:pid', to: 'sources#direct_edit', as: 'direct_edit'
39 - # resources :comments, :sales
39 + get 'sources/direct_edit_submission/:sid', to: 'sources#direct_edit_submission', as: 'direct_edit_submission'
40 - # resource :seller
40 + get 'sources/get_latest_submission_status/:uid/:pid', to: 'sources#get_latest_submission_status', as: 'get_latest_submission_status'
41 - # end
42
41
43 - # Sample resource route with more complex sub-resources
44 - # resources :products do
45 - # resources :comments
46 - # resources :sales do
47 - # get 'recent', :on => :collection
48 - # end
49 - # end
50 -
51 - # Sample resource route within a namespace:
52 - # namespace :admin do
53 - # # Directs /admin/products/* to Admin::ProductsController
54 - # # (app/controllers/admin/products_controller.rb)
55 - # resources :products
56 - # end
57 -
58 - # You can have the root of your site routed with "root"
59 - # just remember to delete public/index.html.
60 - # root :to => 'welcome#index'
61 -
62 - root :to => 'main#login'
63
42
64 match 'tasks/view/:file.:ext' => 'tasks#view'
43 match 'tasks/view/:file.:ext' => 'tasks#view'
65 match 'tasks/download/:id/:file.:ext' => 'tasks#download'
44 match 'tasks/download/:id/:file.:ext' => 'tasks#download'
45 + match 'heartbeat/:id/edit' => 'heartbeat#edit'
66
46
67 - match 'heartbeat/:id/edit' => 'heartbeat#edit'
47 + #main
48 + get "main/list"
49 + get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
50 +
51 + #report
52 + get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
53 + get "report/login"
54 +
55 + #grader
56 + get 'graders/list', to: 'graders#list', as: 'grader_list'
68
57
69 # See how all your routes lay out with "rake routes"
58 # See how all your routes lay out with "rake routes"
70
59
71 # This is a legacy wild controller route that's not recommended for RESTful applications.
60 # This is a legacy wild controller route that's not recommended for RESTful applications.
72 # Note: This route will make all actions in every controller accessible via GET requests.
61 # Note: This route will make all actions in every controller accessible via GET requests.
73 match ':controller(/:action(/:id))(.:format)'
62 match ':controller(/:action(/:id))(.:format)'
74 end
63 end
@@ -6,25 +6,25
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 ActiveRecord::Schema.define(:version => 20150916054105) do
14 ActiveRecord::Schema.define(:version => 20150916054105) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 - t.text "body", :limit => 16777215
18 + t.text "body"
19 t.boolean "published"
19 t.boolean "published"
20 t.datetime "created_at", :null => false
20 t.datetime "created_at", :null => false
21 t.datetime "updated_at", :null => false
21 t.datetime "updated_at", :null => false
22 t.boolean "frontpage", :default => false
22 t.boolean "frontpage", :default => false
23 t.boolean "contest_only", :default => false
23 t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
27
27
28 create_table "contests", :force => true do |t|
28 create_table "contests", :force => true do |t|
29 t.string "title"
29 t.string "title"
30 t.boolean "enabled"
30 t.boolean "enabled"
@@ -41,37 +41,37
41 create_table "contests_users", :id => false, :force => true do |t|
41 create_table "contests_users", :id => false, :force => true do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 create_table "countries", :force => true do |t|
46 create_table "countries", :force => true do |t|
47 t.string "name"
47 t.string "name"
48 t.datetime "created_at", :null => false
48 t.datetime "created_at", :null => false
49 t.datetime "updated_at", :null => false
49 t.datetime "updated_at", :null => false
50 end
50 end
51
51
52 create_table "descriptions", :force => true do |t|
52 create_table "descriptions", :force => true do |t|
53 - t.text "body", :limit => 16777215
53 + t.text "body"
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 t.datetime "created_at", :null => false
55 t.datetime "created_at", :null => false
56 t.datetime "updated_at", :null => false
56 t.datetime "updated_at", :null => false
57 end
57 end
58
58
59 create_table "grader_configurations", :force => true do |t|
59 create_table "grader_configurations", :force => true do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
63 t.datetime "created_at", :null => false
63 t.datetime "created_at", :null => false
64 t.datetime "updated_at", :null => false
64 t.datetime "updated_at", :null => false
65 - t.text "description", :limit => 16777215
65 + t.text "description"
66 end
66 end
67
67
68 create_table "grader_processes", :force => true do |t|
68 create_table "grader_processes", :force => true do |t|
69 t.string "host", :limit => 20
69 t.string "host", :limit => 20
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", :null => false
73 t.datetime "created_at", :null => false
74 t.datetime "updated_at", :null => false
74 t.datetime "updated_at", :null => false
75 t.integer "task_id"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
@@ -98,25 +98,25
98
98
99 create_table "logins", :force => true do |t|
99 create_table "logins", :force => true do |t|
100 t.integer "user_id"
100 t.integer "user_id"
101 t.string "ip_address"
101 t.string "ip_address"
102 t.datetime "created_at", :null => false
102 t.datetime "created_at", :null => false
103 t.datetime "updated_at", :null => false
103 t.datetime "updated_at", :null => false
104 end
104 end
105
105
106 create_table "messages", :force => true do |t|
106 create_table "messages", :force => true do |t|
107 t.integer "sender_id"
107 t.integer "sender_id"
108 t.integer "receiver_id"
108 t.integer "receiver_id"
109 t.integer "replying_message_id"
109 t.integer "replying_message_id"
110 - t.text "body", :limit => 16777215
110 + t.text "body"
111 t.boolean "replied"
111 t.boolean "replied"
112 t.datetime "created_at", :null => false
112 t.datetime "created_at", :null => false
113 t.datetime "updated_at", :null => false
113 t.datetime "updated_at", :null => false
114 end
114 end
115
115
116 create_table "problems", :force => true do |t|
116 create_table "problems", :force => true do |t|
117 t.string "name", :limit => 30
117 t.string "name", :limit => 30
118 t.string "full_name"
118 t.string "full_name"
119 t.integer "full_score"
119 t.integer "full_score"
120 t.date "date_added"
120 t.date "date_added"
121 t.boolean "available"
121 t.boolean "available"
122 t.string "url"
122 t.string "url"
@@ -143,25 +143,25
143 t.string "name"
143 t.string "name"
144 end
144 end
145
145
146 create_table "roles_users", :id => false, :force => true do |t|
146 create_table "roles_users", :id => false, :force => true do |t|
147 t.integer "role_id"
147 t.integer "role_id"
148 t.integer "user_id"
148 t.integer "user_id"
149 end
149 end
150
150
151 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
151 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
152
152
153 create_table "sessions", :force => true do |t|
153 create_table "sessions", :force => true do |t|
154 t.string "session_id"
154 t.string "session_id"
155 - t.text "data", :limit => 16777215
155 + t.text "data"
156 t.datetime "updated_at"
156 t.datetime "updated_at"
157 end
157 end
158
158
159 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
159 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
160 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
160 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
161
161
162 create_table "sites", :force => true do |t|
162 create_table "sites", :force => true do |t|
163 t.string "name"
163 t.string "name"
164 t.boolean "started"
164 t.boolean "started"
165 t.datetime "start_time"
165 t.datetime "start_time"
166 t.datetime "created_at", :null => false
166 t.datetime "created_at", :null => false
167 t.datetime "updated_at", :null => false
167 t.datetime "updated_at", :null => false
@@ -171,70 +171,70
171
171
172 create_table "submission_view_logs", :force => true do |t|
172 create_table "submission_view_logs", :force => true do |t|
173 t.integer "user_id"
173 t.integer "user_id"
174 t.integer "submission_id"
174 t.integer "submission_id"
175 t.datetime "created_at", :null => false
175 t.datetime "created_at", :null => false
176 t.datetime "updated_at", :null => false
176 t.datetime "updated_at", :null => false
177 end
177 end
178
178
179 create_table "submissions", :force => true do |t|
179 create_table "submissions", :force => true do |t|
180 t.integer "user_id"
180 t.integer "user_id"
181 t.integer "problem_id"
181 t.integer "problem_id"
182 t.integer "language_id"
182 t.integer "language_id"
183 - t.text "source", :limit => 16777215
183 + t.text "source"
184 t.binary "binary"
184 t.binary "binary"
185 t.datetime "submitted_at"
185 t.datetime "submitted_at"
186 t.datetime "compiled_at"
186 t.datetime "compiled_at"
187 - t.text "compiler_message", :limit => 16777215
187 + t.text "compiler_message"
188 t.datetime "graded_at"
188 t.datetime "graded_at"
189 t.integer "points"
189 t.integer "points"
190 - t.text "grader_comment", :limit => 16777215
190 + t.text "grader_comment"
191 t.integer "number"
191 t.integer "number"
192 t.string "source_filename"
192 t.string "source_filename"
193 t.float "max_runtime"
193 t.float "max_runtime"
194 t.integer "peak_memory"
194 t.integer "peak_memory"
195 t.integer "effective_code_length"
195 t.integer "effective_code_length"
196 t.string "ip_address"
196 t.string "ip_address"
197 end
197 end
198
198
199 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
199 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
200 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
200 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
201
201
202 create_table "tasks", :force => true do |t|
202 create_table "tasks", :force => true do |t|
203 t.integer "submission_id"
203 t.integer "submission_id"
204 t.datetime "created_at"
204 t.datetime "created_at"
205 t.integer "status"
205 t.integer "status"
206 t.datetime "updated_at"
206 t.datetime "updated_at"
207 end
207 end
208
208
209 create_table "test_pairs", :force => true do |t|
209 create_table "test_pairs", :force => true do |t|
210 t.integer "problem_id"
210 t.integer "problem_id"
211 - t.text "input", :limit => 2147483647
211 + t.text "input", :limit => 16777215
212 - t.text "solution", :limit => 2147483647
212 + t.text "solution", :limit => 16777215
213 t.datetime "created_at", :null => false
213 t.datetime "created_at", :null => false
214 t.datetime "updated_at", :null => false
214 t.datetime "updated_at", :null => false
215 end
215 end
216
216
217 create_table "test_requests", :force => true do |t|
217 create_table "test_requests", :force => true do |t|
218 t.integer "user_id"
218 t.integer "user_id"
219 t.integer "problem_id"
219 t.integer "problem_id"
220 t.integer "submission_id"
220 t.integer "submission_id"
221 t.string "input_file_name"
221 t.string "input_file_name"
222 t.string "output_file_name"
222 t.string "output_file_name"
223 t.string "running_stat"
223 t.string "running_stat"
224 t.integer "status"
224 t.integer "status"
225 t.datetime "updated_at", :null => false
225 t.datetime "updated_at", :null => false
226 t.datetime "submitted_at"
226 t.datetime "submitted_at"
227 t.datetime "compiled_at"
227 t.datetime "compiled_at"
228 - t.text "compiler_message", :limit => 16777215
228 + t.text "compiler_message"
229 t.datetime "graded_at"
229 t.datetime "graded_at"
230 t.string "grader_comment"
230 t.string "grader_comment"
231 t.datetime "created_at", :null => false
231 t.datetime "created_at", :null => false
232 t.float "running_time"
232 t.float "running_time"
233 t.string "exit_status"
233 t.string "exit_status"
234 t.integer "memory_usage"
234 t.integer "memory_usage"
235 end
235 end
236
236
237 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
237 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
238
238
239 create_table "user_contest_stats", :force => true do |t|
239 create_table "user_contest_stats", :force => true do |t|
240 t.integer "user_id"
240 t.integer "user_id"
@@ -247,21 +247,20
247 create_table "users", :force => true do |t|
247 create_table "users", :force => true do |t|
248 t.string "login", :limit => 50
248 t.string "login", :limit => 50
249 t.string "full_name"
249 t.string "full_name"
250 t.string "hashed_password"
250 t.string "hashed_password"
251 t.string "salt", :limit => 5
251 t.string "salt", :limit => 5
252 t.string "alias"
252 t.string "alias"
253 t.string "email"
253 t.string "email"
254 t.integer "site_id"
254 t.integer "site_id"
255 t.integer "country_id"
255 t.integer "country_id"
256 t.boolean "activated", :default => false
256 t.boolean "activated", :default => false
257 t.datetime "created_at"
257 t.datetime "created_at"
258 t.datetime "updated_at"
258 t.datetime "updated_at"
259 - t.string "section"
260 t.boolean "enabled", :default => true
259 t.boolean "enabled", :default => true
261 t.string "remark"
260 t.string "remark"
262 t.string "last_ip"
261 t.string "last_ip"
263 end
262 end
264
263
265 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
264 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
266
265
267 end
266 end
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now