lol_data_fetcher 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d5d6c8fcc2a14a1aa67e0271e7c837d31445e93f1791c9e471d587339e4f2bec
4
+ data.tar.gz: 45e513368cc422fd4cf82080d3f61af7b3ef4cd65fd8c28f50f00ad9e434b9d1
5
+ SHA512:
6
+ metadata.gz: 25b31cb500270ae2d41c8423a13aa59493d11208083dd4c81df9479c61a2f894f0236094cdfcc98946d2f609cbc896f07fd0d8aa48498735f63a6d68524a057b
7
+ data.tar.gz: 66cc593f2038aaf3673d8c06ef93625249703f74c17105595bcc47a5ed7e1d09f18ba88048917a67fd031b260ce695eeb3ecb92388ff464fc013967a4e9803de
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ EnforcedStyle: double_quotes
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ EnforcedStyle: double_quotes
data/CHANGELOG.md ADDED
@@ -0,0 +1,32 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-11-20
9
+
10
+ ### Added
11
+ - Initial release of lol_data_fetcher gem
12
+ - Client class for interacting with League of Legends Data Dragon API
13
+ - Champions resource for fetching champion data and skills
14
+ - Items resource for fetching and searching items
15
+ - Skins resource for fetching champion skins with image URLs
16
+ - Versions resource for managing Data Dragon versions
17
+ - Configuration system for setting default language and version
18
+ - Thor-based CLI with commands for champions, items, skins, and versions
19
+ - Comprehensive RSpec test suite with VCR for HTTP recording
20
+ - Support for multiple languages (en_US, ko_KR, ja_JP, etc.)
21
+ - Error handling with custom exception classes
22
+ - Detailed README with usage examples
23
+ - SimpleCov integration for code coverage tracking
24
+
25
+ ### Features
26
+ - Fetch all champions with detailed information
27
+ - Get champion skills and abilities
28
+ - Search items by name
29
+ - Retrieve champion skins with splash and loading screen URLs
30
+ - Support for all Data Dragon versions
31
+ - Command-line interface for quick data access
32
+ - 87.88% code coverage with automated tests
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 Mark Chavez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,344 @@
1
+ # LolDataFetcher
2
+
3
+ A Ruby client for the League of Legends Data Dragon API. Fetch champions, items, skins, and other static game data with ease.
4
+
5
+ ## Features
6
+
7
+ - Fetch all champions with detailed information including skills/spells
8
+ - Get all items and search by name
9
+ - Retrieve champion skins with image URLs
10
+ - Support for multiple game versions and languages
11
+ - Command-line interface (CLI) for quick data access
12
+ - Comprehensive test coverage with RSpec
13
+ - VCR cassettes for fast, repeatable tests
14
+
15
+ ## Installation
16
+
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'lol_data_fetcher'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ ```bash
26
+ bundle install
27
+ ```
28
+
29
+ Or install it yourself as:
30
+
31
+ ```bash
32
+ gem install lol_data_fetcher
33
+ ```
34
+
35
+ ## Usage
36
+
37
+ ### Ruby API
38
+
39
+ #### Basic Usage
40
+
41
+ ```ruby
42
+ require 'lol_data_fetcher'
43
+
44
+ # Create a client (automatically fetches the latest version)
45
+ client = LolDataFetcher::Client.new
46
+
47
+ # Or specify a version and language
48
+ client = LolDataFetcher::Client.new(
49
+ version: "15.23.1",
50
+ language: "ko_KR"
51
+ )
52
+ ```
53
+
54
+ #### Fetching Champions
55
+
56
+ ```ruby
57
+ # Get all champions (overview)
58
+ champions = client.champions.all
59
+ champions["data"].each do |key, champion|
60
+ puts "#{champion['name']}: #{champion['title']}"
61
+ end
62
+
63
+ # Get detailed champion data including skills
64
+ ahri = client.champions.find("Ahri")
65
+ ahri_data = ahri["data"]["Ahri"]
66
+
67
+ puts ahri_data["name"] # => "Ahri"
68
+ puts ahri_data["title"] # => "the Nine-Tailed Fox"
69
+
70
+ # Access champion spells/skills
71
+ ahri_data["spells"].each do |spell|
72
+ puts "#{spell['name']}: #{spell['description']}"
73
+ end
74
+
75
+ # List all champion names
76
+ names = client.champions.list_names
77
+ # => ["Aatrox", "Ahri", "Akali", ...]
78
+
79
+ # Find champion by ID
80
+ champion = client.champions.find_by_id("103") # Ahri
81
+ ```
82
+
83
+ #### Fetching Items
84
+
85
+ ```ruby
86
+ # Get all items
87
+ items = client.items.all
88
+ items["data"].each do |id, item|
89
+ puts "#{item['name']} - #{item['gold']['total']}g"
90
+ end
91
+
92
+ # Find specific item by ID
93
+ boots = client.items.find("1001")
94
+ puts boots["name"] # => "Boots"
95
+
96
+ # Search items by name
97
+ swords = client.items.search("sword")
98
+ swords.each do |item|
99
+ puts item["name"]
100
+ end
101
+
102
+ # List all item IDs
103
+ ids = client.items.list_ids
104
+ ```
105
+
106
+ #### Fetching Skins
107
+
108
+ ```ruby
109
+ # Get all skins for a specific champion
110
+ skins = client.skins.for_champion("Ahri")
111
+ skins.each do |skin|
112
+ puts skin["name"]
113
+ puts "Splash: #{skin['splash_url']}"
114
+ puts "Loading: #{skin['loading_url']}"
115
+ end
116
+ ```
117
+
118
+ #### Version Management
119
+
120
+ ```ruby
121
+ # Get all available versions
122
+ versions = client.versions.all
123
+ # => ["15.23.1", "15.23.0", ...]
124
+
125
+ # Get the latest version
126
+ latest = client.versions.latest
127
+ # => "15.23.1"
128
+
129
+ # Check if a version exists
130
+ client.versions.exists?("15.23.1") # => true
131
+ ```
132
+
133
+ #### Global Configuration
134
+
135
+ ```ruby
136
+ # Configure default settings
137
+ LolDataFetcher.configure do |config|
138
+ config.default_language = "ja_JP"
139
+ config.default_version = "15.23.1"
140
+ config.timeout = 15
141
+ end
142
+
143
+ # Use the configured client
144
+ client = LolDataFetcher.client
145
+
146
+ # Reset configuration
147
+ LolDataFetcher.reset!
148
+ ```
149
+
150
+ ### Command Line Interface
151
+
152
+ The gem includes a powerful CLI for quick data access.
153
+
154
+ #### View Help
155
+
156
+ ```bash
157
+ lol_data_fetcher help
158
+ ```
159
+
160
+ #### Get Version Information
161
+
162
+ ```bash
163
+ # Gem version
164
+ lol_data_fetcher version
165
+
166
+ # Latest Data Dragon version
167
+ lol_data_fetcher latest_version
168
+ ```
169
+
170
+ #### List Champions
171
+
172
+ ```bash
173
+ # List all champions
174
+ lol_data_fetcher champions
175
+
176
+ # Limit results
177
+ lol_data_fetcher champions --limit 10
178
+
179
+ # Use specific version and language
180
+ lol_data_fetcher champions -v 15.23.1 -l ko_KR
181
+ ```
182
+
183
+ #### Get Champion Details
184
+
185
+ ```bash
186
+ # Get champion info with skills
187
+ lol_data_fetcher champion Ahri
188
+
189
+ # Without skills
190
+ lol_data_fetcher champion Ahri --no-skills
191
+
192
+ # With skins
193
+ lol_data_fetcher champion Ahri --skins
194
+
195
+ # Use specific version
196
+ lol_data_fetcher champion Ahri -v 15.23.1
197
+ ```
198
+
199
+ #### List Items
200
+
201
+ ```bash
202
+ # List all items
203
+ lol_data_fetcher items
204
+
205
+ # Search items
206
+ lol_data_fetcher items --search "sword"
207
+
208
+ # Limit results
209
+ lol_data_fetcher items --limit 20
210
+
211
+ # Use specific version
212
+ lol_data_fetcher items -v 15.23.1 -l es_ES
213
+ ```
214
+
215
+ #### Get Champion Skins
216
+
217
+ ```bash
218
+ # List skins for a champion
219
+ lol_data_fetcher skins Ahri
220
+
221
+ # Show image URLs
222
+ lol_data_fetcher skins Ahri --urls
223
+ ```
224
+
225
+ ### Available Languages
226
+
227
+ The Data Dragon API supports multiple languages:
228
+ - `en_US` - English (United States)
229
+ - `ko_KR` - Korean
230
+ - `ja_JP` - Japanese
231
+ - `es_ES` - Spanish (Spain)
232
+ - `es_MX` - Spanish (Mexico)
233
+ - `fr_FR` - French
234
+ - `de_DE` - German
235
+ - `it_IT` - Italian
236
+ - `pl_PL` - Polish
237
+ - `pt_BR` - Portuguese (Brazil)
238
+ - `ru_RU` - Russian
239
+ - `tr_TR` - Turkish
240
+ - `zh_CN` - Chinese (China)
241
+ - `zh_TW` - Chinese (Taiwan)
242
+
243
+ ## Development
244
+
245
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
246
+
247
+ 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 the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
248
+
249
+ ## API Reference
250
+
251
+ ### Client
252
+
253
+ The main client class for interacting with the Data Dragon API.
254
+
255
+ ```ruby
256
+ client = LolDataFetcher::Client.new(version: "15.23.1", language: "en_US")
257
+ ```
258
+
259
+ **Methods:**
260
+ - `champions` - Access the Champions resource
261
+ - `items` - Access the Items resource
262
+ - `skins` - Access the Skins resource
263
+ - `versions` - Access the Versions resource
264
+
265
+ ### Champions Resource
266
+
267
+ ```ruby
268
+ client.champions.all # Get all champions (overview)
269
+ client.champions.find("Ahri") # Get detailed champion data
270
+ client.champions.list_names # List all champion names
271
+ client.champions.find_by_id("103") # Find champion by ID
272
+ ```
273
+
274
+ ### Items Resource
275
+
276
+ ```ruby
277
+ client.items.all # Get all items
278
+ client.items.find("1001") # Find item by ID
279
+ client.items.list_ids # List all item IDs
280
+ client.items.search("sword") # Search items by name
281
+ ```
282
+
283
+ ### Skins Resource
284
+
285
+ ```ruby
286
+ client.skins.for_champion("Ahri") # Get skins for a champion
287
+ ```
288
+
289
+ ### Versions Resource
290
+
291
+ ```ruby
292
+ client.versions.all # Get all available versions
293
+ client.versions.latest # Get latest version
294
+ client.versions.exists?("15.23.1") # Check if version exists
295
+ ```
296
+
297
+ ## Error Handling
298
+
299
+ The gem defines several error classes:
300
+
301
+ - `LolDataFetcher::Error` - Base error class
302
+ - `LolDataFetcher::ApiError` - API request failures
303
+ - `LolDataFetcher::NotFoundError` - Resource not found
304
+ - `LolDataFetcher::ConfigurationError` - Configuration issues
305
+
306
+ ```ruby
307
+ begin
308
+ client.champions.find("NonExistentChampion")
309
+ rescue LolDataFetcher::NotFoundError => e
310
+ puts "Champion not found: #{e.message}"
311
+ rescue LolDataFetcher::ApiError => e
312
+ puts "API error: #{e.message}"
313
+ end
314
+ ```
315
+
316
+ ## Testing
317
+
318
+ The gem uses RSpec for testing with VCR for recording HTTP interactions:
319
+
320
+ ```bash
321
+ # Run all tests
322
+ bundle exec rspec
323
+
324
+ # Run specific test file
325
+ bundle exec rspec spec/lol_data_fetcher/client_spec.rb
326
+
327
+ # Run with coverage report
328
+ bundle exec rspec
329
+ # Coverage report will be in coverage/index.html
330
+ ```
331
+
332
+ ## Contributing
333
+
334
+ Bug reports and pull requests are welcome on GitHub at https://github.com/markchavez/lol_data_fetcher.
335
+
336
+ 1. Fork the repository
337
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
338
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
339
+ 4. Push to the branch (`git push origin my-new-feature`)
340
+ 5. Create a new Pull Request
341
+
342
+ ## License
343
+
344
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "lol_data_fetcher"
6
+ require "lol_data_fetcher/cli"
7
+
8
+ LolDataFetcher::CLI.start(ARGV)
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module LolDataFetcher
6
+ # Command-line interface for LolDataFetcher
7
+ class CLI < Thor
8
+ def self.exit_on_failure?
9
+ true
10
+ end
11
+
12
+ desc "version", "Display the gem version"
13
+ def version
14
+ puts "lol_data_fetcher version #{LolDataFetcher::VERSION}"
15
+ end
16
+
17
+ desc "latest_version", "Show the latest game version"
18
+ def latest_version
19
+ client = LolDataFetcher::Client.new
20
+ puts "Latest Data Dragon version: #{client.version}"
21
+ rescue LolDataFetcher::Error => e
22
+ error("Failed to fetch latest version: #{e.message}")
23
+ end
24
+
25
+ desc "champions", "List all champions"
26
+ method_option :version, aliases: "-v", desc: "Game version to use"
27
+ method_option :language, aliases: "-l", default: "en_US", desc: "Language code (e.g., en_US, ko_KR)"
28
+ method_option :limit, aliases: "-n", type: :numeric, desc: "Limit number of results"
29
+ def champions
30
+ client = create_client
31
+ data = client.champions.all
32
+
33
+ champions = data["data"].values
34
+ champions = champions.first(options[:limit]) if options[:limit]
35
+
36
+ champions.each do |champion|
37
+ puts format_champion(champion)
38
+ end
39
+
40
+ puts "\nTotal: #{champions.length} champions"
41
+ rescue LolDataFetcher::Error => e
42
+ error("Failed to fetch champions: #{e.message}")
43
+ end
44
+
45
+ desc "champion NAME", "Get details for a specific champion"
46
+ method_option :version, aliases: "-v", desc: "Game version to use"
47
+ method_option :language, aliases: "-l", default: "en_US", desc: "Language code"
48
+ method_option :skills, aliases: "-s", type: :boolean, default: true, desc: "Show champion skills"
49
+ method_option :skins, type: :boolean, default: false, desc: "Show champion skins"
50
+ def champion(name)
51
+ client = create_client
52
+ data = client.champions.find(name)
53
+
54
+ champion_data = data.dig("data", name)
55
+ unless champion_data
56
+ error("Champion '#{name}' not found")
57
+ return
58
+ end
59
+
60
+ puts "\n#{champion_data['name']} - #{champion_data['title']}"
61
+ puts "=" * 50
62
+ puts "\nLore:"
63
+ puts word_wrap(champion_data["lore"])
64
+
65
+ if options[:skills] && champion_data["spells"]
66
+ puts "\n#{champion_data['name']}'s Skills:"
67
+ puts "-" * 50
68
+ champion_data["spells"].each_with_index do |spell, idx|
69
+ puts "\n#{idx + 1}. #{spell['name']}"
70
+ puts " #{word_wrap(strip_html(spell['description']), 3)}"
71
+ end
72
+ end
73
+
74
+ if options[:skins]
75
+ puts "\n#{champion_data['name']}'s Skins:"
76
+ puts "-" * 50
77
+ skins = client.skins.for_champion(name)
78
+ skins.each do |skin|
79
+ puts " - #{skin['name']}"
80
+ end
81
+ end
82
+ rescue LolDataFetcher::NotFoundError => e
83
+ error("Champion not found: #{e.message}")
84
+ rescue LolDataFetcher::Error => e
85
+ error("Failed to fetch champion: #{e.message}")
86
+ end
87
+
88
+ desc "items", "List all items"
89
+ method_option :version, aliases: "-v", desc: "Game version to use"
90
+ method_option :language, aliases: "-l", default: "en_US", desc: "Language code"
91
+ method_option :search, aliases: "-s", desc: "Search items by name"
92
+ method_option :limit, aliases: "-n", type: :numeric, desc: "Limit number of results"
93
+ def items
94
+ client = create_client
95
+
96
+ if options[:search]
97
+ items_list = client.items.search(options[:search])
98
+ else
99
+ data = client.items.all
100
+ items_list = data["data"].values
101
+ end
102
+
103
+ items_list = items_list.first(options[:limit]) if options[:limit]
104
+
105
+ items_list.each do |item|
106
+ gold = item.dig("gold", "total") || 0
107
+ puts "#{item['name']} - #{gold}g"
108
+ end
109
+
110
+ puts "\nTotal: #{items_list.length} items"
111
+ rescue LolDataFetcher::Error => e
112
+ error("Failed to fetch items: #{e.message}")
113
+ end
114
+
115
+ desc "skins CHAMPION", "List all skins for a champion"
116
+ method_option :version, aliases: "-v", desc: "Game version to use"
117
+ method_option :language, aliases: "-l", default: "en_US", desc: "Language code"
118
+ method_option :urls, aliases: "-u", type: :boolean, default: false, desc: "Show image URLs"
119
+ def skins(champion_name)
120
+ client = create_client
121
+ skins = client.skins.for_champion(champion_name)
122
+
123
+ puts "\n#{champion_name}'s Skins:"
124
+ puts "=" * 50
125
+
126
+ skins.each do |skin|
127
+ puts "\n#{skin['name']}"
128
+ if options[:urls]
129
+ puts " Splash: #{skin['splash_url']}"
130
+ puts " Loading: #{skin['loading_url']}"
131
+ end
132
+ end
133
+
134
+ puts "\nTotal: #{skins.length} skins"
135
+ rescue LolDataFetcher::NotFoundError => e
136
+ error("Champion not found: #{e.message}")
137
+ rescue LolDataFetcher::Error => e
138
+ error("Failed to fetch skins: #{e.message}")
139
+ end
140
+
141
+ private
142
+
143
+ def create_client
144
+ LolDataFetcher::Client.new(
145
+ version: options[:version],
146
+ language: options[:language]
147
+ )
148
+ end
149
+
150
+ def format_champion(champion)
151
+ "#{champion['name'].ljust(20)} - #{champion['title']}"
152
+ end
153
+
154
+ def strip_html(text)
155
+ text.gsub(/<[^>]*>/, "")
156
+ end
157
+
158
+ def word_wrap(text, indent = 0)
159
+ return "" unless text
160
+
161
+ prefix = " " * indent
162
+ text.gsub(/(.{1,#{78 - indent}})(\s+|$)/, "#{prefix}\\1\n").strip
163
+ end
164
+
165
+ def error(message)
166
+ warn "\nError: #{message}"
167
+ exit 1
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require "faraday/retry"
5
+
6
+ module LolDataFetcher
7
+ # Main client class for interacting with the Data Dragon API
8
+ class Client
9
+ BASE_URL = "https://ddragon.leagueoflegends.com"
10
+
11
+ attr_reader :version, :language
12
+
13
+ # Initialize a new client
14
+ # @param version [String, nil] Game version to use (nil = fetch latest)
15
+ # @param language [String] Language code (default: "en_US")
16
+ def initialize(version: nil, language: nil)
17
+ @language = language || LolDataFetcher.configuration.default_language
18
+ @version = version || LolDataFetcher.configuration.default_version || fetch_latest_version
19
+ end
20
+
21
+ # Access the champions resource
22
+ # @return [LolDataFetcher::Resources::Champions]
23
+ def champions
24
+ @champions ||= Resources::Champions.new(self)
25
+ end
26
+
27
+ # Access the items resource
28
+ # @return [LolDataFetcher::Resources::Items]
29
+ def items
30
+ @items ||= Resources::Items.new(self)
31
+ end
32
+
33
+ # Access the skins resource
34
+ # @return [LolDataFetcher::Resources::Skins]
35
+ def skins
36
+ @skins ||= Resources::Skins.new(self)
37
+ end
38
+
39
+ # Access the versions resource
40
+ # @return [LolDataFetcher::Resources::Versions]
41
+ def versions
42
+ @versions ||= Resources::Versions.new(self)
43
+ end
44
+
45
+ # Returns the Faraday connection object
46
+ # @return [Faraday::Connection]
47
+ def connection
48
+ @connection ||= Faraday.new(url: BASE_URL) do |faraday|
49
+ faraday.request :retry, max: 3, interval: 0.5, backoff_factor: 2
50
+ faraday.response :json, content_type: /\bjson$/
51
+ faraday.response :raise_error
52
+ faraday.options.timeout = LolDataFetcher.configuration.timeout
53
+ faraday.adapter Faraday.default_adapter
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def fetch_latest_version
60
+ versions.latest
61
+ rescue StandardError => e
62
+ raise ConfigurationError, "Failed to fetch latest version: #{e.message}"
63
+ end
64
+ end
65
+ end
66
+
67
+ # Require resources after client is defined
68
+ require_relative "resources/base"
69
+ require_relative "resources/versions"
70
+ require_relative "resources/champions"
71
+ require_relative "resources/items"
72
+ require_relative "resources/skins"
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ # Configuration class for global settings
5
+ class Configuration
6
+ attr_accessor :default_version, :default_language, :cache_enabled, :cache_ttl, :timeout
7
+
8
+ def initialize
9
+ @default_version = nil # nil = fetch latest
10
+ @default_language = "en_US"
11
+ @cache_enabled = false
12
+ @cache_ttl = 3600 # 1 hour in seconds
13
+ @timeout = 10 # seconds
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ # Base error class for all LolDataFetcher errors
5
+ class Error < StandardError; end
6
+
7
+ # Raised when an API request fails
8
+ class ApiError < Error; end
9
+
10
+ # Raised when a requested resource is not found
11
+ class NotFoundError < ApiError; end
12
+
13
+ # Raised when rate limit is exceeded
14
+ class RateLimitError < ApiError; end
15
+
16
+ # Raised when there's a configuration issue
17
+ class ConfigurationError < Error; end
18
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ module Resources
5
+ # Base class for all resource classes
6
+ class Base
7
+ attr_reader :client
8
+
9
+ # Initialize a new resource
10
+ # @param client [LolDataFetcher::Client] The client instance
11
+ def initialize(client)
12
+ @client = client
13
+ end
14
+
15
+ private
16
+
17
+ # Make a GET request to the API
18
+ # @param path [String] The API path
19
+ # @param params [Hash] Query parameters
20
+ # @return [Hash] Parsed JSON response
21
+ # @raise [LolDataFetcher::ApiError] If the request fails
22
+ def get(path, params = {})
23
+ response = client.connection.get(path, params)
24
+ response.body
25
+ rescue Faraday::ResourceNotFound => e
26
+ raise NotFoundError, "Resource not found: #{path}"
27
+ rescue Faraday::Error => e
28
+ raise ApiError, "API request failed: #{e.message}"
29
+ end
30
+
31
+ # Build a CDN path for data resources
32
+ # @param resource [String] The resource name (e.g., "champion", "item")
33
+ # @return [String] The full CDN path
34
+ def cdn_path(resource)
35
+ "/cdn/#{client.version}/data/#{client.language}/#{resource}.json"
36
+ end
37
+
38
+ # Build a CDN path for image resources
39
+ # @param type [String] Image type (e.g., "champion/splash")
40
+ # @param filename [String] The image filename
41
+ # @return [String] The full CDN image path
42
+ def cdn_image_path(type, filename)
43
+ "/cdn/img/#{type}/#{filename}"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ module Resources
5
+ # Resource for fetching champion data
6
+ class Champions < Base
7
+ # Fetch all champions (overview data)
8
+ # @return [Hash] Hash containing all champions data
9
+ def all
10
+ get(cdn_path("champion"))
11
+ end
12
+
13
+ # Fetch detailed data for a specific champion including skills
14
+ # @param name [String] Champion name (e.g., "Ahri", "MasterYi")
15
+ # @return [Hash] Detailed champion data including spells/skills
16
+ def find(name)
17
+ get(cdn_path("champion/#{name}"))
18
+ end
19
+
20
+ # List all champion names
21
+ # @return [Array<String>] Array of champion names
22
+ def list_names
23
+ all.dig("data")&.keys || []
24
+ end
25
+
26
+ # Get champion by ID
27
+ # @param id [String, Integer] Champion ID
28
+ # @return [Hash, nil] Champion data or nil if not found
29
+ def find_by_id(id)
30
+ all.dig("data")&.find { |_key, champ| champ["key"] == id.to_s }&.last
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ module Resources
5
+ # Resource for fetching item data
6
+ class Items < Base
7
+ # Fetch all items
8
+ # @return [Hash] Hash containing all items data
9
+ def all
10
+ get(cdn_path("item"))
11
+ end
12
+
13
+ # Find a specific item by ID
14
+ # @param id [String, Integer] Item ID
15
+ # @return [Hash, nil] Item data or nil if not found
16
+ def find(id)
17
+ all.dig("data", id.to_s)
18
+ end
19
+
20
+ # List all item IDs
21
+ # @return [Array<String>] Array of item IDs
22
+ def list_ids
23
+ all.dig("data")&.keys || []
24
+ end
25
+
26
+ # Search items by name
27
+ # @param query [String] Search query
28
+ # @return [Array<Hash>] Array of matching items
29
+ def search(query)
30
+ items = all.dig("data") || {}
31
+ items.select { |_id, item| item["name"]&.downcase&.include?(query.downcase) }.values
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ module Resources
5
+ # Resource for fetching champion skin data
6
+ class Skins < Base
7
+ # Fetch skins for a specific champion
8
+ # @param champion_name [String] Champion name (e.g., "Ahri")
9
+ # @return [Array<Hash>] Array of skin data with image URLs
10
+ def for_champion(champion_name)
11
+ champion_data = get(cdn_path("champion/#{champion_name}"))
12
+ skins = champion_data.dig("data", champion_name, "skins") || []
13
+
14
+ skins.map do |skin|
15
+ {
16
+ "id" => skin["id"],
17
+ "num" => skin["num"],
18
+ "name" => skin["name"],
19
+ "splash_url" => splash_url(champion_name, skin["num"]),
20
+ "loading_url" => loading_url(champion_name, skin["num"]),
21
+ "chromas" => skin["chromas"] || false
22
+ }
23
+ end
24
+ end
25
+
26
+ # Get all skins across all champions
27
+ # @return [Hash] Hash of champion names to their skins
28
+ def all
29
+ champions_data = client.champions.all
30
+ skins = {}
31
+
32
+ champions_data.dig("data")&.each do |name, _champion|
33
+ skins[name] = for_champion(name)
34
+ rescue NotFoundError
35
+ # Skip champions without detailed data
36
+ next
37
+ end
38
+
39
+ skins
40
+ end
41
+
42
+ private
43
+
44
+ # Build splash art URL for a skin
45
+ # @param champion_name [String] Champion name
46
+ # @param skin_num [Integer] Skin number
47
+ # @return [String] Full URL to splash art
48
+ def splash_url(champion_name, skin_num)
49
+ "#{Client::BASE_URL}#{cdn_image_path('champion/splash', "#{champion_name}_#{skin_num}.jpg")}"
50
+ end
51
+
52
+ # Build loading screen URL for a skin
53
+ # @param champion_name [String] Champion name
54
+ # @param skin_num [Integer] Skin number
55
+ # @return [String] Full URL to loading screen
56
+ def loading_url(champion_name, skin_num)
57
+ "#{Client::BASE_URL}#{cdn_image_path('champion/loading', "#{champion_name}_#{skin_num}.jpg")}"
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ module Resources
5
+ # Resource for fetching game version information
6
+ class Versions < Base
7
+ # Fetch all available versions
8
+ # @return [Array<String>] List of version strings
9
+ def all
10
+ get("/api/versions.json")
11
+ end
12
+
13
+ # Fetch the latest version
14
+ # @return [String] Latest version string
15
+ def latest
16
+ all.first
17
+ end
18
+
19
+ # Check if a version exists
20
+ # @param version [String] Version to check
21
+ # @return [Boolean] True if version exists
22
+ def exists?(version)
23
+ all.include?(version)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module LolDataFetcher
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lol_data_fetcher/version"
4
+ require_relative "lol_data_fetcher/errors"
5
+ require_relative "lol_data_fetcher/configuration"
6
+
7
+ module LolDataFetcher
8
+ class << self
9
+ attr_writer :configuration
10
+
11
+ # Returns the global configuration object
12
+ # @return [LolDataFetcher::Configuration]
13
+ def configuration
14
+ @configuration ||= Configuration.new
15
+ end
16
+
17
+ # Yields the configuration object for setup
18
+ # @yield [LolDataFetcher::Configuration]
19
+ def configure
20
+ yield(configuration)
21
+ end
22
+
23
+ # Returns a new client instance
24
+ # @return [LolDataFetcher::Client]
25
+ def client
26
+ @client ||= Client.new
27
+ end
28
+
29
+ # Resets the configuration and client to defaults
30
+ def reset!
31
+ @configuration = Configuration.new
32
+ @client = nil
33
+ end
34
+ end
35
+ end
36
+
37
+ # Require client and resources after module is defined
38
+ require_relative "lol_data_fetcher/client"
@@ -0,0 +1,4 @@
1
+ module LolDataFetcher
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,207 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lol_data_fetcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark Chavez
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-11-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday-retry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.50'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.50'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.20'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.20'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.22'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.22'
125
+ - !ruby/object:Gem::Dependency
126
+ name: vcr
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '6.2'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '6.2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: webmock
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '3.19'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '3.19'
153
+ description: Fetch champions, items, skins, and other static data from League of Legends
154
+ Data Dragon API
155
+ email:
156
+ - mjfchavez@gmail.com
157
+ executables:
158
+ - lol_data_fetcher
159
+ extensions: []
160
+ extra_rdoc_files: []
161
+ files:
162
+ - ".rspec"
163
+ - ".rubocop.yml"
164
+ - CHANGELOG.md
165
+ - LICENSE.txt
166
+ - README.md
167
+ - Rakefile
168
+ - exe/lol_data_fetcher
169
+ - lib/lol_data_fetcher.rb
170
+ - lib/lol_data_fetcher/cli.rb
171
+ - lib/lol_data_fetcher/client.rb
172
+ - lib/lol_data_fetcher/configuration.rb
173
+ - lib/lol_data_fetcher/errors.rb
174
+ - lib/lol_data_fetcher/resources/base.rb
175
+ - lib/lol_data_fetcher/resources/champions.rb
176
+ - lib/lol_data_fetcher/resources/items.rb
177
+ - lib/lol_data_fetcher/resources/skins.rb
178
+ - lib/lol_data_fetcher/resources/versions.rb
179
+ - lib/lol_data_fetcher/version.rb
180
+ - sig/lol_data_fetcher.rbs
181
+ homepage: https://github.com/markchavez/lol_data_fetcher
182
+ licenses:
183
+ - MIT
184
+ metadata:
185
+ homepage_uri: https://github.com/markchavez/lol_data_fetcher
186
+ source_code_uri: https://github.com/markchavez/lol_data_fetcher
187
+ changelog_uri: https://github.com/markchavez/lol_data_fetcher/blob/main/CHANGELOG.md
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: 3.0.0
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubygems_version: 3.4.10
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: A Ruby client for League of Legends Data Dragon API
207
+ test_files: []