omegaup 0.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.
- checksums.yaml +7 -0
- data/.rubocop.yml +3 -0
- data/Gemfile +4 -0
- data/bin/omega +6 -0
- data/lib/omega.rb +7 -0
- data/lib/omega/base.rb +12 -0
- data/lib/omega/cli.rb +102 -0
- data/lib/omega/cli/contest.rb +39 -0
- data/lib/omega/client.rb +82 -0
- data/lib/omega/contest.rb +42 -0
- data/lib/omega/scoreboard.rb +74 -0
- data/lib/omega/user.rb +28 -0
- data/lib/omega/version.rb +5 -0
- data/omega.gemspec +29 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d68043d4f4131c6b4d11b1607e6d38b0ba05e74621bab4c08cf1bcc0e1c7a948
|
4
|
+
data.tar.gz: cefb8c9d26da0a24d6d720fcd22fbcdc8a4aedc57f5a8b28d1e2b7ceedad9226
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 84ee8b49d4c2d380b03b9dbbe6c67ae0af343a89b09b7fe5c95ac639a8be46478d484bb9c2e4328eff7e2705303ffaf807c7636418825b7995d5e0ef3fe50509
|
7
|
+
data.tar.gz: 93c3a835cbbca8134b4ef626eb14c53061fc495c5cd7fc716a5333b8e209035e2beea10c840f0385f16a41d2632159a3b5367a7e36c4adb564f2433dfa26e99e
|
data/.rubocop.yml
ADDED
data/Gemfile
ADDED
data/bin/omega
ADDED
data/lib/omega.rb
ADDED
data/lib/omega/base.rb
ADDED
data/lib/omega/cli.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../omega'
|
4
|
+
require_relative 'cli/contest'
|
5
|
+
require 'optimist'
|
6
|
+
|
7
|
+
module Omega
|
8
|
+
class CLI
|
9
|
+
attr_reader :omega
|
10
|
+
|
11
|
+
include Omega::CLI::Contest
|
12
|
+
SUB_COMMANDS = %w[
|
13
|
+
register-users
|
14
|
+
user
|
15
|
+
scoreboard
|
16
|
+
create-contest
|
17
|
+
add-problem
|
18
|
+
help
|
19
|
+
].freeze
|
20
|
+
|
21
|
+
def print_help
|
22
|
+
puts %(
|
23
|
+
OmegaUp CLI. Developed by OMIJal https://github.com/omijal/omegaup-cli.
|
24
|
+
Tool for interacting with omegaup from CLI and available throug ruby gems.
|
25
|
+
Commands:
|
26
|
+
- register_users Add a user or a bunch of users to the a contest.
|
27
|
+
- user Generates a dump of the user data in yml format.
|
28
|
+
- scoreboard Gets contest scoreboard with users and score.
|
29
|
+
Parametes:
|
30
|
+
--contest Contest name
|
31
|
+
--user Username or email
|
32
|
+
--user_file A file path containing a list of user one per line without
|
33
|
+
header
|
34
|
+
Setup:
|
35
|
+
You need to add two env variables with your omegaup credentials.
|
36
|
+
OMEGAUP_URL *Optional* This is intended for development purpose, it will target
|
37
|
+
to https://omegau.com by default.
|
38
|
+
OMEGAUP_USER *Required* Your OmegaUp Username or Email
|
39
|
+
OMEGAUP_PASS *Required* Your OmegaUp Password
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def initialize(_)
|
44
|
+
@cmd = ARGV.shift
|
45
|
+
|
46
|
+
@cmd_opts = case @cmd
|
47
|
+
when 'register-users'
|
48
|
+
Optimist.options do
|
49
|
+
opt :contest, 'Contest ShortName or identifier', type: :string
|
50
|
+
opt :user, 'Username or email', type: :string
|
51
|
+
opt :user_file, 'A file containing the users list one per line and without header', type: :string
|
52
|
+
end
|
53
|
+
when 'user'
|
54
|
+
Optimist.options do
|
55
|
+
opt :user, 'Username or email', type: :string
|
56
|
+
end
|
57
|
+
when 'scoreboard'
|
58
|
+
Optimist.options do
|
59
|
+
opt :contest, 'Contest ShortName or identifier', type: :string
|
60
|
+
end
|
61
|
+
# when 'create-contest'
|
62
|
+
# Optimist.options do
|
63
|
+
# opt :contest, 'Contest ShortName or identifier', type: :string
|
64
|
+
# end
|
65
|
+
# when 'add-problem'
|
66
|
+
# Optimist.options do
|
67
|
+
# opt :contest, 'Contest ShortName or identifier', type: :string
|
68
|
+
# opt :problem, type: :string
|
69
|
+
# end
|
70
|
+
else
|
71
|
+
print_help
|
72
|
+
exit(0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def login
|
77
|
+
config = {
|
78
|
+
'omega' => {
|
79
|
+
'endpoint' => ENV['OMEGAUP_URL'] || 'https://omegaup.com',
|
80
|
+
'user' => ENV['OMEGAUP_USER'],
|
81
|
+
'pass' => ENV['OMEGAUP_PASS']
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
@omega = Omega::Client.new(config['omega'])
|
86
|
+
@omega.login
|
87
|
+
end
|
88
|
+
|
89
|
+
def execute
|
90
|
+
login
|
91
|
+
case @cmd
|
92
|
+
when 'register-users'
|
93
|
+
register_user(@cmd_opts[:contest], @cmd_opts[:user]) if @cmd_opts[:user]
|
94
|
+
register_users(@cmd_opts[:contest], @cmd_opts[:user_file]) if @cmd_opts[:user_file]
|
95
|
+
when 'user'
|
96
|
+
user_data(@cmd_opts[:user])
|
97
|
+
when 'scoreboard'
|
98
|
+
scoreboard(@cmd_opts[:contest])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Omega
|
4
|
+
class CLI
|
5
|
+
module Contest
|
6
|
+
def register_user(contest_name, user)
|
7
|
+
contest = omega.contest(contest_name)
|
8
|
+
puts contest.add_user(user)[:status]
|
9
|
+
rescue StandardError => e
|
10
|
+
puts "Error adding #{user}: #{e.message}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def register_users(contest_name, user_file)
|
14
|
+
users = File.readlines(user_file).map(&:strip)
|
15
|
+
contest = omega.contest(contest_name)
|
16
|
+
failed = []
|
17
|
+
users.each do |user|
|
18
|
+
puts "Adding #{user}..."
|
19
|
+
contest.add_user(user)
|
20
|
+
rescue StandardError => e
|
21
|
+
puts "Error adding #{user}: #{e.message}"
|
22
|
+
failed << user
|
23
|
+
end
|
24
|
+
puts "Failed users: \n- #{failed.join("\n- ")}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def user_data(user)
|
28
|
+
puts omega.user(user).full_data.to_yaml
|
29
|
+
end
|
30
|
+
|
31
|
+
def scoreboard(contest_name)
|
32
|
+
score = omega.scoreboard(contest_name)
|
33
|
+
score.simple_display.each_with_index { |s, i| puts "#{i + 1}.- #{s.values.join(': ')}" }
|
34
|
+
rescue StandardError => e
|
35
|
+
puts "#{contest_name}: #{e.message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/omega/client.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'contest'
|
4
|
+
require_relative 'scoreboard'
|
5
|
+
require_relative 'user'
|
6
|
+
|
7
|
+
require 'httparty'
|
8
|
+
|
9
|
+
module Omega
|
10
|
+
class OmegaError < StandardError
|
11
|
+
attr_reader :data
|
12
|
+
|
13
|
+
def initialize(data)
|
14
|
+
@data = data
|
15
|
+
end
|
16
|
+
|
17
|
+
def message
|
18
|
+
"#{@data[:errorname]}::#{@data[:errorcode]} >> #{@data[:error]}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Client
|
23
|
+
include HTTParty
|
24
|
+
|
25
|
+
def initialize(conf)
|
26
|
+
@config = conf
|
27
|
+
end
|
28
|
+
|
29
|
+
def perform_request(method, endpoint, data)
|
30
|
+
url = "#{@config['endpoint']}#{endpoint}"
|
31
|
+
response = self.class.send(method, url, body: data)
|
32
|
+
body = JSON.parse(response.body, symbolize_names: true)
|
33
|
+
raise OmegaError, body if body[:error]
|
34
|
+
|
35
|
+
body
|
36
|
+
end
|
37
|
+
|
38
|
+
def post(endpoint, data)
|
39
|
+
perform_request(:post, endpoint, data)
|
40
|
+
end
|
41
|
+
|
42
|
+
def login
|
43
|
+
data = post('/api/user/login',
|
44
|
+
usernameOrEmail: @config['user'],
|
45
|
+
password: @config['pass'])
|
46
|
+
@token = data[:auth_token]
|
47
|
+
self.class.default_cookies.add_cookies('ouat' => data[:auth_token])
|
48
|
+
end
|
49
|
+
|
50
|
+
def open_contest(name)
|
51
|
+
post('/api/contest/open/', { contest_alias: name })
|
52
|
+
end
|
53
|
+
|
54
|
+
def contest(name)
|
55
|
+
data = post('/api/contest/details/', { contest_alias: name })
|
56
|
+
Contest.new(self, data)
|
57
|
+
rescue OmegaError => e
|
58
|
+
raise unless e.data[:errorname] == 'userNotAllowed'
|
59
|
+
|
60
|
+
open_contest(name)
|
61
|
+
retry
|
62
|
+
end
|
63
|
+
|
64
|
+
def scoreboard(name)
|
65
|
+
data = post('/api/contest/scoreboard/', { contest_alias: name })
|
66
|
+
Scoreboard.new(self, data)
|
67
|
+
end
|
68
|
+
|
69
|
+
def user(user)
|
70
|
+
data = post('/api/user/profile/', { username: user })
|
71
|
+
User.new(self, data)
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_user_to_contest(user, contest)
|
75
|
+
post('/api/contest/addUser', { contest_alias: contest, usernameOrEmail: user })
|
76
|
+
end
|
77
|
+
|
78
|
+
def problems_solved(user)
|
79
|
+
post('/api/user/problemsSolved/', { username: user })
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module Omega
|
6
|
+
class Contest < Base
|
7
|
+
def scoreboard
|
8
|
+
@client.scoreboard(data[:alias])
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_user(user)
|
12
|
+
if user.is_a?(String)
|
13
|
+
@client.add_user_to_contest(user, data[:alias])
|
14
|
+
else
|
15
|
+
@client.add_user_to_contest(user.data[:username], data[:alias])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def observe
|
20
|
+
last = current = scoreboard
|
21
|
+
sleep(5)
|
22
|
+
loop do
|
23
|
+
current = scoreboard
|
24
|
+
last.users.each do |score|
|
25
|
+
puts score.username
|
26
|
+
current_score = current.score_for(score.username)
|
27
|
+
score.problems.each do |problem|
|
28
|
+
name = problem[:alias]
|
29
|
+
current_problem = current_score.score_for(name)
|
30
|
+
last_points = problem[:points]
|
31
|
+
current_points = current_problem[:points]
|
32
|
+
puts " #{name}::#{last_points} >> #{current_points}"
|
33
|
+
yield(contest_name, score.username, name, current_points, last_points) if current_points != last_points
|
34
|
+
end
|
35
|
+
puts '-' * 60
|
36
|
+
end
|
37
|
+
last = current
|
38
|
+
sleep(15)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module Omega
|
6
|
+
class ScoreboardEntry < Base
|
7
|
+
attr_accessor :problems
|
8
|
+
attr_reader :username
|
9
|
+
|
10
|
+
def initialize(client, entry)
|
11
|
+
@username = entry[:username]
|
12
|
+
@client = client
|
13
|
+
@problems = entry[:problems] || []
|
14
|
+
@data = entry
|
15
|
+
end
|
16
|
+
|
17
|
+
def merge(score)
|
18
|
+
result = clone
|
19
|
+
result.problems += score.problems
|
20
|
+
result.data[:total][:points] += score.data[:total][:points]
|
21
|
+
result
|
22
|
+
end
|
23
|
+
|
24
|
+
def simple_display
|
25
|
+
{
|
26
|
+
username: @data[:username],
|
27
|
+
score: @data[:total][:points]
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def <=>(other)
|
32
|
+
other.data[:total][:points] <=> @data[:total][:points]
|
33
|
+
end
|
34
|
+
|
35
|
+
def score_for(name)
|
36
|
+
problems.each do |problem|
|
37
|
+
return problem if problem[:alias] == name
|
38
|
+
end
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Scoreboard < Base
|
44
|
+
def initialize(client, data)
|
45
|
+
@client = client
|
46
|
+
@data = data.dup
|
47
|
+
@data[:ranking] = {}
|
48
|
+
data[:ranking].each do |entry|
|
49
|
+
@data[:ranking][entry[:username]] = ScoreboardEntry.new(client, entry)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def merge(board)
|
54
|
+
result = clone
|
55
|
+
board.data[:ranking].each do |user, score|
|
56
|
+
result.data[:ranking][user] =
|
57
|
+
result.data[:ranking][user].nil? ? score : result.data[:ranking][user].merge(score)
|
58
|
+
end
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
def simple_display
|
63
|
+
users.map(&:simple_display)
|
64
|
+
end
|
65
|
+
|
66
|
+
def score_for(user)
|
67
|
+
@data[:ranking][user]
|
68
|
+
end
|
69
|
+
|
70
|
+
def users
|
71
|
+
@data[:ranking].values.sort
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/omega/user.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
|
5
|
+
module Omega
|
6
|
+
class User < Base
|
7
|
+
def full_data
|
8
|
+
{
|
9
|
+
data: @data,
|
10
|
+
problems_solved: problems_solved,
|
11
|
+
resume: report
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def problems_solved
|
16
|
+
@client.problems_solved(data[:username])[:problems]
|
17
|
+
end
|
18
|
+
|
19
|
+
def report
|
20
|
+
data = { score: 0, count: 0 }
|
21
|
+
problems_solved.each do |p|
|
22
|
+
data[:score] += p[:difficulty] || 0
|
23
|
+
data[:count] += 1
|
24
|
+
end
|
25
|
+
data
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/omega.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'omega/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'omegaup'
|
9
|
+
spec.version = Omega::VERSION
|
10
|
+
spec.authors = ['Gilberto Vargas']
|
11
|
+
spec.email = ['tachoguitar@gmail.com']
|
12
|
+
|
13
|
+
spec.summary = 'File created for encrypting files using ssh keys'
|
14
|
+
spec.description = 'Allows to encrypt files using ssh keys'
|
15
|
+
spec.homepage = 'https://github.com/omijal/omegaup-cli'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
spec.bindir = 'bin'
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
23
|
+
spec.require_paths = ['lib']
|
24
|
+
|
25
|
+
spec.add_development_dependency 'amazing_print'
|
26
|
+
spec.add_development_dependency 'minitest', '~> 5'
|
27
|
+
spec.add_development_dependency 'optimist'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omegaup
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gilberto Vargas
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: amazing_print
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: optimist
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description: Allows to encrypt files using ssh keys
|
70
|
+
email:
|
71
|
+
- tachoguitar@gmail.com
|
72
|
+
executables:
|
73
|
+
- omega
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".rubocop.yml"
|
78
|
+
- Gemfile
|
79
|
+
- bin/omega
|
80
|
+
- lib/omega.rb
|
81
|
+
- lib/omega/base.rb
|
82
|
+
- lib/omega/cli.rb
|
83
|
+
- lib/omega/cli/contest.rb
|
84
|
+
- lib/omega/client.rb
|
85
|
+
- lib/omega/contest.rb
|
86
|
+
- lib/omega/scoreboard.rb
|
87
|
+
- lib/omega/user.rb
|
88
|
+
- lib/omega/version.rb
|
89
|
+
- omega.gemspec
|
90
|
+
homepage: https://github.com/omijal/omegaup-cli
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubygems_version: 3.1.4
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: File created for encrypting files using ssh keys
|
113
|
+
test_files: []
|