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 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
@@ -0,0 +1,3 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+ NewCops: enable
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
data/bin/omega ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/omega/cli'
5
+
6
+ Omega::CLI.new(ARGV).execute
data/lib/omega.rb ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'omega/base'
4
+ require_relative 'omega/contest'
5
+ require_relative 'omega/scoreboard'
6
+ require_relative 'omega/user'
7
+ require_relative 'omega/client'
data/lib/omega/base.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omega
4
+ class Base
5
+ attr_reader :data
6
+
7
+ def initialize(client, data)
8
+ @client = client
9
+ @data = data
10
+ end
11
+ end
12
+ end
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
@@ -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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Omega
4
+ VERSION = '0.1.0'
5
+ 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: []