fotmob 0.0.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5caec733f122382ab9f85603b76e3bbe504b30441006fd45cffda22fbe3ef7a
4
- data.tar.gz: 03b13331563a2a684bae0f24c332969b83a6b2abbce004777747758fca0dcd59
3
+ metadata.gz: 2db5d9b53f38dd3532d6db31d0442b64193ee9df642f0e27e5cafca07e7ca5e7
4
+ data.tar.gz: ec6df784201636a0f4e5cb2585e022fb10ccad33e5de8dc8ba3311f6d0ef3f7d
5
5
  SHA512:
6
- metadata.gz: a4568898b296b09d8984c40165568ea18cdbe0f60f54a0e4d5b1d01db6291f8962785128b24f40cc76553529b17a58a50ebf45e86aad7663cdcce6a827f6ab66
7
- data.tar.gz: 4f6e2475ae2e1c029990de8d332b4eec869367adace09e315238452fee8427a81781eadc4a21d2513b6212807b44ebdb04753785c95a528590bc2254a7f04f2b
6
+ metadata.gz: ea85bde7a3e7f9ca2e3a124fe0613a1e2df76e29311557ba69065bb7968833d343c5e43afe887c260552095d602677335aac8a1f3a0a45b865d3f4ee9514afbc
7
+ data.tar.gz: 3dab6a921e4a4b40b28f3d434c2e099760b69c4d0d2d8d291e41131c2b9013da8656a7d992de9a24b8acbb63d1da6f333cba52e8a10560aa4e2e1af7144e147e
data/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
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.2.0] - 2026-05-16
9
+
10
+ ### Changed
11
+ - Updated all API endpoints to match FotMob's current backend (`/api/data/`)
12
+ - `get_matches` fully working — returns all matches across 150+ leagues for a date
13
+ - `get_match_details` reimplemented via Next.js SSR data (full lineups, stats, events)
14
+ - `get_match_details` now auto-refreshes build ID on stale deploys (transparent retry)
15
+ - Added `timezone` option to client (default: `Europe/Paris`)
16
+ - Removed `get_player` — endpoint now requires Cloudflare Turnstile (browser-only)
17
+
18
+ ## [0.1.0] - 2026-01-15
19
+
20
+ ### Added
21
+ - Initial release
22
+ - `get_team`, `get_match_details`, `get_player`, `get_league`, `get_matches`
23
+ - Custom error classes, configurable timeout, VCR-based test suite
24
+
25
+ [0.1.0]: https://github.com/bjrsti/fotmob/releases/tag/v0.1.0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Stian Bjørkelo
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # Fotmob Ruby Gem
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/fotmob.svg)](https://badge.fury.io/rb/fotmob)
4
+ [![CI](https://github.com/bjrsti/fotmob/actions/workflows/ci.yml/badge.svg)](https://github.com/bjrsti/fotmob/actions/workflows/ci.yml)
5
+ [![Ruby](https://img.shields.io/badge/ruby-%3E%3D%202.7-ruby.svg)](https://www.ruby-lang.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ An unofficial Ruby wrapper for the [FotMob](https://www.fotmob.com/) API. Get football/soccer data including team stats, match details, and league standings.
9
+
10
+ ## Features
11
+
12
+ - 🏆 **Team Data** - Get comprehensive team information and statistics
13
+ - ⚽ **Match Details** - Detailed match information including lineups, stats, and live scores
14
+ - 📅 **Matches by Date** - All matches for a given day across 150+ leagues
15
+ - 📊 **League Data** - League tables, fixtures, and competition details
16
+ - 🛡️ **Error Handling** - Custom error classes for different scenarios
17
+ - ⏱️ **Configurable** - Timeout and timezone support
18
+
19
+ ## Installation
20
+
21
+ Add to your Gemfile:
22
+
23
+ ```ruby
24
+ gem 'fotmob'
25
+ ```
26
+
27
+ Or install directly:
28
+
29
+ ```bash
30
+ gem install fotmob
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```ruby
36
+ require 'fotmob'
37
+
38
+ client = Fotmob.new
39
+
40
+ # All matches for today
41
+ matches = client.get_matches("20260516")
42
+ matches[:leagues].each { |l| puts l[:name] }
43
+
44
+ # Match details (lineups, stats, events)
45
+ match = client.get_match_details("5315746")
46
+ puts "#{match[:general][:homeTeam][:name]} vs #{match[:general][:awayTeam][:name]}"
47
+ puts match[:header][:status][:scoreStr]
48
+
49
+ # Team info
50
+ team = client.get_team("8455") # Chelsea
51
+ puts team[:details][:name]
52
+
53
+ # League standings
54
+ league = client.get_league("47") # Premier League
55
+ puts league[:details][:name]
56
+ ```
57
+
58
+ ## API Methods
59
+
60
+ ### `get_matches(date)`
61
+
62
+ All matches for a given date (150+ leagues).
63
+
64
+ ```ruby
65
+ matches = client.get_matches("20260516")
66
+ # Returns: { leagues: [...], date: "..." }
67
+ # Each league has a :matches array with scores, teams, status
68
+ ```
69
+
70
+ ### `get_match_details(match_id)`
71
+
72
+ Full match data — lineups, stats, events, shotmap.
73
+
74
+ ```ruby
75
+ match = client.get_match_details("5315746")
76
+ # Returns: { general:, header:, content: { stats:, lineup:, shotmap:, ... } }
77
+ ```
78
+
79
+ ### `get_team(team_id)`
80
+
81
+ Team overview, fixtures, and squad.
82
+
83
+ ```ruby
84
+ team = client.get_team("8455")
85
+ # Returns: { details:, overview:, fixtures:, ... }
86
+ ```
87
+
88
+ ### `get_league(league_id)`
89
+
90
+ League table, fixtures, and stats.
91
+
92
+ ```ruby
93
+ league = client.get_league("47")
94
+ # Returns: { details:, table:, fixtures:, stats:, ... }
95
+ ```
96
+
97
+ ## Configuration
98
+
99
+ ```ruby
100
+ # Defaults: timeout 10s, timezone Europe/Paris
101
+ client = Fotmob.new(timeout: 30, timezone: "Europe/Paris")
102
+ ```
103
+
104
+ ## Error Handling
105
+
106
+ The gem includes custom error classes for different scenarios:
107
+
108
+ ```ruby
109
+ begin
110
+ team = client.get_team("invalid_id")
111
+ rescue Fotmob::NotFoundError => e
112
+ puts "Team not found: #{e.message}"
113
+ rescue Fotmob::RateLimitError => e
114
+ puts "Rate limit exceeded: #{e.message}"
115
+ rescue Fotmob::TimeoutError => e
116
+ puts "Request timed out: #{e.message}"
117
+ rescue Fotmob::APIError => e
118
+ puts "API error: #{e.message} (Status: #{e.status_code})"
119
+ rescue Fotmob::Error => e
120
+ puts "Error: #{e.message}"
121
+ end
122
+ ```
123
+
124
+ ### Error Classes
125
+
126
+ - `Fotmob::Error` - Base error class
127
+ - `Fotmob::APIError` - API returned an error response
128
+ - `Fotmob::NotFoundError` - Resource not found (404)
129
+ - `Fotmob::RateLimitError` - Rate limit exceeded (429)
130
+ - `Fotmob::TimeoutError` - Request timed out
131
+ - `Fotmob::InvalidResponseError` - Invalid JSON response
132
+
133
+ ## Development
134
+
135
+ ```bash
136
+ # Clone the repository
137
+ git clone https://github.com/bjrsti/fotmob.git
138
+ cd fotmob
139
+
140
+ # Install dependencies
141
+ bundle install
142
+
143
+ # Run tests
144
+ bundle exec rspec
145
+
146
+ # Run linter
147
+ bundle exec rubocop
148
+
149
+ # Open console
150
+ bundle exec rake console
151
+ ```
152
+
153
+ ## Testing
154
+
155
+ The gem uses RSpec for testing with VCR for recording API responses:
156
+
157
+ ```bash
158
+ bundle exec rspec
159
+ ```
160
+
161
+ ## Contributing
162
+
163
+ 1. Fork it
164
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
165
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
166
+ 4. Push to the branch (`git push origin my-new-feature`)
167
+ 5. Create a Pull Request
168
+
169
+ ## Finding IDs
170
+
171
+ IDs are in the fotmob.com URL for each resource:
172
+
173
+ - **Teams**: `fotmob.com/teams/8455/overview/chelsea` → `8455`
174
+ - **Matches**: `fotmob.com/matches/chelsea-vs-manchester-city/abc123#5315746` → `5315746`
175
+ - **Leagues**: `fotmob.com/leagues/47/overview/premier-league` → `47`
176
+
177
+ ## Disclaimer
178
+
179
+ This is an unofficial API wrapper and is not affiliated with FotMob. Use at your own risk and be mindful of rate limits.
180
+
181
+ ## License
182
+
183
+ MIT License. See [LICENSE](LICENSE) for details.
184
+
185
+ ## Author
186
+
187
+ [Stian Bjørkelo](https://github.com/bjrsti)
188
+
189
+ ## Links
190
+
191
+ - [RubyGems](https://rubygems.org/gems/fotmob)
192
+ - [GitHub](https://github.com/bjrsti/fotmob)
193
+ - [Issues](https://github.com/bjrsti/fotmob/issues)
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open-uri"
4
+ require "json"
5
+ require "uri"
6
+ require "timeout"
7
+
8
+ module Fotmob
9
+ class Client
10
+ BASE_URL = "https://www.fotmob.com/api/data"
11
+ DEFAULT_TIMEOUT = 10
12
+ DEFAULT_TIMEZONE = "Europe/Paris"
13
+ UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " \
14
+ "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
15
+
16
+ attr_reader :timeout, :timezone
17
+
18
+ def initialize(timeout: DEFAULT_TIMEOUT, timezone: DEFAULT_TIMEZONE)
19
+ @timeout = timeout
20
+ @timezone = timezone
21
+ end
22
+
23
+ def get_league(league_id)
24
+ get("/leagues", id: league_id, tab: "overview")
25
+ end
26
+
27
+ def get_matches(date)
28
+ get("/matches", date: date, timezone: @timezone)
29
+ end
30
+
31
+ # Returns pageProps with keys: general, header, content (stats, lineup, etc.)
32
+ # Resolves the match slug via a redirect, with automatic buildId refresh on stale deploys.
33
+ def get_match_details(match_id)
34
+ @retried_build_id = false
35
+ build_id = fetch_build_id
36
+ slug = fetch_match_slug(match_id, build_id)
37
+ body = fetch_with_timeout(URI("https://www.fotmob.com/_next/data/#{build_id}/matches/#{slug}.json"))
38
+ parse_json(body)[:pageProps]
39
+ rescue OpenURI::HTTPError => e
40
+ handle_http_error(e)
41
+ end
42
+
43
+ def get_team(team_id)
44
+ get("/teams", id: team_id)
45
+ end
46
+
47
+ private
48
+
49
+ def get(path, **params)
50
+ uri = build_uri(path, params)
51
+ response_body = fetch_with_timeout(uri)
52
+ parse_json(response_body)
53
+ rescue OpenURI::HTTPError => e
54
+ handle_http_error(e)
55
+ end
56
+
57
+ def fetch_build_id(force: false)
58
+ @fetch_build_id = nil if force
59
+ @fetch_build_id ||= begin
60
+ html = fetch_with_timeout(URI("https://www.fotmob.com/"))
61
+ html.match(/"buildId":"([^"]+)"/)[1]
62
+ end
63
+ end
64
+
65
+ def fetch_match_slug(match_id, build_id)
66
+ redirect_body = fetch_with_timeout(
67
+ URI("https://www.fotmob.com/_next/data/#{build_id}/match/#{match_id}.json")
68
+ )
69
+ redirect = parse_json(redirect_body).dig(:pageProps, :__N_REDIRECT)
70
+ raise NotFoundError.new("Match #{match_id} not found", status_code: 404) unless redirect
71
+
72
+ redirect.sub(%r{^/matches/}, "").sub(/#.*$/, "")
73
+ rescue OpenURI::HTTPError => e
74
+ raise unless e.io.status[0].to_i == 404 && !@retried_build_id
75
+
76
+ @retried_build_id = true
77
+ fetch_match_slug(match_id, fetch_build_id(force: true))
78
+ end
79
+
80
+ def build_uri(path, params)
81
+ uri = URI(BASE_URL + path)
82
+ uri.query = URI.encode_www_form(params) unless params.empty?
83
+ uri
84
+ end
85
+
86
+ def fetch_with_timeout(uri)
87
+ Timeout.timeout(@timeout) do
88
+ URI.open(uri.to_s, "User-Agent" => UA).read
89
+ end
90
+ rescue Timeout::Error => e
91
+ raise TimeoutError, "Request timed out after #{@timeout} seconds: #{e.message}"
92
+ rescue OpenURI::HTTPError
93
+ raise
94
+ rescue StandardError => e
95
+ raise Error, "Network error: #{e.message}"
96
+ end
97
+
98
+ def handle_http_error(error)
99
+ status = error.io.status[0].to_i
100
+ body = begin
101
+ error.io.read
102
+ rescue StandardError
103
+ ""
104
+ end
105
+
106
+ case status
107
+ when 404
108
+ raise NotFoundError.new("Resource not found", status_code: 404, response_body: body)
109
+ when 429
110
+ raise RateLimitError.new("Rate limit exceeded. Please try again later.", status_code: 429, response_body: body)
111
+ when 400..499
112
+ raise APIError.new("Client error: #{status}", status_code: status, response_body: body)
113
+ when 500..599
114
+ raise APIError.new("Server error: #{status}", status_code: status, response_body: body)
115
+ else
116
+ raise APIError.new("HTTP Error: #{status}", status_code: status, response_body: body)
117
+ end
118
+ end
119
+
120
+ def parse_json(body)
121
+ JSON.parse(body, symbolize_names: true)
122
+ rescue JSON::ParserError => e
123
+ raise InvalidResponseError, "Failed to parse response: #{e.message}"
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fotmob
4
+ # Base error class for all Fotmob errors
5
+ class Error < StandardError; end
6
+
7
+ # Raised when the API returns an error response
8
+ class APIError < Error
9
+ attr_reader :status_code, :response_body
10
+
11
+ def initialize(message, status_code: nil, response_body: nil)
12
+ @status_code = status_code
13
+ @response_body = response_body
14
+ super(message)
15
+ end
16
+ end
17
+
18
+ # Raised when a resource is not found (404)
19
+ class NotFoundError < APIError; end
20
+
21
+ # Raised when rate limit is exceeded (429)
22
+ class RateLimitError < APIError; end
23
+
24
+ # Raised when the request times out
25
+ class TimeoutError < Error; end
26
+
27
+ # Raised when the response cannot be parsed or is invalid
28
+ class InvalidResponseError < Error; end
29
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fotmob
4
+ VERSION = "0.2.0"
5
+ end
data/lib/fotmob.rb CHANGED
@@ -1,45 +1,18 @@
1
- require 'open-uri'
2
- require 'json'
1
+ # frozen_string_literal: true
3
2
 
4
- class Fotmob
5
-
6
- BASE_URL = "http://www.fotmob.com/api"
7
- LEAGUES_URL = BASE_URL + "/leagues?id="
8
- MATCHES_URL = BASE_URL + "/matches?date="
9
- MATCH_DETAILS_URL = BASE_URL + "/matchDetails?matchId="
10
- PLAYER_URL = BASE_URL + "/playerData?id="
11
- TEAMS_URL = BASE_URL + "/teams?id="
12
-
13
- def get_league(league_id)
14
- json = URI.open(LEAGUES_URL+league_id).read
15
- symbolize_json(json)
16
- end
17
-
18
- def get_matches(match_date)
19
- json = URI.open(MATCHES_URL+match_date).read
20
- symbolize_json(json)
21
- end
22
-
23
- def get_match_details(match_id)
24
- json = URI.open(MATCH_DETAILS_URL+match_id).read
25
- symbolize_json(json)
26
- end
27
-
28
- def get_player(player_id)
29
- json = URI.open(PLAYER_URL+player_id).read
30
- symbolize_json(json)
31
- end
32
-
33
- def get_team(team_id)
34
- json = URI.open(TEAMS_URL+team_id).read
35
- symbolize_json(json)
36
- end
37
-
38
-
39
- private
40
-
41
- def symbolize_json(json)
42
- JSON.parse(json, :symbolize_names => true)
3
+ require_relative "fotmob/version"
4
+ require_relative "fotmob/error"
5
+ require_relative "fotmob/client"
6
+
7
+ # FotMob API wrapper for Ruby
8
+ module Fotmob
9
+ class << self
10
+ # Create a new client instance
11
+ #
12
+ # @param options [Hash] Client options
13
+ # @return [Fotmob::Client] A new client instance
14
+ def new(**options)
15
+ Client.new(**options)
16
+ end
43
17
  end
44
-
45
- end
18
+ end
metadata CHANGED
@@ -1,67 +1,108 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fotmob
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stian Bjørkelo
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-10-30 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: open-uri
13
+ name: rake
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '0.2'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 0.2.0
23
- type: :runtime
18
+ version: '13.0'
19
+ type: :development
24
20
  prerelease: false
25
21
  version_requirements: !ruby/object:Gem::Requirement
26
22
  requirements:
27
23
  - - "~>"
28
24
  - !ruby/object:Gem::Version
29
- version: '0.2'
30
- - - ">="
25
+ version: '13.0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.2.0
32
+ version: '3.12'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '3.12'
33
40
  - !ruby/object:Gem::Dependency
34
- name: json
41
+ name: rubocop
35
42
  requirement: !ruby/object:Gem::Requirement
36
43
  requirements:
37
44
  - - "~>"
38
45
  - !ruby/object:Gem::Version
39
- version: '2.6'
40
- - - ">="
46
+ version: '1.50'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
41
52
  - !ruby/object:Gem::Version
42
- version: 2.6.2
43
- type: :runtime
53
+ version: '1.50'
54
+ - !ruby/object:Gem::Dependency
55
+ name: vcr
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '6.1'
61
+ type: :development
44
62
  prerelease: false
45
63
  version_requirements: !ruby/object:Gem::Requirement
46
64
  requirements:
47
65
  - - "~>"
48
66
  - !ruby/object:Gem::Version
49
- version: '2.6'
50
- - - ">="
67
+ version: '6.1'
68
+ - !ruby/object:Gem::Dependency
69
+ name: webmock
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.18'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
51
80
  - !ruby/object:Gem::Version
52
- version: 2.6.2
53
- description: Lets you pull data from fotmob for easy access
81
+ version: '3.18'
82
+ description: A simple Ruby gem for accessing football/soccer data from the FotMob
83
+ API. Get team stats, match details, player data, league tables, and more.
54
84
  email: stianbj@gmail.com
55
85
  executables: []
56
86
  extensions: []
57
87
  extra_rdoc_files: []
58
88
  files:
89
+ - CHANGELOG.md
90
+ - LICENSE
91
+ - README.md
59
92
  - lib/fotmob.rb
93
+ - lib/fotmob/client.rb
94
+ - lib/fotmob/error.rb
95
+ - lib/fotmob/version.rb
60
96
  homepage: https://github.com/bjrsti/fotmob
61
97
  licenses:
62
98
  - MIT
63
- metadata: {}
64
- post_install_message:
99
+ metadata:
100
+ homepage_uri: https://github.com/bjrsti/fotmob
101
+ source_code_uri: https://github.com/bjrsti/fotmob
102
+ bug_tracker_uri: https://github.com/bjrsti/fotmob/issues
103
+ changelog_uri: https://github.com/bjrsti/fotmob/blob/main/CHANGELOG.md
104
+ documentation_uri: https://github.com/bjrsti/fotmob#readme
105
+ rubygems_mfa_required: 'true'
65
106
  rdoc_options: []
66
107
  require_paths:
67
108
  - lib
@@ -69,15 +110,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
110
  requirements:
70
111
  - - ">="
71
112
  - !ruby/object:Gem::Version
72
- version: '0'
113
+ version: 2.7.0
73
114
  required_rubygems_version: !ruby/object:Gem::Requirement
74
115
  requirements:
75
116
  - - ">="
76
117
  - !ruby/object:Gem::Version
77
118
  version: '0'
78
119
  requirements: []
79
- rubygems_version: 3.3.24
80
- signing_key:
120
+ rubygems_version: 4.0.6
81
121
  specification_version: 4
82
- summary: An unofficial Fotmob API wrapper for Ruby
122
+ summary: An unofficial FotMob API wrapper for Ruby
83
123
  test_files: []