contestify 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/contestify/contest.rb
CHANGED
@@ -9,6 +9,13 @@ module Contestify
|
|
9
9
|
clean_dir! contest.working_root_path
|
10
10
|
end
|
11
11
|
|
12
|
+
desc "local PROBLEMS_DIRECTORY JUDGE_UPLOAD_URL JUDGE_PASSWORD", "Setups a contest based on a local problemset"
|
13
|
+
def local(problems_path, judge_url, judge_password)
|
14
|
+
contest = Contestify::Judge::Local.new problems_path
|
15
|
+
Contestify::Uploader.upload!(judge_url, judge_password, contest.problems_paths)
|
16
|
+
clean_dir! contest.working_root_path
|
17
|
+
end
|
18
|
+
|
12
19
|
desc "check", "Checks that the user has the required OS software installed"
|
13
20
|
def check
|
14
21
|
check_dependencies
|
data/lib/contestify/judges.rb
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
require 'contestify/judges/coci/coci'
|
1
|
+
require 'contestify/judges/coci/coci'
|
2
|
+
require 'contestify/judges/local/local'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Contestify::Local
|
2
|
+
===
|
3
|
+
|
4
|
+
This strategy will upload the problems from a local directory to the server. Usage:
|
5
|
+
|
6
|
+
contestify local problem_url judge_upload_url judge_admin_password
|
7
|
+
|
8
|
+
Note that the Judge URL is the actual **upload** URL, which is normally `http://you-dom-judge.com/jury/problem.php`.
|
9
|
+
|
10
|
+
Here's an example of usage with _real_ data:
|
11
|
+
|
12
|
+
contestify /tmp/my_test_data http://domjudge.factorcomun.org/jury/problem.php p4ssw0rd
|
13
|
+
|
14
|
+
This will get the problems in `/tmp/my_test_data` and add them to DOMjudge on the server.
|
15
|
+
|
16
|
+
`/tmp/my_test_data` should contain a directory for every problem and each directory should
|
17
|
+
contain the input and output files for the problem. The files should be named `something.in`
|
18
|
+
and `something.out`, respectively. So if you want to add several test files for a problem
|
19
|
+
named `Example` the files inside `/tmp/my_test_data/example` would look like this: `example.1.in, example.1.out, example.2.in, example.2.out`.
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Contestify
|
2
|
+
module Local
|
3
|
+
# <tt>Local::Configuration</tt> holds all the logic to configure a contest
|
4
|
+
# from a local directory. This class **must** implement the `self.configure!`
|
5
|
+
# method.
|
6
|
+
class Configuration
|
7
|
+
|
8
|
+
# <tt>Contestify::Configuration.configure!</tt> is *the only* method you
|
9
|
+
# should call from the contest interface. All the other methods should be
|
10
|
+
# called from here. This is the only method needed for future strategies
|
11
|
+
# for other judges.
|
12
|
+
#
|
13
|
+
# This should be called in a directory structure such that you have a
|
14
|
+
# `base_folder` with one folder for each problem you want to upload to the
|
15
|
+
# server. Each of these problems folders should have all the input/output
|
16
|
+
# files you want to use as test cases.
|
17
|
+
#
|
18
|
+
# This method **must** return the absolute paths of the problem folders in
|
19
|
+
# an array. This return value will be used in Contestify::Uploader.upload!
|
20
|
+
#
|
21
|
+
# ==== Parameters
|
22
|
+
# base_folder<String>:: The base folder where all the problems folders are
|
23
|
+
# stored.
|
24
|
+
#
|
25
|
+
def self.configure!(base_folder)
|
26
|
+
puts green "=> Configuring problems (#{base_folder})"
|
27
|
+
problem_index = 0
|
28
|
+
Dir.glob("*").select { |f| File.directory?(f) }.map do |dir|
|
29
|
+
Dir.chdir File.join(base_folder, dir)
|
30
|
+
dirid = Dir.pwd.split('/').last[0...8]
|
31
|
+
puts green "==> #{dirid.upcase}"
|
32
|
+
rename_data_files
|
33
|
+
convert_to_unix_format
|
34
|
+
add_problem_config(dirid, problem_index)
|
35
|
+
problem_index += 1
|
36
|
+
puts green "==> All the work for #{dirid.upcase} is done"
|
37
|
+
# Return the absolute path for this problem
|
38
|
+
Dir.pwd
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#########################################################################
|
43
|
+
private #################################################################
|
44
|
+
|
45
|
+
# <tt>Local::Configuration.rename_data_files</tt> is in charge of
|
46
|
+
# giving each input/output file a standard name that DOMJudge understands.
|
47
|
+
#
|
48
|
+
# This method should be overriden in future strategies.
|
49
|
+
#
|
50
|
+
# After this method is called, every different input/output file **must**
|
51
|
+
# have the following structure:
|
52
|
+
#
|
53
|
+
# `problemid`.`number`.in
|
54
|
+
# `problemid`.`number`.out
|
55
|
+
#
|
56
|
+
# where:
|
57
|
+
#
|
58
|
+
# `problemid` is at most 8 letters long and it's the id for the judge and
|
59
|
+
# `number` is the test case number. The .in and .out will determine the
|
60
|
+
# input and compare file the judge will run/diff.
|
61
|
+
def self.rename_data_files
|
62
|
+
puts blue "===> Renaming input/output files"
|
63
|
+
Dir.glob("*").select { |f| f =~ /\.in.[0-9]+/ }.each do |f|
|
64
|
+
|
65
|
+
parts = f.gsub(".dummy", "-dummy").split(".")
|
66
|
+
new_name = [parts[0], parts[2], parts[1]].join(".")
|
67
|
+
File.rename f, new_name
|
68
|
+
|
69
|
+
f.gsub!(".in", ".out")
|
70
|
+
parts = f.gsub(".dummy", "-dummy").split(".")
|
71
|
+
new_name = [parts[0], parts[2], parts[1]].join(".")
|
72
|
+
File.rename f, new_name
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# <tt>Local::Configuration.add_problem_config</tt> will add the
|
78
|
+
# configuration file needed for DOMJudge to understand the problem.
|
79
|
+
#
|
80
|
+
# ==== Parameters
|
81
|
+
# probid<String>:: The problem id for DOMJudge. This **must** be at most
|
82
|
+
# 8 letters long.
|
83
|
+
#
|
84
|
+
# problem_index<Integer>:: This is the problem number. This is only used
|
85
|
+
# to choose the problem ballon color.
|
86
|
+
#
|
87
|
+
def self.add_problem_config(probid, problem_index)
|
88
|
+
puts blue "===> Adding DOM Judge configuration #{probid}"
|
89
|
+
file_content = <<-TEXT
|
90
|
+
probid = #{probid}
|
91
|
+
name = #{probid}
|
92
|
+
allow_submit = true
|
93
|
+
color = #{Contestify::PROBLEM_COLORS[problem_index]}
|
94
|
+
timelimit = 1
|
95
|
+
TEXT
|
96
|
+
File.open(File.join(Dir.pwd, "domjudge-problem.ini"), 'w') {|f| f.write(file_content) }
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.convert_to_unix_format
|
100
|
+
puts blue "===> Converting to UNIX file format"
|
101
|
+
system "dos2unix *"
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'contestify/judges/local/configuration'
|
2
|
+
|
3
|
+
module Contestify
|
4
|
+
module Judge
|
5
|
+
class Local
|
6
|
+
attr_accessor :problems_path, :working_root_path, :problems_paths
|
7
|
+
|
8
|
+
def initialize(problems_path)
|
9
|
+
@problems_path = problems_path
|
10
|
+
@working_root_path = File.join(Dir.pwd, "contestify")
|
11
|
+
FileUtils.mkdir_p @working_root_path
|
12
|
+
copy_problems
|
13
|
+
@problems_paths = Contestify::Local::Configuration.configure!(@working_root_path)
|
14
|
+
end
|
15
|
+
|
16
|
+
private ################################################ PRIVATE
|
17
|
+
|
18
|
+
def copy_problems
|
19
|
+
puts green "=> Copying problems from #{@problems_path}"
|
20
|
+
if not File.directory?(@problems_path)
|
21
|
+
raise Exception.new(red "#{@problems_path} is not a valid directory. Did you mistype something?")
|
22
|
+
end
|
23
|
+
Dir.chdir @problems_path
|
24
|
+
FileUtils.cp_r Dir.glob("*"), @working_root_path
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/contestify/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contestify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: thor
|
16
|
-
requirement: &
|
16
|
+
requirement: &70361113068320 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.14.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70361113068320
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70361113065580 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 0.9.2
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70361113065580
|
36
36
|
description: Gem to prepare internal programming contests taking problems from the
|
37
37
|
COCI contests.
|
38
38
|
email:
|
@@ -56,6 +56,9 @@ files:
|
|
56
56
|
- lib/contestify/judges/coci/README.md
|
57
57
|
- lib/contestify/judges/coci/coci.rb
|
58
58
|
- lib/contestify/judges/coci/configuration.rb
|
59
|
+
- lib/contestify/judges/local/README.md
|
60
|
+
- lib/contestify/judges/local/configuration.rb
|
61
|
+
- lib/contestify/judges/local/local.rb
|
59
62
|
- lib/contestify/messages.rb
|
60
63
|
- lib/contestify/uploader.rb
|
61
64
|
- lib/contestify/util.rb
|
@@ -74,7 +77,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
77
|
version: '0'
|
75
78
|
segments:
|
76
79
|
- 0
|
77
|
-
hash:
|
80
|
+
hash: 2690431504346224305
|
78
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
82
|
none: false
|
80
83
|
requirements:
|
@@ -83,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
86
|
version: '0'
|
84
87
|
segments:
|
85
88
|
- 0
|
86
|
-
hash:
|
89
|
+
hash: 2690431504346224305
|
87
90
|
requirements: []
|
88
91
|
rubyforge_project:
|
89
92
|
rubygems_version: 1.8.10
|