omegaup 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Gemfile +0 -0
- data/lib/omega/base.rb +0 -0
- data/lib/omega/cli/contest.rb +17 -0
- data/lib/omega/cli.rb +17 -2
- data/lib/omega/client.rb +116 -2
- data/lib/omega/contest.rb +24 -0
- data/lib/omega/contest_run.rb +1 -1
- data/lib/omega/scoreboard.rb +9 -1
- data/lib/omega/user.rb +5 -1
- data/lib/omega/version.rb +1 -1
- data/lib/omega.rb +0 -0
- data/omega.gemspec +5 -4
- metadata +19 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 767e4b440acdf0d4b4f07d2fa568b0c05e78a8e066e1280765d49c6d62b23c46
|
4
|
+
data.tar.gz: 4151f5ade0af99d594d81e7cb1dae1259532d0627cc1c02f0499e1db03c4cec3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2511e42ce423bb7530f9e696e2a8f436fe547a9526731e3fc119952d63a014c0ef151b2ed78087b033009ee3420fe5bfee6495fe0b35f33a92aff90d62ee1488
|
7
|
+
data.tar.gz: b0816baf5e9fb16c43a9dbdb2e00b8c1462fd0f77ae33ce843c9fc03d42f6491e75d492a4d3847591cd9cf225589a6b2b23601ce333ee90c23873814cce80e90
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
File without changes
|
data/lib/omega/base.rb
CHANGED
File without changes
|
data/lib/omega/cli/contest.rb
CHANGED
@@ -51,6 +51,23 @@ module Omega
|
|
51
51
|
puts "#{contest_name}: #{e.message}"
|
52
52
|
end
|
53
53
|
|
54
|
+
def add_problem(contest_name, problem_name)
|
55
|
+
contest = omega.contest(contest_name)
|
56
|
+
contest.add_problem(problem_name)
|
57
|
+
rescue StandardError => e
|
58
|
+
puts "Error adding #{problem_name}: #{e.message}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def copy_problems(contest_name, from)
|
62
|
+
contest = omega.contest(contest_name)
|
63
|
+
source = omega.contest(from)
|
64
|
+
source.problems.each do |problem|
|
65
|
+
contest.add_problem(problem[:alias])
|
66
|
+
rescue StandardError => e
|
67
|
+
puts "Error adding #{problem[:alias]}: #{e.message}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
54
71
|
def download_sources(contest_name, path)
|
55
72
|
Dir.mkdir(path) unless File.directory?(path)
|
56
73
|
contest = omega.contest(contest_name)
|
data/lib/omega/cli.rb
CHANGED
@@ -24,6 +24,7 @@ OmegaUp CLI. Developed by OMIJal https://github.com/omijal/omegaup-cli.
|
|
24
24
|
Tool for interacting with omegaup from CLI and available throug ruby gems.
|
25
25
|
Commands:
|
26
26
|
- register-users Add a user or a bunch of users to the a contest.
|
27
|
+
- copy-problems Adds prob from another contest
|
27
28
|
- user Generates a dump of the user data in yml format.
|
28
29
|
- scoreboard Gets contest scoreboard with users and score.
|
29
30
|
- clarifications Gets contest clarifications.
|
@@ -51,6 +52,16 @@ OMEGAUP_PASS *Required* Your OmegaUp Password
|
|
51
52
|
@cmd = ARGV.shift
|
52
53
|
|
53
54
|
@cmd_opts = case @cmd
|
55
|
+
when 'copy-problems'
|
56
|
+
Optimist.options do
|
57
|
+
opt :contest, 'Contest ShortName or identifier', type: :string
|
58
|
+
opt :from, 'Another constest that allows to clone users from another contest', type: :string
|
59
|
+
end
|
60
|
+
when 'add-problem'
|
61
|
+
Optimist.options do
|
62
|
+
opt :contest, 'Contest ShortName or identifier', type: :string
|
63
|
+
opt :problem, 'Problem name', type: :string
|
64
|
+
end
|
54
65
|
when 'register-users'
|
55
66
|
Optimist.options do
|
56
67
|
opt :contest, 'Contest ShortName or identifier', type: :string
|
@@ -95,8 +106,8 @@ OMEGAUP_PASS *Required* Your OmegaUp Password
|
|
95
106
|
config = {
|
96
107
|
'omega' => {
|
97
108
|
'endpoint' => ENV['OMEGAUP_URL'] || 'https://omegaup.com',
|
98
|
-
'user' => ENV
|
99
|
-
'pass' => ENV
|
109
|
+
'user' => ENV.fetch('OMEGAUP_USER', nil),
|
110
|
+
'pass' => ENV.fetch('OMEGAUP_PASS', nil)
|
100
111
|
}
|
101
112
|
}
|
102
113
|
|
@@ -119,6 +130,10 @@ OMEGAUP_PASS *Required* Your OmegaUp Password
|
|
119
130
|
clarifications(@cmd_opts[:contest], @cmd_opts[:open])
|
120
131
|
when 'sources'
|
121
132
|
download_sources(@cmd_opts[:contest], @cmd_opts[:path])
|
133
|
+
when 'copy-problems'
|
134
|
+
copy_problems(@cmd_opts[:contest], @cmd_opts[:from])
|
135
|
+
when 'add-problem'
|
136
|
+
add_problem(@cmd_opts[:contest], @cmd_opts[:problem])
|
122
137
|
end
|
123
138
|
end
|
124
139
|
end
|
data/lib/omega/client.rb
CHANGED
@@ -4,10 +4,16 @@ require_relative 'contest'
|
|
4
4
|
require_relative 'scoreboard'
|
5
5
|
require_relative 'user'
|
6
6
|
require_relative 'contest_run'
|
7
|
+
require 'json'
|
8
|
+
require 'nokogiri'
|
7
9
|
|
8
10
|
require 'httparty'
|
9
11
|
|
10
12
|
module Omega
|
13
|
+
KAREL_LANGS = 'kp,kj'
|
14
|
+
OMI_LANGS = 'c11-gcc,c11-clang,cpp11-gcc,cpp11-clang,cpp17-gcc,cpp17-clang,cpp20-gcc,cpp20-clang'
|
15
|
+
ALL_LANGS = 'kp,kj,c11-gcc,c11-clang,cpp11-gcc,cpp11-clang,cpp17-gcc,cpp17-clang,cpp20-gcc,cpp20-clang,java,kt,py2,py3,rb,cs,pas,cat,hs,lua,go,rs,js'
|
16
|
+
|
11
17
|
class OmegaError < StandardError
|
12
18
|
attr_reader :data
|
13
19
|
|
@@ -18,6 +24,14 @@ module Omega
|
|
18
24
|
def message
|
19
25
|
"#{@data[:errorname]}::#{@data[:errorcode]} >> #{@data[:error]}"
|
20
26
|
end
|
27
|
+
|
28
|
+
def errorname
|
29
|
+
@data[:errorname]
|
30
|
+
end
|
31
|
+
|
32
|
+
def errorcode
|
33
|
+
@data[:errorcode]
|
34
|
+
end
|
21
35
|
end
|
22
36
|
|
23
37
|
class Client
|
@@ -30,7 +44,7 @@ module Omega
|
|
30
44
|
def perform_request(method, endpoint, data, retried = false)
|
31
45
|
url = "#{@config['endpoint']}#{endpoint}"
|
32
46
|
response = self.class.send(method, url, body: data)
|
33
|
-
body = JSON.parse(response.body, symbolize_names: true)
|
47
|
+
body = ::JSON.parse(response.body, symbolize_names: true)
|
34
48
|
|
35
49
|
if body[:errorcode] == 401 && !retried
|
36
50
|
login
|
@@ -67,6 +81,58 @@ module Omega
|
|
67
81
|
retry
|
68
82
|
end
|
69
83
|
|
84
|
+
def problem_details(problem_alias)
|
85
|
+
post('/api/problem/details', { problem_alias: })
|
86
|
+
end
|
87
|
+
|
88
|
+
def create_group(name, description: nil, alias: nil)
|
89
|
+
post('/api/group/create', name:, alias:, description:)
|
90
|
+
end
|
91
|
+
|
92
|
+
def create_contest(name:, short_name:, description:, start_time:, finish_time:,
|
93
|
+
public: false, penalty_calc_policy: 'sum', show_penalty: true,
|
94
|
+
points_decay_factor: '0', submissions_gap: '60', languages: ALL_LANGS, feedback: 'none',
|
95
|
+
penalty: '0', scoreboard: '100', penalty_type: 'none',
|
96
|
+
default_show_all_contestants_in_scoreboard: false,
|
97
|
+
show_scoreboard_after: true,
|
98
|
+
score_mode: 'partial',
|
99
|
+
needs_basic_information: false,
|
100
|
+
requests_user_information: 'no',
|
101
|
+
contest_for_teams: false)
|
102
|
+
post('/api/contest/create/', {
|
103
|
+
admin: true,
|
104
|
+
admission_mode: (public ? 'public' : 'private'),
|
105
|
+
alias: short_name,
|
106
|
+
archived: false,
|
107
|
+
opened: false,
|
108
|
+
penalty_calc_policy:,
|
109
|
+
show_penalty:,
|
110
|
+
title: name,
|
111
|
+
description:,
|
112
|
+
has_submissions: false,
|
113
|
+
start_time: start_time.to_time.to_i,
|
114
|
+
finish_time: finish_time.to_time.to_i,
|
115
|
+
points_decay_factor:,
|
116
|
+
submissions_gap:,
|
117
|
+
languages:,
|
118
|
+
feedback:,
|
119
|
+
penalty:,
|
120
|
+
scoreboard:,
|
121
|
+
penalty_type:,
|
122
|
+
default_show_all_contestants_in_scoreboard:,
|
123
|
+
show_scoreboard_after:,
|
124
|
+
score_mode:,
|
125
|
+
needs_basic_information:,
|
126
|
+
requests_user_information:,
|
127
|
+
contest_for_teams:
|
128
|
+
})
|
129
|
+
contest(short_name)
|
130
|
+
rescue OmegaError => e
|
131
|
+
raise e unless e.errorname == 'aliasInUse'
|
132
|
+
|
133
|
+
contest(short_name)
|
134
|
+
end
|
135
|
+
|
70
136
|
def scoreboard(name)
|
71
137
|
data = post('/api/contest/scoreboard/', { contest_alias: name })
|
72
138
|
Scoreboard.new(self, data)
|
@@ -86,6 +152,12 @@ module Omega
|
|
86
152
|
User.new(self, data)
|
87
153
|
end
|
88
154
|
|
155
|
+
def add_admin_group(contest, group)
|
156
|
+
post('/api/contest/addGroupAdmin', { contest_alias: contest, group: })
|
157
|
+
rescue OmegaError
|
158
|
+
# Omega seems to have a bug
|
159
|
+
end
|
160
|
+
|
89
161
|
def add_user_to_contest(user, contest)
|
90
162
|
post('/api/contest/addUser', { contest_alias: contest, usernameOrEmail: user })
|
91
163
|
end
|
@@ -99,8 +171,50 @@ module Omega
|
|
99
171
|
end
|
100
172
|
|
101
173
|
def contest_runs(contest, offset, page_size)
|
102
|
-
data = post('/api/contest/runs/', { contest_alias: contest, offset
|
174
|
+
data = post('/api/contest/runs/', { contest_alias: contest, offset:, rowcount: page_size })
|
103
175
|
data[:runs].map { |run| ContestRun.new(self, run) }
|
104
176
|
end
|
177
|
+
|
178
|
+
def add_problem_to_contest(contest, problem, points = 100)
|
179
|
+
post('/api/contest/addProblem', contest_alias: contest, problem_alias: problem, points:)
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_user_to_group(group_name, username)
|
183
|
+
post('/api/group/addUser', group_alias: group_name, usernameOrEmail: username)
|
184
|
+
rescue OmegaError => e
|
185
|
+
raise if e.errorname != 'identityInGroup'
|
186
|
+
end
|
187
|
+
|
188
|
+
def get_payload_from_response_by_id(response_body, id)
|
189
|
+
page = Nokogiri::HTML(response_body)
|
190
|
+
script = page.at_css("script##{id}")
|
191
|
+
unless script
|
192
|
+
raise OmegaError.new(errorname: 'ScrapingError', errorcode: 404,
|
193
|
+
error: "Script with id #{id} not found")
|
194
|
+
end
|
195
|
+
|
196
|
+
script_content = script.content
|
197
|
+
# Extrayendo el contenido JSON del script
|
198
|
+
begin
|
199
|
+
::JSON.parse(script_content, symbolize_names: true)
|
200
|
+
rescue JSON::ParserError
|
201
|
+
raise OmegaError.new(errorname: 'ScrapingError', errorcode: 500, error: 'Unable to parse JSON data')
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def scrap_get(endpoint, id = 'payload')
|
206
|
+
url = "#{@config['endpoint']}#{endpoint}"
|
207
|
+
response = self.class.get(url)
|
208
|
+
unless response.success?
|
209
|
+
raise OmegaError.new(errorname: 'HttpError', errorcode: response.code,
|
210
|
+
error: response.message)
|
211
|
+
end
|
212
|
+
|
213
|
+
body = get_payload_from_response_by_id(response.body, id)
|
214
|
+
|
215
|
+
raise OmegaError, body if body[:error]
|
216
|
+
|
217
|
+
body
|
218
|
+
end
|
105
219
|
end
|
106
220
|
end
|
data/lib/omega/contest.rb
CHANGED
@@ -9,6 +9,10 @@ module Omega
|
|
9
9
|
@client.scoreboard(data[:alias])
|
10
10
|
end
|
11
11
|
|
12
|
+
def problems
|
13
|
+
@data[:problems]
|
14
|
+
end
|
15
|
+
|
12
16
|
def runs(offset = 0, page_size = 100)
|
13
17
|
@client.contest_runs(data[:alias], offset, page_size)
|
14
18
|
end
|
@@ -27,6 +31,14 @@ module Omega
|
|
27
31
|
sources
|
28
32
|
end
|
29
33
|
|
34
|
+
def full_details
|
35
|
+
@full_details ||= @client.scrap_get("/contest/#{data[:alias]}/edit/")
|
36
|
+
end
|
37
|
+
|
38
|
+
def group_admin?(group_name)
|
39
|
+
full_details[:group_admins].any? { |group| group[:alias].casecmp(group_name).zero? }
|
40
|
+
end
|
41
|
+
|
30
42
|
def add_user(user)
|
31
43
|
if user.is_a?(String)
|
32
44
|
@client.add_user_to_contest(user, data[:alias])
|
@@ -43,6 +55,18 @@ module Omega
|
|
43
55
|
scoreboard.users
|
44
56
|
end
|
45
57
|
|
58
|
+
def alias
|
59
|
+
@data[:alias].downcase
|
60
|
+
end
|
61
|
+
|
62
|
+
def add_problem(name)
|
63
|
+
@client.add_problem_to_contest(data[:alias], name)
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_admin_group(group)
|
67
|
+
@client.add_admin_group(data[:alias], group)
|
68
|
+
end
|
69
|
+
|
46
70
|
def observe(score_notifier, clar_noritifer)
|
47
71
|
last = current = scoreboard
|
48
72
|
sleep(5)
|
data/lib/omega/contest_run.rb
CHANGED
data/lib/omega/scoreboard.rb
CHANGED
@@ -10,7 +10,7 @@ module Omega
|
|
10
10
|
def initialize(client, entry)
|
11
11
|
@username = entry[:username]
|
12
12
|
@problems = entry[:problems] || []
|
13
|
-
super
|
13
|
+
super
|
14
14
|
end
|
15
15
|
|
16
16
|
def merge(score)
|
@@ -37,6 +37,10 @@ module Omega
|
|
37
37
|
end
|
38
38
|
nil
|
39
39
|
end
|
40
|
+
|
41
|
+
def to_h
|
42
|
+
@data[:problems]
|
43
|
+
end
|
40
44
|
end
|
41
45
|
|
42
46
|
class Scoreboard < Base
|
@@ -49,6 +53,10 @@ module Omega
|
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
56
|
+
def to_h
|
57
|
+
@data[:ranking].map { |username, entry| { username:, score: entry.to_h } }
|
58
|
+
end
|
59
|
+
|
52
60
|
def merge(board)
|
53
61
|
result = clone
|
54
62
|
board.data[:ranking].each do |user, score|
|
data/lib/omega/user.rb
CHANGED
@@ -7,7 +7,7 @@ module Omega
|
|
7
7
|
def full_data
|
8
8
|
{
|
9
9
|
data: @data,
|
10
|
-
problems_solved
|
10
|
+
problems_solved:,
|
11
11
|
resume: report
|
12
12
|
}
|
13
13
|
end
|
@@ -16,6 +16,10 @@ module Omega
|
|
16
16
|
@client.problems_solved(data[:username])[:problems]
|
17
17
|
end
|
18
18
|
|
19
|
+
def username
|
20
|
+
@data[:username]
|
21
|
+
end
|
22
|
+
|
19
23
|
def report
|
20
24
|
data = { score: 0, count: 0 }
|
21
25
|
problems_solved.each do |p|
|
data/lib/omega/version.rb
CHANGED
data/lib/omega.rb
CHANGED
File without changes
|
data/omega.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.name = 'omegaup'
|
9
9
|
spec.version = Omega::VERSION
|
10
10
|
spec.authors = ['Gilberto Vargas']
|
11
|
-
spec.email = ['
|
11
|
+
spec.email = ['tachomexgems@gmail.com']
|
12
12
|
|
13
13
|
spec.summary = 'File created for encrypting files using ssh keys'
|
14
14
|
spec.description = 'Allows to encrypt files using ssh keys'
|
@@ -25,10 +25,11 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency 'amazing_print'
|
26
26
|
spec.add_development_dependency 'httparty'
|
27
27
|
spec.add_development_dependency 'minitest', '~> 5'
|
28
|
+
spec.add_development_dependency 'mocha'
|
28
29
|
spec.add_development_dependency 'optimist'
|
29
30
|
spec.add_development_dependency 'rack-minitest'
|
30
|
-
spec.add_development_dependency 'webmock'
|
31
|
-
spec.add_development_dependency 'mocha'
|
32
|
-
spec.add_development_dependency 'simplecov'
|
33
31
|
spec.add_development_dependency 'rake', '~> 10.0'
|
32
|
+
spec.add_development_dependency 'simplecov'
|
33
|
+
spec.add_development_dependency 'webmock'
|
34
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
34
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: omegaup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gilberto Vargas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: amazing_print
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '5'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: mocha
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: optimist
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rack-minitest
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -95,19 +95,19 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: rake
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
103
|
+
version: '10.0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
110
|
+
version: '10.0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: simplecov
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,22 +123,22 @@ dependencies:
|
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: webmock
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- - "
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
|
-
version: '
|
131
|
+
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- - "
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: '
|
138
|
+
version: '0'
|
139
139
|
description: Allows to encrypt files using ssh keys
|
140
140
|
email:
|
141
|
-
-
|
141
|
+
- tachomexgems@gmail.com
|
142
142
|
executables:
|
143
143
|
- omega
|
144
144
|
extensions: []
|
@@ -161,7 +161,8 @@ files:
|
|
161
161
|
homepage: https://github.com/omijal/omegaup-cli
|
162
162
|
licenses:
|
163
163
|
- MIT
|
164
|
-
metadata:
|
164
|
+
metadata:
|
165
|
+
rubygems_mfa_required: 'true'
|
165
166
|
post_install_message:
|
166
167
|
rdoc_options: []
|
167
168
|
require_paths:
|
@@ -177,7 +178,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
178
|
- !ruby/object:Gem::Version
|
178
179
|
version: '0'
|
179
180
|
requirements: []
|
180
|
-
rubygems_version: 3.
|
181
|
+
rubygems_version: 3.5.14
|
181
182
|
signing_key:
|
182
183
|
specification_version: 4
|
183
184
|
summary: File created for encrypting files using ssh keys
|