contestify 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Contestify
2
- VERSION = "2.0.1"
2
+ VERSION = "2.1.0"
3
3
  end
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.1
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-10 00:00:00.000000000 Z
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: &70213862761180 !ruby/object:Gem::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: *70213862761180
24
+ version_requirements: *70361113068320
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70213862760440 !ruby/object:Gem::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: *70213862760440
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: -2100471125524470564
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: -2100471125524470564
89
+ hash: 2690431504346224305
87
90
  requirements: []
88
91
  rubyforge_project:
89
92
  rubygems_version: 1.8.10