codeforces_api 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/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +69 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/codeforces_api.gemspec +21 -0
- data/lib/codeforces_api.rb +20 -0
- data/lib/codeforces_api/client.rb +43 -0
- data/lib/codeforces_api/client/contest.rb +58 -0
- data/lib/codeforces_api/client/helper.rb +33 -0
- data/lib/codeforces_api/client/problemset.rb +33 -0
- data/lib/codeforces_api/client/user.rb +49 -0
- data/lib/codeforces_api/configuration.rb +26 -0
- data/lib/codeforces_api/object/contest.rb +31 -0
- data/lib/codeforces_api/object/hack.rb +25 -0
- data/lib/codeforces_api/object/member.rb +15 -0
- data/lib/codeforces_api/object/party.rb +23 -0
- data/lib/codeforces_api/object/problem.rb +20 -0
- data/lib/codeforces_api/object/problem_result.rb +19 -0
- data/lib/codeforces_api/object/problem_statistics.rb +17 -0
- data/lib/codeforces_api/object/ranklist_row.rb +25 -0
- data/lib/codeforces_api/object/rating_change.rb +20 -0
- data/lib/codeforces_api/object/submission.rb +28 -0
- data/lib/codeforces_api/object/user.rb +31 -0
- data/lib/codeforces_api/version.rb +3 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3ca7a0de1e263b7325b48009dcc33ef3ee2b9078
|
4
|
+
data.tar.gz: 59268e75efd87ab4e7a8057e99197ef5ae112292
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f9ced42650bc50aad25b9a2447957f259e38f6e03f2d795c77c4dbd4c5773803afb7d4540254605b465e3236b16158689a49d80746a128ba28cfd19219077e9
|
7
|
+
data.tar.gz: 09f35c05d4864106081024bb32361f1519127ab687b99c3b121ed1b799ad246531653e921e6f57029bd4761723227402c79301603ccdc688d3880fe7611ccd35
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# CodeforcesAPI
|
2
|
+
|
3
|
+
a ruby wrapper of [codeforces api][cfapi].
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'codeforces_api'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install codeforces_api
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### Configuration
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
CodeforcesAPI.configure do |config|
|
27
|
+
config.key = YOUR_API_KEY
|
28
|
+
config.secret = YOUR_API_SECRET
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
once you setup the api key, all the methods are through authorization.
|
33
|
+
if you have not set up the key info, all the methods are anonymouse.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
CodeforcesAPI.reset!
|
37
|
+
```
|
38
|
+
|
39
|
+
this will clear the api key info.
|
40
|
+
|
41
|
+
|
42
|
+
### Methods
|
43
|
+
|
44
|
+
let's take me(delta\_4d) as an example
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
me, tourist = CodeforcesAPI.user.info('delta_4d', 'tourist')
|
48
|
+
puts me.rank # master
|
49
|
+
puts tourist.rank # international grandmaster
|
50
|
+
```
|
51
|
+
|
52
|
+
you can also use the `user` object
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
user = CodeforcesAPI.user
|
56
|
+
first_contest = user.rating('delta_4d')[0]
|
57
|
+
puts "#{first_contest.contestName} #{first_contest.newRating}"
|
58
|
+
# Codeforces Beta Round #30 (Codeforces format) 1430
|
59
|
+
```
|
60
|
+
|
61
|
+
as you can see, the usage are pretty much the same as in the [official doc][cfapi].
|
62
|
+
|
63
|
+
## Contributing
|
64
|
+
|
65
|
+
feel free to file an issue or send a pr.
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
[cfapi]: http://codeforces.com/api/help
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "codeforces_api"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'codeforces_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "codeforces_api"
|
8
|
+
spec.version = CodeforcesAPI::VERSION
|
9
|
+
spec.authors = ["delta"]
|
10
|
+
spec.email = ["delta4d@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{a ruby wrapper of codeforces api}
|
13
|
+
spec.description = %q{a ruby wrapper of codeforces api}
|
14
|
+
spec.homepage = "https://github.com/delta4d/codeforces_api"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
19
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
20
|
+
spec.add_development_dependency "rspec"
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path("../codeforces_api/client", __FILE__)
|
2
|
+
require File.expand_path("../codeforces_api/version", __FILE__)
|
3
|
+
|
4
|
+
module CodeforcesAPI
|
5
|
+
class << self
|
6
|
+
include CodeforcesAPI::Configuration
|
7
|
+
|
8
|
+
def client
|
9
|
+
return @client if defined?(@client)
|
10
|
+
@client ||= CodeforcesAPI::Client.new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def method_missing method, *args, &block
|
16
|
+
return super unless client.respond_to?(method)
|
17
|
+
client.send(method, *args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
require 'digest/sha2'
|
4
|
+
|
5
|
+
require File.expand_path('../client/user', __FILE__)
|
6
|
+
require File.expand_path('../client/helper', __FILE__)
|
7
|
+
require File.expand_path('../configuration', __FILE__)
|
8
|
+
require File.expand_path('../client/contest', __FILE__)
|
9
|
+
require File.expand_path('../client/problemset', __FILE__)
|
10
|
+
|
11
|
+
require File.expand_path('../object/user', __FILE__)
|
12
|
+
require File.expand_path('../object/hack', __FILE__)
|
13
|
+
require File.expand_path('../object/party', __FILE__)
|
14
|
+
require File.expand_path('../object/member', __FILE__)
|
15
|
+
require File.expand_path('../object/contest', __FILE__)
|
16
|
+
require File.expand_path('../object/problem', __FILE__)
|
17
|
+
require File.expand_path('../object/submission', __FILE__)
|
18
|
+
require File.expand_path('../object/ranklist_row', __FILE__)
|
19
|
+
require File.expand_path('../object/rating_change', __FILE__)
|
20
|
+
require File.expand_path('../object/problem_result', __FILE__)
|
21
|
+
require File.expand_path('../object/problem_statistics', __FILE__)
|
22
|
+
|
23
|
+
module CodeforcesAPI
|
24
|
+
class Client
|
25
|
+
include CodeforcesAPI::Configuration
|
26
|
+
|
27
|
+
def initialize options = {}
|
28
|
+
options.each{ |k, v| instance_variable_set(:"@#{k}", v) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def user
|
32
|
+
@user ||= CodeforcesAPI::MethodClass::User.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def contest
|
36
|
+
@contest ||= CodeforcesAPI::MethodClass::Contest.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def problemset
|
40
|
+
@problemset ||= CodeforcesAPI::MethodClass::ProblemSet.new
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module MethodClass
|
3
|
+
class Contest
|
4
|
+
def hacks contestId
|
5
|
+
params = {'contestId' => contestId}
|
6
|
+
json_request = CodeforcesAPI.client.get('contest.hacks', params)
|
7
|
+
if json_request['status'] != 'OK'
|
8
|
+
raise json_request['result']
|
9
|
+
else
|
10
|
+
json_hacks = json_request['result']
|
11
|
+
hacks = json_hacks.collect{ |h| CodeforcesAPI::Object::Hack.new(h) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def list gym = false
|
16
|
+
params = {'gym' => gym}
|
17
|
+
json_request = CodeforcesAPI.client.get('contest.list', params)
|
18
|
+
if json_request['status'] != 'OK'
|
19
|
+
raise json_request['result']
|
20
|
+
else
|
21
|
+
json_contests = json_request['result']
|
22
|
+
contests = json_contests.collect{ |c| CodeforcesAPI::Object::Contest.new(c) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def standings contestId, optional_params = {}
|
27
|
+
required_params = {'contestId' => contestId}
|
28
|
+
json_request = CodeforcesAPI.client.get('contest.standings', required_params, optional_params)
|
29
|
+
if json_request['status'] != 'OK'
|
30
|
+
raise json_request['result']
|
31
|
+
else
|
32
|
+
json_result = json_request['result']
|
33
|
+
|
34
|
+
json_contest = json_result['contest']
|
35
|
+
json_problems = json_result['problems']
|
36
|
+
json_rows = json_result['rows']
|
37
|
+
|
38
|
+
{
|
39
|
+
'contest' => CodeforcesAPI::Object::Contest.new(json_contest),
|
40
|
+
'problems' => json_problems.collect{ |p| CodeforcesAPI::Object::Problem.new(p) },
|
41
|
+
'rows' => json_rows.collect{ |r| CodeforcesAPI::Object::RanklistRow.new(r) },
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def status contestId, optional_params = {}
|
47
|
+
required_params = {'contestId' => contestId}
|
48
|
+
json_request = CodeforcesAPI.client.get('contest.status', required_params, optional_params)
|
49
|
+
if json_request['status'] != 'OK'
|
50
|
+
raise json_request['result']
|
51
|
+
else
|
52
|
+
json_submissions = json_request['result']
|
53
|
+
submissinos = json_submissions.collect{ |sub| CodeforcesAPI::Object::Submission.new(sub) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
class Client
|
3
|
+
API_URI = 'http://codeforces.com/api'
|
4
|
+
|
5
|
+
def rand6
|
6
|
+
[*0..5].collect{ rand(10) }.join
|
7
|
+
end
|
8
|
+
|
9
|
+
def post_form options = {}
|
10
|
+
options.collect{ |k, v| "#{k}=#{v}" }.join('&')
|
11
|
+
end
|
12
|
+
|
13
|
+
def request_url method, _params
|
14
|
+
url = "#{API_URI}/#{method}?#{post_form(_params)}"
|
15
|
+
return url unless using_api?
|
16
|
+
salt = rand6()
|
17
|
+
time = Time.now.to_i
|
18
|
+
info = {'apiKey' => @key, 'time' => time}
|
19
|
+
params = _params.merge(info).map{|k, v| [k.to_s, v]}.sort.to_h
|
20
|
+
digest_string = "#{salt}/#{method}?#{post_form(params)}##{@secret}"
|
21
|
+
api_sig = Digest::SHA2.new(512).hexdigest(digest_string)
|
22
|
+
params.merge!('apiSig'=>"#{salt}#{api_sig}")
|
23
|
+
"#{API_URI}/#{method}?#{post_form(params)}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def get method, required_params, optional_params = {}
|
27
|
+
params = required_params.merge(optional_params)
|
28
|
+
uri = URI(request_url(method, params))
|
29
|
+
http_response = Net::HTTP.get(uri)
|
30
|
+
json_response = JSON.parse(http_response)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module MethodClass
|
3
|
+
class ProblemSet
|
4
|
+
def problems *tags
|
5
|
+
params = {'tags' => tags.join(';')}
|
6
|
+
json_request = CodeforcesAPI.client.get('problemset.problems', params)
|
7
|
+
if json_request['status'] != 'OK'
|
8
|
+
raise json_request['result']
|
9
|
+
else
|
10
|
+
json_result = json_request['result']
|
11
|
+
json_problems = json_result['problems']
|
12
|
+
json_problemstatistics = json_result['problemStatistics']
|
13
|
+
|
14
|
+
{
|
15
|
+
'problems' => json_problems.collect{ |p| CodeforcesAPI::Object::Problem.new(p) },
|
16
|
+
'problemStatistics' => json_problemstatistics.collect{ |ps| CodeforcesAPI::Object::ProblemStatistics.new(ps) },
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def recentStatus count
|
22
|
+
params = {'count' => count}
|
23
|
+
json_request = CodeforcesAPI.client.get('problemset.recentStatus', params)
|
24
|
+
if json_request['status'] != 'OK'
|
25
|
+
raise json_request['result']
|
26
|
+
else
|
27
|
+
json_sumbissions = json_request['result']
|
28
|
+
submissions = json_sumbissions.collect{ |sub| CodeforcesAPI::Object::Submission.new(sub) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module MethodClass
|
3
|
+
class User
|
4
|
+
def info *handles
|
5
|
+
params = {'handles' => handles.join(';')}
|
6
|
+
json_request = CodeforcesAPI.client.get('user.info', params)
|
7
|
+
if json_request['status'] != 'OK'
|
8
|
+
raise json_request['result']
|
9
|
+
else
|
10
|
+
json_users = json_request['result']
|
11
|
+
users = json_users.collect{ |user| CodeforcesAPI::Object::User.new(user) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def ratedList activeOnly = true
|
16
|
+
params = {'activeOnly' => activeOnly}
|
17
|
+
json_request = CodeforcesAPI.client.get('user.ratedList', params)
|
18
|
+
if json_request['status'] != 'OK'
|
19
|
+
raise json_request['result']
|
20
|
+
else
|
21
|
+
json_users = json_request['result']
|
22
|
+
users = json_users.collect{ |user| CodeforcesAPI::Object::User.new(user) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def rating handle
|
27
|
+
params = {'handle' => handle}
|
28
|
+
json_request = CodeforcesAPI.client.get('user.rating', params)
|
29
|
+
if json_request['status'] != 'OK'
|
30
|
+
raise json_request['result']
|
31
|
+
else
|
32
|
+
json_ratingchanges = json_request['result']
|
33
|
+
ratingchanges = json_ratingchanges.collect{ |rc| CodeforcesAPI::Object::RatingChange.new(rc) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def status handle, optional_params
|
38
|
+
required_params = {'handle' => handle}
|
39
|
+
json_request = CodeforcesAPI.client.get('user.status', required_params, optional_params)
|
40
|
+
if json_request['status'] != 'OK'
|
41
|
+
raise json_request['result']
|
42
|
+
else
|
43
|
+
json_submissions = json_request['result']
|
44
|
+
submissions = json_submissions.collect{ |sub| CodeforcesAPI::Object::Submission.new(sub) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Configuration
|
3
|
+
ATTRS = [:key, :secret, :use_api].freeze
|
4
|
+
|
5
|
+
attr_accessor *ATTRS
|
6
|
+
|
7
|
+
def configure
|
8
|
+
@use_api = true
|
9
|
+
yield self
|
10
|
+
end
|
11
|
+
|
12
|
+
def options
|
13
|
+
ATTRS.collect{ |attr| [attr, instance_variable_get(:"@#{attr}")] }.to_h
|
14
|
+
end
|
15
|
+
|
16
|
+
def using_api?
|
17
|
+
@use_api
|
18
|
+
end
|
19
|
+
|
20
|
+
def reset!
|
21
|
+
@key = nil
|
22
|
+
@secret = nil
|
23
|
+
@use_api = false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class Contest
|
4
|
+
ATTRS = [
|
5
|
+
:id,
|
6
|
+
:name,
|
7
|
+
:type,
|
8
|
+
:phase,
|
9
|
+
:frozen,
|
10
|
+
:durationSeconds,
|
11
|
+
:startTimeSeconds,
|
12
|
+
:relativeTimeSeconds,
|
13
|
+
:preparedBy,
|
14
|
+
:websiteUrl,
|
15
|
+
:description,
|
16
|
+
:difficulty,
|
17
|
+
:kind,
|
18
|
+
:icpcRegion,
|
19
|
+
:country,
|
20
|
+
:city,
|
21
|
+
:season,
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
attr_reader *ATTRS
|
25
|
+
|
26
|
+
def initialize contest
|
27
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", contest[attr.to_s]) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class Hack
|
4
|
+
ATTRS = [
|
5
|
+
:id,
|
6
|
+
:creationTimeSeconds,
|
7
|
+
:hacker,
|
8
|
+
:defender,
|
9
|
+
:verdict,
|
10
|
+
:problem,
|
11
|
+
:test,
|
12
|
+
:judgeProtocol,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
attr_reader *ATTRS
|
16
|
+
|
17
|
+
def initialize hack
|
18
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", hack[attr.to_s]) }
|
19
|
+
@hacker = Party.new(@hacker) if @hacker
|
20
|
+
@defender = Party.new(@defender) if @defender
|
21
|
+
@problem = Problem.new(@problem) if @problem
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class Party
|
4
|
+
ATTRS = [
|
5
|
+
:contestId,
|
6
|
+
:members,
|
7
|
+
:participantType,
|
8
|
+
:teamId,
|
9
|
+
:teamName,
|
10
|
+
:ghost,
|
11
|
+
:room,
|
12
|
+
:startTimeSeconds,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
attr_reader *ATTRS
|
16
|
+
|
17
|
+
def initialize party
|
18
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", party[attr.to_s]) }
|
19
|
+
@members = @members.map{|mem| Member.new(mem)} if @members
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class Problem
|
4
|
+
ATTRS = [
|
5
|
+
:contestId,
|
6
|
+
:index,
|
7
|
+
:name,
|
8
|
+
:type,
|
9
|
+
:points,
|
10
|
+
:tags,
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
attr_reader *ATTRS
|
14
|
+
|
15
|
+
def initialize prob
|
16
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", prob[attr.to_s]) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class ProblemResult
|
4
|
+
ATTRS = [
|
5
|
+
:points,
|
6
|
+
:penalty,
|
7
|
+
:rejectedAttemptCount,
|
8
|
+
:type,
|
9
|
+
:bestSubmissionTimeSeconds,
|
10
|
+
].freeze
|
11
|
+
|
12
|
+
attr_reader *ATTRS
|
13
|
+
|
14
|
+
def initialize problem_result
|
15
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", problem_result[attr.to_s]) }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class ProblemStatistics
|
4
|
+
ATTRS = [
|
5
|
+
:contestId,
|
6
|
+
:index,
|
7
|
+
:solvedCount,
|
8
|
+
].freeze
|
9
|
+
|
10
|
+
attr_reader *ATTRS
|
11
|
+
|
12
|
+
def initialize probstat
|
13
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", probstat[attr.to_s]) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class RanklistRow
|
4
|
+
ATTRS = [
|
5
|
+
:party,
|
6
|
+
:rank,
|
7
|
+
:points,
|
8
|
+
:penalty,
|
9
|
+
:successfulHackCount,
|
10
|
+
:unsuccessfulHackCount,
|
11
|
+
:problemResults,
|
12
|
+
:lastSubmissionTimeSeconds,
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
attr_reader *ATTRS
|
16
|
+
|
17
|
+
def initialize ranklist_row
|
18
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", ranklist_row[attr.to_s]) }
|
19
|
+
@party = Party.new(@party) if @party
|
20
|
+
@problemResults = @problemResults.map { |pr| ProblemResult.new(pr) } if @problemResults
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class RatingChange
|
4
|
+
ATTRS = [
|
5
|
+
:contestId,
|
6
|
+
:contestName,
|
7
|
+
:rank,
|
8
|
+
:ratingUpdateTimeSeconds,
|
9
|
+
:oldRating,
|
10
|
+
:newRating,
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
attr_reader *ATTRS
|
14
|
+
|
15
|
+
def initialize rate
|
16
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", rate[attr.to_s]) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class Submission
|
4
|
+
ATTRS = [
|
5
|
+
:id,
|
6
|
+
:contestId,
|
7
|
+
:creationTimeSeconds,
|
8
|
+
:relativeTimeSeconds,
|
9
|
+
:problem,
|
10
|
+
:author,
|
11
|
+
:programmingLanguage,
|
12
|
+
:verdict,
|
13
|
+
:testset,
|
14
|
+
:passedTestCount,
|
15
|
+
:timeConsumedMillis,
|
16
|
+
:memoryConsumedBytes,
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
attr_reader *ATTRS
|
20
|
+
|
21
|
+
def initialize sub
|
22
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", sub[attr.to_s]) }
|
23
|
+
@problem = Problem.new(@problem) if @problem
|
24
|
+
@author = Party.new(@author) if @author
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module CodeforcesAPI
|
2
|
+
module Object
|
3
|
+
class User
|
4
|
+
ATTRS = [
|
5
|
+
:handle,
|
6
|
+
:email,
|
7
|
+
:vkId,
|
8
|
+
:openId,
|
9
|
+
:firstName,
|
10
|
+
:lastName,
|
11
|
+
:country,
|
12
|
+
:city,
|
13
|
+
:organization,
|
14
|
+
:contribution,
|
15
|
+
:rank,
|
16
|
+
:rating,
|
17
|
+
:maxRank,
|
18
|
+
:maxRating,
|
19
|
+
:lastOnlineTimeSeconds,
|
20
|
+
:registrationTimeSeconds
|
21
|
+
].freeze
|
22
|
+
|
23
|
+
attr_reader *ATTRS
|
24
|
+
|
25
|
+
def initialize user
|
26
|
+
ATTRS.each { |attr| instance_variable_set("@#{attr}", user[attr.to_s]) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: codeforces_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- delta
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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
|
+
description: a ruby wrapper of codeforces api
|
56
|
+
email:
|
57
|
+
- delta4d@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- ".rspec"
|
64
|
+
- ".travis.yml"
|
65
|
+
- Gemfile
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/console
|
69
|
+
- bin/setup
|
70
|
+
- codeforces_api.gemspec
|
71
|
+
- lib/codeforces_api.rb
|
72
|
+
- lib/codeforces_api/client.rb
|
73
|
+
- lib/codeforces_api/client/contest.rb
|
74
|
+
- lib/codeforces_api/client/helper.rb
|
75
|
+
- lib/codeforces_api/client/problemset.rb
|
76
|
+
- lib/codeforces_api/client/user.rb
|
77
|
+
- lib/codeforces_api/configuration.rb
|
78
|
+
- lib/codeforces_api/object/contest.rb
|
79
|
+
- lib/codeforces_api/object/hack.rb
|
80
|
+
- lib/codeforces_api/object/member.rb
|
81
|
+
- lib/codeforces_api/object/party.rb
|
82
|
+
- lib/codeforces_api/object/problem.rb
|
83
|
+
- lib/codeforces_api/object/problem_result.rb
|
84
|
+
- lib/codeforces_api/object/problem_statistics.rb
|
85
|
+
- lib/codeforces_api/object/ranklist_row.rb
|
86
|
+
- lib/codeforces_api/object/rating_change.rb
|
87
|
+
- lib/codeforces_api/object/submission.rb
|
88
|
+
- lib/codeforces_api/object/user.rb
|
89
|
+
- lib/codeforces_api/version.rb
|
90
|
+
homepage: https://github.com/delta4d/codeforces_api
|
91
|
+
licenses: []
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.2.3
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: a ruby wrapper of codeforces api
|
113
|
+
test_files: []
|
114
|
+
has_rdoc:
|