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.
@@ -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