trackdown 0.2.0 → 0.3.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/.simplecov +25 -0
- data/CHANGELOG.md +8 -0
- data/README.md +52 -7
- data/Rakefile +0 -1
- data/lib/trackdown/location_result.rb +23 -2
- data/lib/trackdown/providers/cloudflare_provider.rb +34 -1
- data/lib/trackdown/providers/maxmind_provider.rb +16 -1
- data/lib/trackdown/version.rb +1 -1
- metadata +10 -119
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 675d77c9715d2b1de76e4d385b95960b82f45355edb57689d2cf243197f19324
|
|
4
|
+
data.tar.gz: 061e61803019b00dd99e2d186f3c3ccbe73cf5ee9a750b513e1dfc11c46c0859
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5394b49ff9c641ae941675b2bc18da7e92d934effab2f771707ded19179ea4f019a5c18533dc059e5e8f12e7cf6ff0847d0e3dd91586e1e218bb7f0f3d96c139
|
|
7
|
+
data.tar.gz: bddbc1ea728846d08dd1ca75033c3a9b3eb95144fdbec641089593c8f1e177e3ac52eb9cb495b2a14bbc118d99d23a504f2ecbe37578017629f9344e13faf0d7
|
data/.simplecov
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
SimpleCov.start do
|
|
4
|
+
formatter SimpleCov::Formatter::SimpleFormatter
|
|
5
|
+
|
|
6
|
+
add_filter "/test/"
|
|
7
|
+
|
|
8
|
+
track_files "{lib,app}/**/*.rb"
|
|
9
|
+
|
|
10
|
+
enable_coverage :branch
|
|
11
|
+
|
|
12
|
+
minimum_coverage line: 80, branch: 65
|
|
13
|
+
|
|
14
|
+
command_name "Job #{ENV['TEST_ENV_NUMBER']}" if ENV['TEST_ENV_NUMBER']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
SimpleCov.at_exit do
|
|
18
|
+
SimpleCov.result.format!
|
|
19
|
+
puts "\n" + "=" * 60
|
|
20
|
+
puts "COVERAGE SUMMARY"
|
|
21
|
+
puts "=" * 60
|
|
22
|
+
puts "Line Coverage: #{SimpleCov.result.covered_percent.round(2)}%"
|
|
23
|
+
puts "Branch Coverage: #{SimpleCov.result.coverage_statistics[:branch]&.percent&.round(2) || 'N/A'}%"
|
|
24
|
+
puts "=" * 60
|
|
25
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## [0.3.0] - 2026-02-08
|
|
2
|
+
|
|
3
|
+
- Add 8 new geolocation fields: `region`, `region_code`, `continent`, `timezone`, `latitude`, `longitude`, `postal_code`, `metro_code`
|
|
4
|
+
- All new fields available from both Cloudflare and MaxMind providers
|
|
5
|
+
- All 10 Cloudflare "Add visitor location headers" now fully supported
|
|
6
|
+
- Backward compatible — all new fields are optional, existing API unchanged
|
|
7
|
+
- `to_h` now includes all new fields
|
|
8
|
+
|
|
1
9
|
## [0.2.0] - 2026-01-02
|
|
2
10
|
|
|
3
11
|
- Completely decouple Maxmind from the gem, making it optional
|
data/README.md
CHANGED
|
@@ -1,23 +1,36 @@
|
|
|
1
1
|
# 📍 `trackdown` - Ruby gem to geolocate IPs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> [!TIP]
|
|
4
|
+
> **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com/?ref=trackdown)**, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks. Go [check it out](https://railsfast.com/?ref=trackdown)!
|
|
5
|
+
|
|
6
|
+
`trackdown` is a Ruby gem that allows you to geolocate IP addresses easily.
|
|
7
|
+
|
|
8
|
+
It works out-of-the-box with **Cloudflare** (zero config!); and it's also a simple, convenient wrapper on top of **MaxMind** (just bring your own MaxMind key, and you're good to go!).
|
|
9
|
+
|
|
10
|
+
`trackdown` offers a clean API for Rails applications to fetch country, city, region, continent, timezone, coordinates, and emoji flag information for any IP address.
|
|
4
11
|
|
|
5
12
|
Given an IP, it gives you the corresponding:
|
|
6
13
|
- 🗺️ Country (two-letter country code + country name)
|
|
7
14
|
- 📍 City
|
|
15
|
+
- 🏔️ Region / state (e.g. "California") and region code (e.g. "CA")
|
|
16
|
+
- 🌍 Continent (e.g. "NA", "EU")
|
|
17
|
+
- 🕐 Timezone (e.g. "America/Los_Angeles")
|
|
18
|
+
- 📌 Latitude and longitude coordinates
|
|
19
|
+
- 📮 Postal code (e.g. "94107")
|
|
20
|
+
- 📺 Metro code (e.g. "807")
|
|
8
21
|
- 🇺🇸 Emoji flag of the country
|
|
9
22
|
|
|
10
|
-
##
|
|
23
|
+
## First, choose your `trackdown` Geo IP provider
|
|
11
24
|
|
|
12
25
|
### Option 1: Cloudflare (recommended, zero config)
|
|
13
26
|
|
|
14
|
-
If your app is behind Cloudflare, you can use `trackdown` with **zero configuration**:
|
|
27
|
+
If your Rails app is behind Cloudflare, you can use `trackdown` with **zero configuration**:
|
|
15
28
|
- No API keys needed
|
|
16
29
|
- No database downloads
|
|
17
30
|
- No external dependencies
|
|
18
31
|
- Instant lookups from Cloudflare headers
|
|
19
32
|
|
|
20
|
-
Just enable "IP Geolocation" in your Cloudflare dashboard and you're done!
|
|
33
|
+
Just enable "IP Geolocation" in your Cloudflare dashboard and you're done! For the full set of location fields (city, region, coordinates, etc.), enable ["Add visitor location headers"](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) in Managed Transforms. We automatically read these headers from the `request` and provide you with the IP geo data.
|
|
21
34
|
|
|
22
35
|
### Option 2: MaxMind (BYOK - Bring Your Own Key)
|
|
23
36
|
|
|
@@ -162,12 +175,23 @@ result.country_code # => 'US'
|
|
|
162
175
|
result.country_name # => 'United States'
|
|
163
176
|
result.country # => 'United States' (alias for country_name)
|
|
164
177
|
result.city # => 'Mountain View' (from MaxMind or Cloudflare's "Add visitor location headers")
|
|
178
|
+
result.region # => 'California'
|
|
179
|
+
result.region_code # => 'CA'
|
|
180
|
+
result.continent # => 'NA'
|
|
181
|
+
result.timezone # => 'America/Los_Angeles'
|
|
182
|
+
result.latitude # => 37.7749
|
|
183
|
+
result.longitude # => -122.4194
|
|
184
|
+
result.postal_code # => '94107'
|
|
185
|
+
result.metro_code # => '807'
|
|
165
186
|
result.flag_emoji # => '🇺🇸'
|
|
166
187
|
result.emoji # => '🇺🇸' (alias for flag_emoji)
|
|
167
188
|
result.country_flag # => '🇺🇸' (alias for flag_emoji)
|
|
168
189
|
result.country_info # => # Rich country data from the `countries` gem
|
|
169
190
|
```
|
|
170
191
|
|
|
192
|
+
> [!NOTE]
|
|
193
|
+
> The `region`, `region_code`, `continent`, `timezone`, `latitude`, `longitude`, `postal_code`, and `metro_code` fields require Cloudflare's ["Add visitor location headers"](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) Managed Transform to be enabled, or a MaxMind GeoLite2-City database. These fields return `nil` when not available.
|
|
194
|
+
|
|
171
195
|
### Rich country information
|
|
172
196
|
|
|
173
197
|
For `country_info` we're leveraging the [`countries`](https://github.com/countries/countries) gem, so you get a lot of information about the country, like the continent, the region, the languages spoken, the currency, and more:
|
|
@@ -191,6 +215,14 @@ result.to_h
|
|
|
191
215
|
# country_name: 'United States',
|
|
192
216
|
# city: 'Mountain View',
|
|
193
217
|
# flag_emoji: '🇺🇸',
|
|
218
|
+
# region: 'California',
|
|
219
|
+
# region_code: 'CA',
|
|
220
|
+
# continent: 'NA',
|
|
221
|
+
# timezone: 'America/Los_Angeles',
|
|
222
|
+
# latitude: 37.7749,
|
|
223
|
+
# longitude: -122.4194,
|
|
224
|
+
# postal_code: '94107',
|
|
225
|
+
# metro_code: '807',
|
|
194
226
|
# country_info: { ... }
|
|
195
227
|
# }
|
|
196
228
|
```
|
|
@@ -243,13 +275,26 @@ Trackdown.update_database
|
|
|
243
275
|
|
|
244
276
|
### Cloudflare Provider
|
|
245
277
|
|
|
246
|
-
When you enable "IP Geolocation" in Cloudflare, they add the `CF-IPCountry` header to every request. If you enable "Add visitor location headers" (via Managed Transforms), you
|
|
278
|
+
When you enable "IP Geolocation" in Cloudflare, they add the `CF-IPCountry` header to every request. If you also enable ["Add visitor location headers"](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) (via Managed Transforms), you get all 10 location headers:
|
|
279
|
+
|
|
280
|
+
| Cloudflare header | `trackdown` field |
|
|
281
|
+
|---|---|
|
|
282
|
+
| `cf-ipcountry` | `country_code` |
|
|
283
|
+
| `cf-ipcity` | `city` |
|
|
284
|
+
| `cf-ipcontinent` | `continent` |
|
|
285
|
+
| `cf-iplatitude` | `latitude` |
|
|
286
|
+
| `cf-iplongitude` | `longitude` |
|
|
287
|
+
| `cf-region` | `region` |
|
|
288
|
+
| `cf-region-code` | `region_code` |
|
|
289
|
+
| `cf-metro-code` | `metro_code` |
|
|
290
|
+
| `cf-postal-code` | `postal_code` |
|
|
291
|
+
| `cf-timezone` | `timezone` |
|
|
247
292
|
|
|
248
|
-
Trackdown reads these headers directly from the request with zero overhead
|
|
293
|
+
Trackdown reads these headers directly from the request with zero overhead — no database lookups, no external API calls.
|
|
249
294
|
|
|
250
295
|
### MaxMind Provider
|
|
251
296
|
|
|
252
|
-
Downloads the GeoLite2-City database to your server and performs local lookups using connection pooling for performance.
|
|
297
|
+
Downloads the [GeoLite2-City](https://dev.maxmind.com/geoip/docs/databases/city-and-country/) database to your server and performs local lookups using connection pooling for performance. All fields (`country`, `city`, `region`, `continent`, `timezone`, `latitude`, `longitude`, `postal_code`, `metro_code`) are extracted from the database record.
|
|
253
298
|
|
|
254
299
|
|
|
255
300
|
## Development
|
data/Rakefile
CHANGED
|
@@ -4,13 +4,26 @@ require 'countries'
|
|
|
4
4
|
|
|
5
5
|
module Trackdown
|
|
6
6
|
class LocationResult
|
|
7
|
-
attr_reader :country_code, :country_name, :city, :flag_emoji
|
|
7
|
+
attr_reader :country_code, :country_name, :city, :flag_emoji,
|
|
8
|
+
:region, :region_code, :continent, :timezone, :latitude, :longitude,
|
|
9
|
+
:postal_code, :metro_code
|
|
8
10
|
|
|
9
|
-
def initialize(country_code, country_name, city, flag_emoji
|
|
11
|
+
def initialize(country_code, country_name, city, flag_emoji,
|
|
12
|
+
region: nil, region_code: nil, continent: nil,
|
|
13
|
+
timezone: nil, latitude: nil, longitude: nil,
|
|
14
|
+
postal_code: nil, metro_code: nil)
|
|
10
15
|
@country_code = country_code
|
|
11
16
|
@country_name = country_name
|
|
12
17
|
@city = city
|
|
13
18
|
@flag_emoji = flag_emoji
|
|
19
|
+
@region = region
|
|
20
|
+
@region_code = region_code
|
|
21
|
+
@continent = continent
|
|
22
|
+
@timezone = timezone
|
|
23
|
+
@latitude = latitude
|
|
24
|
+
@longitude = longitude
|
|
25
|
+
@postal_code = postal_code
|
|
26
|
+
@metro_code = metro_code
|
|
14
27
|
end
|
|
15
28
|
|
|
16
29
|
alias_method :country, :country_name
|
|
@@ -29,6 +42,14 @@ module Trackdown
|
|
|
29
42
|
country_name: @country_name,
|
|
30
43
|
city: @city,
|
|
31
44
|
flag_emoji: @flag_emoji,
|
|
45
|
+
region: @region,
|
|
46
|
+
region_code: @region_code,
|
|
47
|
+
continent: @continent,
|
|
48
|
+
timezone: @timezone,
|
|
49
|
+
latitude: @latitude,
|
|
50
|
+
longitude: @longitude,
|
|
51
|
+
postal_code: @postal_code,
|
|
52
|
+
metro_code: @metro_code,
|
|
32
53
|
country_info: country_info&.data || {}
|
|
33
54
|
}
|
|
34
55
|
end
|
|
@@ -13,6 +13,14 @@ module Trackdown
|
|
|
13
13
|
class CloudflareProvider < BaseProvider
|
|
14
14
|
COUNTRY_HEADER = 'HTTP_CF_IPCOUNTRY'
|
|
15
15
|
CITY_HEADER = 'HTTP_CF_IPCITY'
|
|
16
|
+
REGION_HEADER = 'HTTP_CF_REGION'
|
|
17
|
+
REGION_CODE_HEADER = 'HTTP_CF_REGION_CODE'
|
|
18
|
+
LATITUDE_HEADER = 'HTTP_CF_IPLATITUDE'
|
|
19
|
+
LONGITUDE_HEADER = 'HTTP_CF_IPLONGITUDE'
|
|
20
|
+
TIMEZONE_HEADER = 'HTTP_CF_TIMEZONE'
|
|
21
|
+
CONTINENT_HEADER = 'HTTP_CF_IPCONTINENT'
|
|
22
|
+
METRO_CODE_HEADER = 'HTTP_CF_METRO_CODE'
|
|
23
|
+
POSTAL_CODE_HEADER = 'HTTP_CF_POSTAL_CODE'
|
|
16
24
|
|
|
17
25
|
# Special Cloudflare country codes
|
|
18
26
|
UNKNOWN_CODE = 'XX'
|
|
@@ -43,7 +51,17 @@ module Trackdown
|
|
|
43
51
|
city = extract_city(request)
|
|
44
52
|
flag_emoji = get_emoji_flag(country_code)
|
|
45
53
|
|
|
46
|
-
LocationResult.new(
|
|
54
|
+
LocationResult.new(
|
|
55
|
+
country_code, country_name, city, flag_emoji,
|
|
56
|
+
region: extract_header(request, REGION_HEADER),
|
|
57
|
+
region_code: extract_header(request, REGION_CODE_HEADER),
|
|
58
|
+
continent: extract_header(request, CONTINENT_HEADER),
|
|
59
|
+
timezone: extract_header(request, TIMEZONE_HEADER),
|
|
60
|
+
latitude: parse_coordinate(request.env[LATITUDE_HEADER]),
|
|
61
|
+
longitude: parse_coordinate(request.env[LONGITUDE_HEADER]),
|
|
62
|
+
postal_code: extract_header(request, POSTAL_CODE_HEADER),
|
|
63
|
+
metro_code: extract_header(request, METRO_CODE_HEADER)
|
|
64
|
+
)
|
|
47
65
|
end
|
|
48
66
|
|
|
49
67
|
private
|
|
@@ -64,6 +82,21 @@ module Trackdown
|
|
|
64
82
|
|
|
65
83
|
city
|
|
66
84
|
end
|
|
85
|
+
|
|
86
|
+
def extract_header(request, header)
|
|
87
|
+
value = request.env[header]
|
|
88
|
+
return nil if value.nil? || value.empty?
|
|
89
|
+
|
|
90
|
+
value
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def parse_coordinate(value)
|
|
94
|
+
return nil if value.nil? || value.empty?
|
|
95
|
+
|
|
96
|
+
Float(value)
|
|
97
|
+
rescue ArgumentError, TypeError
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
67
100
|
end
|
|
68
101
|
end
|
|
69
102
|
end
|
|
@@ -48,7 +48,17 @@ module Trackdown
|
|
|
48
48
|
city = extract_city(record)
|
|
49
49
|
flag_emoji = get_emoji_flag(country_code)
|
|
50
50
|
|
|
51
|
-
LocationResult.new(
|
|
51
|
+
LocationResult.new(
|
|
52
|
+
country_code, country_name, city, flag_emoji,
|
|
53
|
+
region: extract_region(record),
|
|
54
|
+
region_code: record&.dig('subdivisions', 0, 'iso_code'),
|
|
55
|
+
continent: record&.dig('continent', 'code'),
|
|
56
|
+
timezone: record&.dig('location', 'time_zone'),
|
|
57
|
+
latitude: record&.dig('location', 'latitude'),
|
|
58
|
+
longitude: record&.dig('location', 'longitude'),
|
|
59
|
+
postal_code: record&.dig('postal', 'code'),
|
|
60
|
+
metro_code: record&.dig('location', 'metro_code')&.to_s
|
|
61
|
+
)
|
|
52
62
|
end
|
|
53
63
|
|
|
54
64
|
private
|
|
@@ -103,6 +113,11 @@ module Trackdown
|
|
|
103
113
|
(record&.dig('city', 'names')&.values&.first) ||
|
|
104
114
|
'Unknown'
|
|
105
115
|
end
|
|
116
|
+
|
|
117
|
+
def extract_region(record)
|
|
118
|
+
record&.dig('subdivisions', 0, 'names', 'en') ||
|
|
119
|
+
record&.dig('subdivisions', 0, 'names')&.values&.first
|
|
120
|
+
end
|
|
106
121
|
end
|
|
107
122
|
end
|
|
108
123
|
end
|
data/lib/trackdown/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trackdown
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rameerez
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-02-08 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: countries
|
|
@@ -23,129 +23,19 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '7.0'
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
version: '13.0'
|
|
33
|
-
type: :development
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '13.0'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: rubocop
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '1.21'
|
|
47
|
-
type: :development
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '1.21'
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: minitest
|
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '5.25'
|
|
61
|
-
type: :development
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '5.25'
|
|
68
|
-
- !ruby/object:Gem::Dependency
|
|
69
|
-
name: mocha
|
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - "~>"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '2.0'
|
|
75
|
-
type: :development
|
|
76
|
-
prerelease: false
|
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - "~>"
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '2.0'
|
|
82
|
-
- !ruby/object:Gem::Dependency
|
|
83
|
-
name: simplecov
|
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
|
85
|
-
requirements:
|
|
86
|
-
- - "~>"
|
|
87
|
-
- !ruby/object:Gem::Version
|
|
88
|
-
version: '0.22'
|
|
89
|
-
type: :development
|
|
90
|
-
prerelease: false
|
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
-
requirements:
|
|
93
|
-
- - "~>"
|
|
94
|
-
- !ruby/object:Gem::Version
|
|
95
|
-
version: '0.22'
|
|
96
|
-
- !ruby/object:Gem::Dependency
|
|
97
|
-
name: webmock
|
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
|
99
|
-
requirements:
|
|
100
|
-
- - "~>"
|
|
101
|
-
- !ruby/object:Gem::Version
|
|
102
|
-
version: '3.0'
|
|
103
|
-
type: :development
|
|
104
|
-
prerelease: false
|
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
-
requirements:
|
|
107
|
-
- - "~>"
|
|
108
|
-
- !ruby/object:Gem::Version
|
|
109
|
-
version: '3.0'
|
|
110
|
-
- !ruby/object:Gem::Dependency
|
|
111
|
-
name: maxmind-db
|
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
|
113
|
-
requirements:
|
|
114
|
-
- - "~>"
|
|
115
|
-
- !ruby/object:Gem::Version
|
|
116
|
-
version: '1.2'
|
|
117
|
-
type: :development
|
|
118
|
-
prerelease: false
|
|
119
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
-
requirements:
|
|
121
|
-
- - "~>"
|
|
122
|
-
- !ruby/object:Gem::Version
|
|
123
|
-
version: '1.2'
|
|
124
|
-
- !ruby/object:Gem::Dependency
|
|
125
|
-
name: connection_pool
|
|
126
|
-
requirement: !ruby/object:Gem::Requirement
|
|
127
|
-
requirements:
|
|
128
|
-
- - "~>"
|
|
129
|
-
- !ruby/object:Gem::Version
|
|
130
|
-
version: '2.4'
|
|
131
|
-
type: :development
|
|
132
|
-
prerelease: false
|
|
133
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
-
requirements:
|
|
135
|
-
- - "~>"
|
|
136
|
-
- !ruby/object:Gem::Version
|
|
137
|
-
version: '2.4'
|
|
138
|
-
description: Trackdown is a Ruby gem that easily allows you to geolocate IP addresses.
|
|
139
|
-
It works out of the box with Cloudflare headers if you're using it, or you can use
|
|
140
|
-
MaxMind (BYOK). The gem offers a clean API for Rails applications to fetch country,
|
|
141
|
-
city, and emoji flag information for any IP address. Supports Cloudflare headers
|
|
142
|
-
(instant, zero overhead) and MaxMind GeoLite2 database (offline capable).
|
|
26
|
+
description: Trackdown is a Ruby gem that allows you to geolocate IP addresses easily.
|
|
27
|
+
It works out of the box with Cloudflare headers if your Rails app is behind it;
|
|
28
|
+
or you can also use MaxMind databases (BYOK). The gem offers a clean API for Rails
|
|
29
|
+
applications to fetch country, city, emoji flag, region, continent, postal code,
|
|
30
|
+
latitude, longitude and other GeoIP information for any IP address. Supports Cloudflare
|
|
31
|
+
headers, and MaxMind GeoLite2 databases (offline capable).
|
|
143
32
|
email:
|
|
144
33
|
- rubygems@rameerez.com
|
|
145
34
|
executables: []
|
|
146
35
|
extensions: []
|
|
147
36
|
extra_rdoc_files: []
|
|
148
37
|
files:
|
|
38
|
+
- ".simplecov"
|
|
149
39
|
- AGENTS.md
|
|
150
40
|
- CHANGELOG.md
|
|
151
41
|
- CLAUDE.md
|
|
@@ -173,6 +63,7 @@ licenses:
|
|
|
173
63
|
- MIT
|
|
174
64
|
metadata:
|
|
175
65
|
allowed_push_host: https://rubygems.org
|
|
66
|
+
rubygems_mfa_required: 'true'
|
|
176
67
|
homepage_uri: https://github.com/rameerez/trackdown
|
|
177
68
|
source_code_uri: https://github.com/rameerez/trackdown
|
|
178
69
|
changelog_uri: https://github.com/rameerez/trackdown/blob/main/CHANGELOG.md
|