clashinator 0.2 → 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 +4 -4
- data/.gitignore +7 -3
- data/README.md +27 -16
- data/Rakefile +9 -2
- data/clashinator.gemspec +6 -3
- data/config/secrets.sample.yml +1 -0
- data/lib/clashinator.rb +19 -9
- data/lib/clashinator/achievement.rb +16 -0
- data/lib/clashinator/army.rb +13 -0
- data/lib/clashinator/array_resource.rb +43 -0
- data/lib/clashinator/badge_url.rb +13 -0
- data/lib/clashinator/base.rb +94 -0
- data/lib/clashinator/clan.rb +64 -0
- data/lib/clashinator/clan_ranking.rb +8 -0
- data/lib/clashinator/client.rb +52 -63
- data/lib/clashinator/hero.rb +9 -0
- data/lib/clashinator/league.rb +65 -0
- data/lib/clashinator/location.rb +55 -0
- data/lib/clashinator/player.rb +17 -0
- data/lib/clashinator/player_ranking.rb +8 -0
- data/lib/clashinator/season.rb +11 -0
- data/lib/clashinator/spell.rb +9 -0
- data/lib/clashinator/troop.rb +9 -0
- data/lib/clashinator/util/camelcase.rb +8 -0
- data/lib/clashinator/util/underscore.rb +12 -0
- data/lib/clashinator/version.rb +1 -1
- data/lib/clashinator/warlog.rb +8 -0
- metadata +75 -14
- data/Gemfile.lock +0 -27
- data/lib/clashinator/exceptions.rb +0 -2
- data/lib/clashinator/exceptions/base.rb +0 -5
- data/lib/clashinator/exceptions/response_error.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed4851e0beea8740bebd70663cb2bbedf1a89ab8
|
4
|
+
data.tar.gz: a831cbf6903981ae591e0509d1dca692d0fa341c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bfbc1ab8d0057c15277dcd373580505d360df36db1914d9d28b66ebffa14b7b2ba75394b18aa6f1566f7dea50188430d2c0efbdc40f2d2a817a2bd7c7cf3d03
|
7
|
+
data.tar.gz: 2b840f99c50a0e4dbb403a6f12b7535ebe65d27586d4b484fcd550ecc06ff483d55711a8b2daae4968117f58033348e05772d49581a1823ce1d27ddd2cdf827a
|
data/.gitignore
CHANGED
@@ -28,9 +28,13 @@ build/
|
|
28
28
|
|
29
29
|
# for a library or gem, you might want to ignore these files since the code is
|
30
30
|
# intended to run in multiple environments; otherwise, check them in:
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
Gemfile.lock
|
32
|
+
.ruby-version
|
33
|
+
.ruby-gemset
|
34
34
|
|
35
35
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
36
36
|
.rvmrc
|
37
|
+
|
38
|
+
# hide secrets
|
39
|
+
secrets.yml
|
40
|
+
spec/fixtures/*.yml
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Clashinator
|
2
2
|
|
3
|
-
Ruby wrapper for the Clash of Clans API
|
3
|
+
Ruby wrapper for the Clash of Clans API, based on the v1 version
|
4
|
+
|
5
|
+
Note: These docs were updated for the new tagged version 1.0
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -27,32 +29,37 @@ With your access token, retrieve a client instance with it.
|
|
27
29
|
|
28
30
|
`client = Clashinator::Client.new('YOUR TOKEN')`
|
29
31
|
|
30
|
-
|
32
|
+
All query options can be passed as underscored variables instead of
|
33
|
+
camelcased, query options available are at: [https://developer.clashofclans.com](https://developer.clashofclans.com)
|
34
|
+
|
35
|
+
There are several types of objects you can retrieve:
|
31
36
|
|
32
37
|
```ruby
|
33
|
-
client.
|
38
|
+
clans = client.search_clans(name: 'vzlan warriors', min_members: 25)
|
39
|
+
|
40
|
+
clan = client.clan_info('#VQ2QUJG')
|
34
41
|
|
35
|
-
client.
|
42
|
+
players = client.list_clan_members('#VQ2QUJG')
|
36
43
|
|
37
|
-
client.
|
44
|
+
war_log = client.clan_war_log('#VQ2QUJG')
|
38
45
|
|
39
|
-
client.
|
46
|
+
locations = client.list_locations
|
40
47
|
|
41
|
-
client.
|
48
|
+
location = client.location_info(32000254)
|
42
49
|
|
43
|
-
client.
|
50
|
+
clan_rankings = client.location_clan_rankings(32000254)
|
44
51
|
|
45
|
-
client.
|
52
|
+
player_rankings = client.location_player_rankings(32000254)
|
46
53
|
|
47
|
-
client.
|
54
|
+
leagues = client.list_leagues
|
48
55
|
|
49
|
-
client.
|
56
|
+
league = client.league_info(29000022)
|
50
57
|
|
51
|
-
client.
|
58
|
+
seasons = client.league_seasons(29000022)
|
52
59
|
|
53
|
-
client.
|
60
|
+
player_rankings = client.league_season_rankings(29000022, '2015-10')
|
54
61
|
|
55
|
-
client.
|
62
|
+
player = client.player_info('#QOCRLV90')
|
56
63
|
```
|
57
64
|
|
58
65
|
## Development
|
@@ -61,10 +68,14 @@ After checking out the repo, run `bin/setup` to install dependencies. You can al
|
|
61
68
|
|
62
69
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
63
70
|
|
64
|
-
|
71
|
+
Create a new file called `secrets.yml` in the config folder with the contents of `config/secrets.sample.yml`
|
72
|
+
Then, you'll need to generate an access token in Clash of Clans developer page at:
|
73
|
+
[https://developer.clashofclans.com](https://developer.clashofclans.com)
|
65
74
|
|
66
|
-
|
75
|
+
## Contributing
|
67
76
|
|
77
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/leocabeza/clash-api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
78
|
+
Remember to add a test for each new feature you add, and before submitting a pull request, check that all tests are passing by running: `rake`
|
68
79
|
|
69
80
|
## License
|
70
81
|
|
data/Rakefile
CHANGED
data/clashinator.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["info@leonardocabeza.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Ruby wrapper for the Clash of Clans API}
|
13
|
-
spec.homepage = "https://github.com/leocabeza/
|
13
|
+
spec.homepage = "https://github.com/leocabeza/clash-api"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
@@ -28,6 +28,9 @@ Gem::Specification.new do |spec|
|
|
28
28
|
|
29
29
|
spec.add_development_dependency "bundler", "~> 1.11"
|
30
30
|
spec.add_development_dependency "rake", "~> 10.0"
|
31
|
-
spec.
|
32
|
-
spec.
|
31
|
+
spec.add_development_dependency "webmock", "~> 2.1", ">= 2.1.0"
|
32
|
+
spec.add_development_dependency "vcr", "~> 3.0", ">= 3.0.3"
|
33
|
+
spec.add_development_dependency "minitest", "~> 5.9", ">= 5.9.1"
|
34
|
+
|
35
|
+
spec.add_dependency "httparty", "~> 0.14.0"
|
33
36
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
token_test: 'PUT_TEST_TOKEN_HERE'
|
data/lib/clashinator.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
|
-
require '
|
2
|
-
require 'faraday_middleware'
|
1
|
+
require 'httparty'
|
3
2
|
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
require 'clashinator/base.rb'
|
4
|
+
require 'clashinator/array_resource.rb'
|
5
|
+
require 'clashinator/army.rb'
|
6
|
+
require 'clashinator/season.rb'
|
7
|
+
require 'clashinator/clan_ranking.rb'
|
8
|
+
require 'clashinator/player_ranking.rb'
|
9
|
+
require 'clashinator/achievement.rb'
|
10
|
+
require 'clashinator/troop.rb'
|
11
|
+
require 'clashinator/hero.rb'
|
12
|
+
require 'clashinator/spell.rb'
|
13
|
+
require 'clashinator/warlog.rb'
|
14
|
+
require 'clashinator/badge_url.rb'
|
15
|
+
require 'clashinator/league.rb'
|
16
|
+
require 'clashinator/location.rb'
|
17
|
+
require 'clashinator/player.rb'
|
18
|
+
require 'clashinator/clan.rb'
|
19
|
+
require 'clashinator/version.rb'
|
20
|
+
require 'clashinator/client.rb'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the achievement model
|
3
|
+
# through the player model
|
4
|
+
class Achievement
|
5
|
+
attr_accessor :name, :stars, :value, :target, :info, :completion_info
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
@name = attributes['name']
|
9
|
+
@stars = attributes['stars']
|
10
|
+
@value = attributes['value']
|
11
|
+
@target = attributes['target']
|
12
|
+
@info = attributes['info']
|
13
|
+
@completion_info = attributes['completion_info']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the army model
|
3
|
+
# through the player model
|
4
|
+
class Army
|
5
|
+
attr_accessor :name, :level, :max_level
|
6
|
+
|
7
|
+
def initialize(attributes)
|
8
|
+
@name = attributes['name']
|
9
|
+
@level = attributes['level']
|
10
|
+
@max_level = attributes['maxLevel']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the array resource model
|
3
|
+
# This is only for array-based responses
|
4
|
+
# that contains an items attribute and
|
5
|
+
# a paging attribute
|
6
|
+
class ArrayResource
|
7
|
+
attr_accessor :items, :paging, :model
|
8
|
+
|
9
|
+
def initialize(model, items, paging = {})
|
10
|
+
# if after and before are equal, it means it's end of pagination
|
11
|
+
@model = model
|
12
|
+
@items = as_array_of_model(items)
|
13
|
+
@paging = Clashinator::ArrayResource::Cursor.new(
|
14
|
+
paging['cursors']['after'],
|
15
|
+
paging['cursors']['before']
|
16
|
+
) if paging.key?('cursors')
|
17
|
+
end
|
18
|
+
|
19
|
+
private def as_array_of_model(array)
|
20
|
+
new_array = []
|
21
|
+
|
22
|
+
array.each do |arr|
|
23
|
+
new_array.push(@model.new(arr)) if @model.class == Class
|
24
|
+
end
|
25
|
+
|
26
|
+
new_array
|
27
|
+
end
|
28
|
+
|
29
|
+
# This class represent the cursor model
|
30
|
+
# that contains an after & before attribute
|
31
|
+
# for properly paging array resources
|
32
|
+
class Cursor
|
33
|
+
attr_accessor :after, :before
|
34
|
+
|
35
|
+
def initialize(after, before)
|
36
|
+
# can't be both specified
|
37
|
+
# at the same time
|
38
|
+
@after = after
|
39
|
+
@before = before
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the BadgeUrl model
|
3
|
+
class BadgeUrl
|
4
|
+
attr_accessor :tiny, :small, :medium, :large
|
5
|
+
|
6
|
+
def initialize(attributes)
|
7
|
+
@tiny = attributes['tiny']
|
8
|
+
@small = attributes['small']
|
9
|
+
@medium = attributes['medium']
|
10
|
+
@large = attributes['large']
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative 'util/camelcase.rb'
|
2
|
+
require_relative 'util/underscore.rb'
|
3
|
+
|
4
|
+
module Clashinator
|
5
|
+
# This is the base class for the other entities
|
6
|
+
class Base
|
7
|
+
include HTTParty
|
8
|
+
include Underscorable
|
9
|
+
extend Camelizable
|
10
|
+
|
11
|
+
base_uri 'https://api.clashofclans.com'
|
12
|
+
|
13
|
+
CLASS_MAP = {
|
14
|
+
member_list: 'Player', achievements: 'Achievement',
|
15
|
+
troops: 'Troop', heroes: 'Hero', spells: 'Spell'
|
16
|
+
}.freeze
|
17
|
+
OBJECT_MAP = {
|
18
|
+
opponent: 'Clan', league: 'League',
|
19
|
+
location: 'Location', badge_urls: 'BadgeUrl',
|
20
|
+
icon_urls: 'BadgeUrl', clan: 'Clan'
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
def initialize(attrs)
|
24
|
+
attrs.each do |name, val|
|
25
|
+
lower_camel_cased = to_underscore(name)
|
26
|
+
(class << self; self; end).send(:attr_reader, lower_camel_cased.to_sym)
|
27
|
+
val = verify_hash_that_are_objects(lower_camel_cased.to_sym, val)
|
28
|
+
val = verify_array_of_classes(lower_camel_cased.to_sym, val)
|
29
|
+
instance_variable_set "@#{lower_camel_cased}", val
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def verify_hash_that_are_objects(lower_camel_cased, val)
|
34
|
+
if OBJECT_MAP.key? lower_camel_cased
|
35
|
+
class_name = 'Clashinator::' \
|
36
|
+
"#{OBJECT_MAP[lower_camel_cased]}"
|
37
|
+
val = Object
|
38
|
+
.const_get(class_name)
|
39
|
+
.new(val)
|
40
|
+
end
|
41
|
+
|
42
|
+
val
|
43
|
+
end
|
44
|
+
|
45
|
+
def verify_array_of_classes(lower_camel_cased, val)
|
46
|
+
key_found = CLASS_MAP.key?(lower_camel_cased)
|
47
|
+
val = get_array_resource(lower_camel_cased, val) if key_found
|
48
|
+
|
49
|
+
val
|
50
|
+
end
|
51
|
+
|
52
|
+
private def get_array_resource(lower_camel_cased, val)
|
53
|
+
class_name = "Clashinator::#{CLASS_MAP[lower_camel_cased]}"
|
54
|
+
model = Object.const_get(class_name)
|
55
|
+
# this condition is for paging structures
|
56
|
+
# for instance Clan.search_clans
|
57
|
+
if val.is_a? Array
|
58
|
+
val = Clashinator::ArrayResource.new(model, val)
|
59
|
+
# this other condition is for array based structures with no paging
|
60
|
+
# for instance member_list of Clan.clan_info 'member_list' attribute
|
61
|
+
elsif val.is_a?(Hash) && val.key?(:items) && val.key?(:paging)
|
62
|
+
val = Clashinator::ArrayResource.new(
|
63
|
+
model, val['items'], val['paging']
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
val
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.http_default_options(token)
|
71
|
+
{
|
72
|
+
headers: {
|
73
|
+
'Authorization' => "Bearer #{token}"
|
74
|
+
}
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.prepare_options(token, query_options = {})
|
79
|
+
# new hash to store camelcased attributes, to make it work
|
80
|
+
# with the official API
|
81
|
+
new_query_options = {}
|
82
|
+
query_options.each do |name, val|
|
83
|
+
name = to_camel_case(name.to_s)
|
84
|
+
val.gsub!('#', '%23') if val.class == String
|
85
|
+
new_query_options[name.to_sym] = val
|
86
|
+
end
|
87
|
+
|
88
|
+
# duplicate http_default_options to add new_query_options
|
89
|
+
http_default_options(token).dup.merge(query: new_query_options)
|
90
|
+
end
|
91
|
+
|
92
|
+
private_class_method :http_default_options
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the clan model
|
3
|
+
class Clan < Base
|
4
|
+
def initialize(attrs)
|
5
|
+
super(attrs)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.clan_info(token, clan_tag)
|
9
|
+
clan_tag.gsub!('#', '%23')
|
10
|
+
new_options = prepare_options(token)
|
11
|
+
response = get(
|
12
|
+
"/v1/clans/#{clan_tag}",
|
13
|
+
new_options
|
14
|
+
)
|
15
|
+
|
16
|
+
return new(response.parsed_response) if response.ok?
|
17
|
+
raise response['reason'] unless response.ok?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.search_clans(token, options)
|
21
|
+
new_options = prepare_options(token, options)
|
22
|
+
# TODO: options[:name] should be at least 3 chars long
|
23
|
+
response = get('/v1/clans', new_options)
|
24
|
+
|
25
|
+
if response.ok?
|
26
|
+
return Clashinator::ArrayResource.new(
|
27
|
+
Clashinator::Clan,
|
28
|
+
response.parsed_response['items'],
|
29
|
+
response.parsed_response['paging']
|
30
|
+
)
|
31
|
+
end
|
32
|
+
raise response['message'] unless response.ok?
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.list_clan_members(token, clan_tag, options = {})
|
36
|
+
new_options = prepare_options(token, options)
|
37
|
+
clan_tag.gsub!('#', '%23')
|
38
|
+
response = get("/v1/clans/#{clan_tag}/members", new_options)
|
39
|
+
|
40
|
+
if response.ok?
|
41
|
+
return Clashinator::ArrayResource.new(
|
42
|
+
Clashinator::Player, response.parsed_response['items'],
|
43
|
+
response.parsed_response['paging']
|
44
|
+
)
|
45
|
+
end
|
46
|
+
raise response['message'] unless response.ok?
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.clan_war_log(token, clan_tag, options = {})
|
50
|
+
# response.code will be 403 if clan war log is set to private
|
51
|
+
new_options = prepare_options(token, options)
|
52
|
+
clan_tag.gsub!('#', '%23')
|
53
|
+
response = get("/v1/clans/#{clan_tag}/warlog", new_options)
|
54
|
+
|
55
|
+
if response.ok?
|
56
|
+
return Clashinator::ArrayResource.new(
|
57
|
+
Clashinator::Warlog, response.parsed_response['items'],
|
58
|
+
response.parsed_response['paging']
|
59
|
+
)
|
60
|
+
end
|
61
|
+
raise response['reason'] unless response.ok?
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/clashinator/client.rb
CHANGED
@@ -1,89 +1,78 @@
|
|
1
1
|
module Clashinator
|
2
|
+
# Client class that acts as
|
3
|
+
# interface of http methods
|
4
|
+
# available for the client itself
|
2
5
|
class Client
|
3
|
-
CLASH_OF_CLANS_API = 'https://api.clashofclans.com'
|
4
|
-
ENDPOINTS = {
|
5
|
-
find_clan: '/v1/clans',
|
6
|
-
get_clan_info: '/v1/clans/{clan_tag}',
|
7
|
-
list_clan_members: '/v1/clans/{clan_tag}/members',
|
8
|
-
list_war_log: '/v1/clans/{clan_tag}/warlog',
|
9
|
-
list_locations: '/v1/locations',
|
10
|
-
get_location_info: '/v1/locations/{location_id}',
|
11
|
-
get_clan_ranking_for_location: '/v1/locations/{location_id}/rankings/clans',
|
12
|
-
get_player_ranking_for_location: '/v1/locations/{location_id}/rankings/players',
|
13
|
-
list_leagues: '/v1/leagues',
|
14
|
-
get_league: '/v1/leagues/{league_id}',
|
15
|
-
get_league_seasons: '/v1/leagues/{league_id}/seasons',
|
16
|
-
get_league_season_rankings: '/v1/leagues/{league_id}/seasons/{season_id}'
|
17
|
-
}
|
18
|
-
|
19
6
|
attr_reader :token
|
20
7
|
|
21
8
|
def initialize(token)
|
22
9
|
@token = token
|
23
10
|
end
|
24
11
|
|
25
|
-
|
26
|
-
|
12
|
+
# client class methods
|
13
|
+
|
14
|
+
def search_clans(options)
|
15
|
+
Clashinator::Clan.search_clans(@token, options)
|
27
16
|
end
|
28
17
|
|
29
|
-
def
|
30
|
-
|
18
|
+
def clan_info(tag)
|
19
|
+
Clashinator::Clan.clan_info(@token, tag)
|
20
|
+
end
|
21
|
+
|
22
|
+
def list_clan_members(tag, options = {})
|
23
|
+
Clashinator::Clan.list_clan_members(@token, tag, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def clan_war_log(tag, options = {})
|
27
|
+
Clashinator::Clan.clan_war_log(@token, tag, options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# location class methods
|
31
|
+
|
32
|
+
def list_locations(options = {})
|
33
|
+
Clashinator::Location.list_locations(@token, options)
|
31
34
|
end
|
32
35
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def location_info(location_id)
|
37
|
+
Clashinator::Location.location_info(@token, location_id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def location_clan_rankings(location_id, options = {})
|
41
|
+
Clashinator::Locaton.location_clan_rankings(
|
42
|
+
@token, location_id, options
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def location_player_rankings(player_tag, options = {})
|
47
|
+
Clashinator::Location.location_player_rankings(
|
48
|
+
@token, player_tag, options
|
38
49
|
)
|
39
|
-
if response.success?
|
40
|
-
JSON.parse(response.body.to_json)
|
41
|
-
else
|
42
|
-
raise Exceptions::ResponseError.new(response),
|
43
|
-
'Clash of clans API has returned the error.'
|
44
|
-
end
|
45
50
|
end
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
def
|
50
|
-
|
51
|
-
query_params = ''
|
52
|
-
if has_path_param(url)
|
53
|
-
params.each do |key, value|
|
54
|
-
url.gsub!("{#{key}}", CGI::escape(value.to_s))
|
55
|
-
end
|
56
|
-
url.gsub!(/\/{\w+}/, '')
|
57
|
-
else
|
58
|
-
query_params = params
|
59
|
-
end
|
60
|
-
{url: url, query_params: query_params}
|
52
|
+
# league class methods
|
53
|
+
|
54
|
+
def list_leagues(options = {})
|
55
|
+
Clashinator::League.list_leagues(@token, options)
|
61
56
|
end
|
62
57
|
|
63
|
-
def
|
64
|
-
|
58
|
+
def league_info(league_id)
|
59
|
+
Clashinator::League.league_info(@token, league_id)
|
65
60
|
end
|
66
61
|
|
67
|
-
def
|
68
|
-
|
69
|
-
!has_path_param.nil?
|
62
|
+
def league_seasons(league_id, options = {})
|
63
|
+
Clashinator::League.league_seasons(@token, league_id, options)
|
70
64
|
end
|
71
65
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
end
|
66
|
+
def league_season_rankings(league_id, season_id, options = {})
|
67
|
+
Clashinator::League.league_season_rankings(
|
68
|
+
@token, league_id, season_id, options
|
69
|
+
)
|
77
70
|
end
|
78
71
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
content_type: 'application/json',
|
84
|
-
authorization: "Bearer #{token}"
|
85
|
-
}
|
86
|
-
}
|
72
|
+
# player class methods
|
73
|
+
|
74
|
+
def player_info(tag)
|
75
|
+
Clashinator::Player.player_info(@token, tag)
|
87
76
|
end
|
88
77
|
end
|
89
78
|
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the league model
|
3
|
+
class League < Base
|
4
|
+
def initialize(attrs)
|
5
|
+
super(attrs)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.list_leagues(token, options = {})
|
9
|
+
new_options = prepare_options(token, options)
|
10
|
+
response = get('/v1/leagues', new_options)
|
11
|
+
|
12
|
+
if response.ok?
|
13
|
+
return Clashinator::ArrayResource.new(
|
14
|
+
Clashinator::League, response.parsed_response['items'],
|
15
|
+
response.parsed_response['paging']
|
16
|
+
)
|
17
|
+
end
|
18
|
+
raise response['message'] unless response.ok?
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.league_info(token, league_id)
|
22
|
+
new_options = prepare_options(token)
|
23
|
+
response = get("/v1/leagues/#{league_id}", new_options)
|
24
|
+
|
25
|
+
return new(response.parsed_response) if response.ok?
|
26
|
+
raise response['message'] unless response.ok?
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.league_seasons(token, league_id, options = {})
|
30
|
+
new_options = prepare_options(token, options)
|
31
|
+
response = get("/v1/leagues/#{league_id}/seasons", new_options)
|
32
|
+
|
33
|
+
if response.ok?
|
34
|
+
return Clashinator::ArrayResource.new(
|
35
|
+
Clashinator::Season, response.parsed_response['items'],
|
36
|
+
response.parsed_response['paging']
|
37
|
+
)
|
38
|
+
end
|
39
|
+
raise response['reason'] unless response.ok?
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.league_season_rankings(token, league_id, season_id, options = {})
|
43
|
+
# only available for legend_league
|
44
|
+
response = prepare_response_season_rankings(
|
45
|
+
league_id, season_id, token, options
|
46
|
+
)
|
47
|
+
if response.ok?
|
48
|
+
return Clashinator::ArrayResource.new(
|
49
|
+
Clashinator::PlayerRanking, response.parsed_response['items'],
|
50
|
+
response.parsed_response['paging']
|
51
|
+
)
|
52
|
+
end
|
53
|
+
raise response['reason'] unless response.ok?
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.prepare_response_season_rankings(league_id, season_id, token, options)
|
57
|
+
get(
|
58
|
+
"/v1/leagues/#{league_id}/seasons/#{season_id}",
|
59
|
+
prepare_options(token, options)
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
private_class_method :prepare_response_season_rankings
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the location model
|
3
|
+
class Location < Base
|
4
|
+
def initialize(attrs)
|
5
|
+
super(attrs)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.list_locations(token, options = {})
|
9
|
+
new_options = prepare_options(token, options)
|
10
|
+
response = get('/v1/locations', new_options)
|
11
|
+
|
12
|
+
if response.ok?
|
13
|
+
return Clashinator::ArrayResource.new(
|
14
|
+
Clashinator::Location, response.parsed_response['items'],
|
15
|
+
response.parsed_response['paging']
|
16
|
+
)
|
17
|
+
end
|
18
|
+
raise response['message'] unless response.ok?
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.location_info(token, location_id)
|
22
|
+
new_options = prepare_options(token)
|
23
|
+
response = get("/v1/locations/#{location_id}", new_options)
|
24
|
+
|
25
|
+
return new(response.parsed_response) if response.ok?
|
26
|
+
raise response['message'] unless response.ok?
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.location_clan_rankings(token, location_id, options = {})
|
30
|
+
new_options = prepare_options(token, options)
|
31
|
+
response = get("/v1/locations/#{location_id}/rankings/clans", new_options)
|
32
|
+
|
33
|
+
if response.ok?
|
34
|
+
return Clashinator::ArrayResource.new(
|
35
|
+
Clashinator::ClanRanking, response.parsed_response['items'],
|
36
|
+
response.parsed_response['paging']
|
37
|
+
)
|
38
|
+
end
|
39
|
+
raise response['reason'] unless response.ok?
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.location_player_rankings(token, location_id, options = {})
|
43
|
+
response = get(
|
44
|
+
"/v1/locations/#{location_id}/rankings/players",
|
45
|
+
prepare_options(token, options)
|
46
|
+
)
|
47
|
+
|
48
|
+
return Clashinator::ArrayResource.new(
|
49
|
+
Clashinator::PlayerRanking, response.parsed_response['items'],
|
50
|
+
response.parsed_response['paging']
|
51
|
+
) if response.ok?
|
52
|
+
raise response['reason'] unless response.ok?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Clashinator
|
2
|
+
# This class represents the player model
|
3
|
+
class Player < Base
|
4
|
+
def initialize(attrs)
|
5
|
+
super(attrs)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.player_info(token, player_tag)
|
9
|
+
player_tag.gsub!('#', '%23')
|
10
|
+
new_options = prepare_options(token)
|
11
|
+
response = get("/v1/players/#{player_tag}", new_options)
|
12
|
+
|
13
|
+
return new(response.parsed_response) if response.ok?
|
14
|
+
raise response['reason'] unless response.ok?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# module to convert camelcase to underscore
|
2
|
+
module Underscorable
|
3
|
+
def to_underscore(name)
|
4
|
+
modified_word = name.dup
|
5
|
+
modified_word.gsub!(/::/, '/')
|
6
|
+
modified_word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
7
|
+
modified_word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
8
|
+
modified_word.tr!('-', '_')
|
9
|
+
modified_word.downcase!
|
10
|
+
modified_word
|
11
|
+
end
|
12
|
+
end
|
data/lib/clashinator/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clashinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0
|
4
|
+
version: '1.0'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Leonardo Cabeza
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -39,33 +39,79 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: webmock
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
48
|
-
|
47
|
+
version: '2.1'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.1.0
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '2.1'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 2.1.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: vcr
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3.0'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 3.0.3
|
71
|
+
type: :development
|
49
72
|
prerelease: false
|
50
73
|
version_requirements: !ruby/object:Gem::Requirement
|
51
74
|
requirements:
|
52
75
|
- - "~>"
|
53
76
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
77
|
+
version: '3.0'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 3.0.3
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: minitest
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '5.9'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 5.9.1
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '5.9'
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 5.9.1
|
55
101
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
102
|
+
name: httparty
|
57
103
|
requirement: !ruby/object:Gem::Requirement
|
58
104
|
requirements:
|
59
105
|
- - "~>"
|
60
106
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
107
|
+
version: 0.14.0
|
62
108
|
type: :runtime
|
63
109
|
prerelease: false
|
64
110
|
version_requirements: !ruby/object:Gem::Requirement
|
65
111
|
requirements:
|
66
112
|
- - "~>"
|
67
113
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
114
|
+
version: 0.14.0
|
69
115
|
description:
|
70
116
|
email:
|
71
117
|
- info@leonardocabeza.com
|
@@ -76,7 +122,6 @@ files:
|
|
76
122
|
- ".gitignore"
|
77
123
|
- CODE_OF_CONDUCT.md
|
78
124
|
- Gemfile
|
79
|
-
- Gemfile.lock
|
80
125
|
- LICENSE
|
81
126
|
- LICENSE.txt
|
82
127
|
- README.md
|
@@ -84,13 +129,29 @@ files:
|
|
84
129
|
- bin/console
|
85
130
|
- bin/setup
|
86
131
|
- clashinator.gemspec
|
132
|
+
- config/secrets.sample.yml
|
87
133
|
- lib/clashinator.rb
|
134
|
+
- lib/clashinator/achievement.rb
|
135
|
+
- lib/clashinator/army.rb
|
136
|
+
- lib/clashinator/array_resource.rb
|
137
|
+
- lib/clashinator/badge_url.rb
|
138
|
+
- lib/clashinator/base.rb
|
139
|
+
- lib/clashinator/clan.rb
|
140
|
+
- lib/clashinator/clan_ranking.rb
|
88
141
|
- lib/clashinator/client.rb
|
89
|
-
- lib/clashinator/
|
90
|
-
- lib/clashinator/
|
91
|
-
- lib/clashinator/
|
142
|
+
- lib/clashinator/hero.rb
|
143
|
+
- lib/clashinator/league.rb
|
144
|
+
- lib/clashinator/location.rb
|
145
|
+
- lib/clashinator/player.rb
|
146
|
+
- lib/clashinator/player_ranking.rb
|
147
|
+
- lib/clashinator/season.rb
|
148
|
+
- lib/clashinator/spell.rb
|
149
|
+
- lib/clashinator/troop.rb
|
150
|
+
- lib/clashinator/util/camelcase.rb
|
151
|
+
- lib/clashinator/util/underscore.rb
|
92
152
|
- lib/clashinator/version.rb
|
93
|
-
|
153
|
+
- lib/clashinator/warlog.rb
|
154
|
+
homepage: https://github.com/leocabeza/clash-api
|
94
155
|
licenses:
|
95
156
|
- MIT
|
96
157
|
metadata:
|
data/Gemfile.lock
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
clashinator (0.1.2)
|
5
|
-
faraday (~> 0.9.2)
|
6
|
-
faraday_middleware (~> 0.10)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: https://rubygems.org/
|
10
|
-
specs:
|
11
|
-
faraday (0.9.2)
|
12
|
-
multipart-post (>= 1.2, < 3)
|
13
|
-
faraday_middleware (0.10.0)
|
14
|
-
faraday (>= 0.7.4, < 0.10)
|
15
|
-
multipart-post (2.0.0)
|
16
|
-
rake (10.5.0)
|
17
|
-
|
18
|
-
PLATFORMS
|
19
|
-
ruby
|
20
|
-
|
21
|
-
DEPENDENCIES
|
22
|
-
bundler (~> 1.11)
|
23
|
-
clashinator!
|
24
|
-
rake (~> 10.0)
|
25
|
-
|
26
|
-
BUNDLED WITH
|
27
|
-
1.11.2
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Clashinator
|
2
|
-
module Exceptions
|
3
|
-
class ResponseError < Base
|
4
|
-
attr_reader :response
|
5
|
-
|
6
|
-
def initialize(response)
|
7
|
-
@response = response
|
8
|
-
end
|
9
|
-
|
10
|
-
def to_s
|
11
|
-
super +
|
12
|
-
format(' (%s)', data.map { |k, v| %(#{k}: "#{v}") }.join(', '))
|
13
|
-
end
|
14
|
-
|
15
|
-
def error_code
|
16
|
-
data[:error_code] || data['error_code']
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
def data
|
22
|
-
@data ||= begin
|
23
|
-
JSON.parse(response.body)
|
24
|
-
rescue JSON::ParserError
|
25
|
-
{ error_code: response.status, reason: response.body.reason }
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|