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 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
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.6
4
+ before_install: gem install bundler -v 1.10.4
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in codeforces_api.gemspec
4
+ gemspec
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,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -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,15 @@
1
+ module CodeforcesAPI
2
+ module Object
3
+ class Member
4
+ ATTRS = [
5
+ :handle
6
+ ].freeze
7
+
8
+ attr_reader *ATTRS
9
+
10
+ def initialize mem
11
+ ATTRS.each { |attr| instance_variable_set("@#{attr}", mem[attr.to_s]) }
12
+ end
13
+ end
14
+ end
15
+ 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
+
@@ -0,0 +1,3 @@
1
+ module CodeforcesAPI
2
+ VERSION = "0.1.0"
3
+ end
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: