contestify 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +7 -0
- data/README.md +22 -0
- data/Rakefile +2 -0
- data/bin/contestify +13 -0
- data/contestify.gemspec +19 -0
- data/lib/contestify/colorize.rb +24 -0
- data/lib/contestify/configuration.rb +48 -0
- data/lib/contestify/contest.rb +47 -0
- data/lib/contestify/messages.rb +24 -0
- data/lib/contestify/uploader.rb +27 -0
- data/lib/contestify/util.rb +8 -0
- data/lib/contestify/version.rb +3 -0
- data/lib/contestify.rb +10 -0
- metadata +80 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2011 Nicolás Hock Isaza
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Contestify
|
2
|
+
====
|
3
|
+
|
4
|
+
This is a simple ruby gem to automate the process of setting up a programming contest from a [COCI](http://www.hsin.hr/coci/) problem set using [DOMJudge](http://domjudge.sourceforge.net/).
|
5
|
+
|
6
|
+
Usage
|
7
|
+
---
|
8
|
+
|
9
|
+
```
|
10
|
+
contestify coci_problems_url judge_upload_url judge_password
|
11
|
+
```
|
12
|
+
|
13
|
+
This will get the .zip file from the `coci_problems_url` and add the problems to the DOM Judge on the server. This **will not** create a new contest. Just add problems to the current one.
|
14
|
+
|
15
|
+
It is assumed that the admin username is `admin`.
|
16
|
+
|
17
|
+
Contributions
|
18
|
+
---
|
19
|
+
|
20
|
+
If you find any bug or have any addition, please let us know. You can use the [issue tracker](https://github.com/nhocki/contestify/issues) for that. We would like to expand this script and be able to use any other problem (not just the ones from COCI).
|
21
|
+
|
22
|
+
This script was started by [Andrés Mejía](https://github.com/andmej). I added the config file option and gemified it.
|
data/Rakefile
ADDED
data/bin/contestify
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
3
|
+
require 'contestify'
|
4
|
+
|
5
|
+
problems_url = ARGV[0]
|
6
|
+
judge_url = ARGV[1]
|
7
|
+
judge_password = ARGV[2]
|
8
|
+
|
9
|
+
begin
|
10
|
+
Contestify::Contest.new(problems_url, judge_url, judge_password).setup!
|
11
|
+
rescue Exception => e
|
12
|
+
puts e.message
|
13
|
+
end
|
data/contestify.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/contestify/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Nicolás Hock Isaza"]
|
6
|
+
gem.email = ["nhocki@gmail.com"]
|
7
|
+
gem.description = %q{Gem to prepare internal programming contests taking problems from the COCI contests.}
|
8
|
+
gem.summary = %q{Gem to prepare internal programming contests taking problems from the COCI contests.}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "contestify"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Contestify::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency "rake", "~> 0.9.2"
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Contestify
|
2
|
+
PROBLEM_COLORS = %w(blue red green yellow black pink purple gray orange white brown cyan)
|
3
|
+
|
4
|
+
module Colorize
|
5
|
+
def colorize(text, color_code)
|
6
|
+
"\033[#{color_code}m#{text}\033[0m"
|
7
|
+
end
|
8
|
+
|
9
|
+
{
|
10
|
+
:black => 30,
|
11
|
+
:red => 31,
|
12
|
+
:green => 32,
|
13
|
+
:yellow => 33,
|
14
|
+
:blue => 34,
|
15
|
+
:magenta => 35,
|
16
|
+
:cyan => 36,
|
17
|
+
:white => 37
|
18
|
+
}.each do |key, color_code|
|
19
|
+
define_method key do |text|
|
20
|
+
colorize(text, color_code)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Contestify
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
def self.configure!(base_folder)
|
5
|
+
puts green "=> Configuring problems"
|
6
|
+
problem_index = 0
|
7
|
+
Dir.glob("*").select { |f| File.directory?(f) }.each do |dir|
|
8
|
+
Dir.chdir File.join(base_folder, dir)
|
9
|
+
dirid = Dir.pwd.split('/').last[0...8]
|
10
|
+
puts green "==> #{dirid.upcase}"
|
11
|
+
rename_data_files
|
12
|
+
add_problem_config(dirid, problem_index)
|
13
|
+
problem_index += 1
|
14
|
+
puts green "==> All the work for #{dirid.upcase} is done"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.rename_data_files
|
19
|
+
puts blue "===> Renaming input/output files"
|
20
|
+
Dir.glob("*").select { |f| f =~ /\.in.[0-9]+/ }.each do |f|
|
21
|
+
# puts red " Renaming #{f}..."
|
22
|
+
parts = f.split(".")
|
23
|
+
new_name = [parts[0], parts[2], parts[1]].join(".")
|
24
|
+
# puts blue " " + new_name
|
25
|
+
File.rename f, new_name
|
26
|
+
|
27
|
+
f.gsub!(".in", ".out")
|
28
|
+
# puts red " Renaming #{f}..."
|
29
|
+
parts = f.split(".")
|
30
|
+
new_name = [parts[0], parts[2], parts[1]].join(".")
|
31
|
+
# puts blue " " + new_name
|
32
|
+
File.rename f, new_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.add_problem_config(probid, problem_index)
|
37
|
+
puts blue "===> Adding DOM Judge configuration #{probid}"
|
38
|
+
file_content = <<-TEXT
|
39
|
+
probid = #{probid}
|
40
|
+
name = #{probid}
|
41
|
+
allow_submit = true
|
42
|
+
color = #{Contestify::PROBLEM_COLORS[problem_index]}
|
43
|
+
timelimit = 1
|
44
|
+
TEXT
|
45
|
+
File.open(File.join(Dir.pwd, "domjudge-problem.ini"), 'w') {|f| f.write(file_content) }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Contestify
|
2
|
+
class Contest
|
3
|
+
include Contestify::Util
|
4
|
+
|
5
|
+
attr_accessor :problems_url, :judge_url, :judge_password, :base_dir
|
6
|
+
|
7
|
+
def initialize(problems_url, judge_url, judge_password)
|
8
|
+
@problems_url, @judge_url, @judge_password = problems_url, judge_url, judge_password
|
9
|
+
|
10
|
+
if [@problems_url, @judge_url, @judge_password].any? {|attribute| attribute.nil? or attribute.empty?}
|
11
|
+
raise Exception.new(Contestify::HELP_MESSAGE)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup!
|
16
|
+
check_dependencies
|
17
|
+
get_problems
|
18
|
+
unzip_problems
|
19
|
+
@base_dir = Dir.pwd
|
20
|
+
Contestify::Configuration.configure!(@base_dir)
|
21
|
+
Contestify::Uploader.upload!(@judge_url, @judge_password, @base_dir)
|
22
|
+
end
|
23
|
+
|
24
|
+
private ######################################################################## PRIVATE
|
25
|
+
|
26
|
+
def check_dependencies
|
27
|
+
system?(:zip) and
|
28
|
+
system?(:curl) and
|
29
|
+
system?(:unzip) and
|
30
|
+
system?(:dos2unix)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_problems
|
34
|
+
FileUtils.mkdir_p File.join(Dir.pwd, "contestify")
|
35
|
+
Dir.chdir File.join(Dir.pwd, "contestify")
|
36
|
+
puts green "=> Fetching problems from #{@problems_url}"
|
37
|
+
curl_output = `curl #{@problems_url} > #{File.join(Dir.pwd, "problems.zip")}`
|
38
|
+
raise Exception.new(red Contestify::CURL_PROBLEM) unless $?.success?
|
39
|
+
end
|
40
|
+
|
41
|
+
def unzip_problems
|
42
|
+
puts green "=> Unzipping problems"
|
43
|
+
unzip_output = `unzip #{File.join(Dir.pwd, "problems.zip")}`
|
44
|
+
raise Exception.new(red Contestify::UNZIP_PROBLEM) unless $?.success?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Contestify
|
2
|
+
HELP_MESSAGE = <<-TEXT
|
3
|
+
You need to specify the three arguments. Here's an example:
|
4
|
+
|
5
|
+
contestify coci_problems_url judge_upload_url judge_password
|
6
|
+
TEXT
|
7
|
+
|
8
|
+
CURL_PROBLEM = <<-TEXT
|
9
|
+
We could not get the problems from that URL. Maybe you mispelled it? Please try again.
|
10
|
+
TEXT
|
11
|
+
|
12
|
+
UNZIP_MISSING = <<-TEXT
|
13
|
+
Please install `unzip` first or add it to your PATH if needed.
|
14
|
+
TEXT
|
15
|
+
|
16
|
+
UNZIP_PROBLEM = <<-TEXT
|
17
|
+
We couldn't unzip your files. Please verify that the download was succesful.
|
18
|
+
TEXT
|
19
|
+
|
20
|
+
ZIP_PROBLEM = <<-TEXT
|
21
|
+
We couldn't zip your files. Please try again.
|
22
|
+
TEXT
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Contestify
|
2
|
+
class Uploader
|
3
|
+
def self.upload!(server_url, admin_pwd, base_dir)
|
4
|
+
puts green "\n\n=> Uploading problems to the server"
|
5
|
+
|
6
|
+
Dir.chdir base_dir # Ensure you're on the `root` dir
|
7
|
+
Dir.glob("*").select { |f| File.directory?(f) }.each do |dir|
|
8
|
+
Dir.chdir File.join(base_dir, dir)
|
9
|
+
|
10
|
+
unless File.exists?("domjudge-problem.ini")
|
11
|
+
puts cyan "domjudge-problem.ini not found. Skipping #{dir}."
|
12
|
+
next
|
13
|
+
end
|
14
|
+
|
15
|
+
puts blue "==> Building #{dir}"
|
16
|
+
FileUtils.rm_f "bundle.zip"
|
17
|
+
zip_output = system("zip bundle.zip *")
|
18
|
+
raise Exception.new(red Contestify::ZIP_PROBLEM) unless $?.success?
|
19
|
+
|
20
|
+
puts blue "===> Uploading #{dir}/bundle.zip..."
|
21
|
+
curl_output = system("curl -vv -F upload=Upload -F problem_archive=@bundle.zip --user admin:#{admin_pwd} #{server_url}")
|
22
|
+
puts blue "===> Upload done\n"
|
23
|
+
end
|
24
|
+
puts green "\n\n=> All problems have been uploaded"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/contestify.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require "contestify/version"
|
3
|
+
require "contestify/messages"
|
4
|
+
require "contestify/colorize"
|
5
|
+
require "contestify/util"
|
6
|
+
require "contestify/contest"
|
7
|
+
require "contestify/configuration"
|
8
|
+
require "contestify/uploader"
|
9
|
+
|
10
|
+
include Contestify::Colorize
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: contestify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nicolás Hock Isaza
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70342794831580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70342794831580
|
25
|
+
description: Gem to prepare internal programming contests taking problems from the
|
26
|
+
COCI contests.
|
27
|
+
email:
|
28
|
+
- nhocki@gmail.com
|
29
|
+
executables:
|
30
|
+
- contestify
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- bin/contestify
|
40
|
+
- contestify.gemspec
|
41
|
+
- lib/contestify.rb
|
42
|
+
- lib/contestify/colorize.rb
|
43
|
+
- lib/contestify/configuration.rb
|
44
|
+
- lib/contestify/contest.rb
|
45
|
+
- lib/contestify/messages.rb
|
46
|
+
- lib/contestify/uploader.rb
|
47
|
+
- lib/contestify/util.rb
|
48
|
+
- lib/contestify/version.rb
|
49
|
+
homepage: ''
|
50
|
+
licenses: []
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options: []
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
hash: -4442839192131223781
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
hash: -4442839192131223781
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.8.10
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Gem to prepare internal programming contests taking problems from the COCI
|
79
|
+
contests.
|
80
|
+
test_files: []
|