omegaup 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []