merefield
(Robert)
31 Gennaio 2026, 7:06pm
1213
Se stai pagando, sì
Questo è un plugin indipendente, il supporto non è gratuito e non fornisco alcuna garanzia - lo usi a tuo rischio.
Avrei potuto facilmente non condividerlo affatto, da nessuna parte.
3 Mi Piace
merefield
(Robert)
31 Gennaio 2026, 9:04pm
1214
Questo è stato ora unito, ancora grazie agli sponsor @祁同伟 e @nathank
main ← automated_ip_based_user_location_determination
merged 09:02PM - 31 Jan 26 UTC
## IP‑based User Location (MaxMind → GeoNames)
### What this adds
- Auto… matically determines a user’s location from their IP after post creation.
- Uses **MaxMind (DiscourseIpInfo)** for identity + GeoNames for canonical lat/lon.
- Stores exactly **one granularity level** per user (`country` / `province` / `city`) in `UserCustomField`
`geo_location`.
- Ensures lat/lon match the chosen granularity (privacy‑correct coordinates).
- Caches GeoNames lookups by `geoname_id` (no extra gems; uses `FinalDestination::HTTP`).
---
## Prerequisites (official accounts)
You must have valid accounts and credentials from:
- **MaxMind GeoLite2**
Sign up and obtain an Account ID + License Key:
https://www.maxmind.com/en/geolite2/signup
- **GeoNames**
Create a username for the GeoNames API and **enable Web Services** in your GeoNames account settings:
https://www.geonames.org/login
---
## Required Configuration
**Env vars (MaxMind) for `app.yml`**
- `DISCOURSE_MAXMIND_ACCOUNT_ID`
- `DISCOURSE_MAXMIND_LICENSE_KEY`
**Site settings**
- `location_geonames_username` (GeoNames username)
**Dev note (MaxMind DBs)**
- In development, ensure the MaxMind DBs are downloaded:
DISCOURSE_MAXMIND_ACCOUNT_ID=... DISCOURSE_MAXMIND_LICENSE_KEY=... bundle exec rake maxminddb:get
Restart web/sidekiq afterward so `DiscourseIpInfo` reloads the DBs.
---
## Settings
| Setting | Default | Description |
|---|---:|---|
| `location_ip_granularity` | `city` | Controls stored level: `country`, `province` (admin1), `county` (admin2), or `city`. |
| `location_geonames_username` | `""` | GeoNames username for `getJSON` requests. Acts as a feature flag (blank => skip). |
| `location_ip_lookup_cooldown_days` | `1` | Per‑user cooldown between IP lookups (0 disables cooldown). |
| `locations_skip_ip_based_location_update_if_existing` | `true` | Skip IP lookup when existing `geo_location` already has **lat + lon**. |
| `location_ip_auto_lookup_enabled` | `false` | Auto‑enqueue IP lookups on post creation. Rake task still works when off. |
---
## Flow
- `post_created` → enqueue `Jobs::Locations::IpLocationLookup` with user ID + IP.
- Job:
- Guards: plugin enabled, users map enabled, GeoNames username present, MaxMind env vars present, cooldown
OK, and optional “existing location” check.
- Uses `DiscourseIpInfo.get(ip)` to get `geoname_ids`.
- Resolves GeoNames IDs, picks feature by granularity (`country` / `province` / `county` / `city`), builds
`geo_location`.
- Saves `geo_location` to user custom field + updates `locations_user` table.
---
## Job + Hook
**Hook**
- `post_created` now enqueues `Jobs::Locations::IpLocationLookup`
- In development, IP is overridden to a fixed test IP (`2.139.231.7`) to ensure resolvable data.
**Job**
- `Jobs::Locations::IpLocationLookup` (new, in `app/jobs/regular/locations/ip_location_lookup.rb`)
- Logs key steps, skips when prerequisites are missing.
- Writes `geo_location` only when successfully built.
---
## GeoNames Helpers
New modules in `lib/locations/`:
- `GeoNamesClient`
- Calls `https://secure.geonames.org/getJSON` via `FinalDestination::HTTP`.
- Normalizes `geoname_id`, `fcl`, `fcode`, `lat`, `lon`, etc.
- Caches only successful lookups (avoids caching nil).
- `GeoNamesGranularityPicker`
- Selects best `PCLI` / `ADM1` / `PPL*` by desired granularity.
- `GeoLocationBuilder`
- Builds `geo_location` hash with correct `lat/lon`, `state`/`city` based on granularity.
---
## Rake Task
New rake task in `lib/tasks/locations.rake`:
**Task**
rake locations:enqueue_user_ip_location_lookups[username_pattern,pattern_type,delay]
**Behavior**
- Iterates users and enqueues the IP lookup job using `user.ip_address`.
- Progress is based on **matched population** (not total users).
- Skips enqueue when IP is blank.
**Options**
- `username_pattern` (optional): filter users by username.
- `pattern_type`: `string` (default substring match) or `regex`.
- `delay`: seconds between enqueues (float, default `0`).
**Help**
rake locations:enqueue_user_ip_location_lookups:help
Dettagli estesi sulla PR.
@Roi noto che non stai pagando per il supporto - tuttavia credo di aver migliorato il codice in questa PR, per favore prova di nuovo quello script che ho pubblicato. Se hai bisogno che dia un’occhiata più da vicino, puoi assumermi.
4 Mi Piace
Roi
31 Gennaio 2026, 10:11pm
1215
@merefield non ancora.
Ho appena controllato, la voce errata è rimasta anche con la nuova versione.
Ma dato che era solo un utente, ho controllato manualmente e aveva una città nel campo di posizione “normale” e ho ricreato il campo di posizione con queste informazioni. Ora la query è vuota.
2 Mi Piace
Quacken
1 Febbraio 2026, 3:10pm
1216
Ehi, ho pubblicato una segnalazione di bug altrove e sono stato reindirizzato a ripubblicarla in questa discussione.
Si scopre che se si abilitano le località per una categoria e si imposta la visualizzazione predefinita per la categoria su Mappa, la navigazione verso quella categoria provoca un crash.
Ecco alcuni screenshot (scusate la localizzazione, le parole significano “Aspetto: Elenco argomenti predefinito: Caldi, Ultimi, Migliori, Mappa”):
Sembra che il plugin acceda a siteSettings supponendo che sia definito quando non lo è.
Segnalazione di bug originale:
Support
Discourse Locations
Environment Discourse Version: v2026.2.0-latest +15 Plugin Commit: c1547ead Steps to Reproduce When using Locations plugin if I check Allow locations to be added to topics in this category and then try to set the map tab as the default view for...
Reading time: 1 mins 🕑
Likes: 1 ❤
1 Mi Piace
merefield
(Robert)
1 Febbraio 2026, 3:25pm
1217
grazie, se questo è abbastanza importante per te, puoi assumermi per sistemarlo. PR benvenuto.
1 Mi Piace