إذا كنت تدفع، نعم
هذا مكون إضافي مستقل، والدعم ليس مجانيًا ولا أقدم أي ضمانات - أنت تستخدمه على مسؤوليتك الخاصة.
كان بإمكاني بسهولة عدم مشاركة ذلك على الإطلاق، في أي مكان.
3 إعجابات
تم دمج هذا الآن، شكرًا مرة أخرى للداعمين @祁同伟 و @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
تفاصيل شاملة حول طلب السحب (PR).
@Roi ألاحظ أنك لا تدفع مقابل الدعم - ومع ذلك، أعتقد أنني ربما قمت بتحسين الكود في طلب السحب هذا، يرجى تجربة هذا السكريبت الذي نشرته مرة أخرى. إذا كنت بحاجة إليّ لإلقاء نظرة فاحصة، يمكنك توظيفي.
4 إعجابات
Roi
31 يناير 2026، 10:11م
1215
@merefield ليس بعد.
لقد تحققت للتو، وظل الإدخال السيئ موجودًا مع الإصدار الجديد أيضًا.
ولكن بما أنه كان مستخدمًا واحدًا فقط، فقد تحققت يدويًا وكان لديه مدينة في حقل الموقع “العادي” وأعدت إنشاء حقل الموقع بهذه المعلومات. الآن الاستعلام فارغ.
إعجابَين (2)
مرحباً، لقد نشرت تقريراً عن خطأ في مكان آخر وتمت إعادة توجيهي لإعادة نشره في هذا الموضوع.
اتضح أنه إذا قمت بتمكين المواقع لفئة ما وتعيين العرض الافتراضي للفئة على الخريطة، فإن الانتقال إلى تلك الفئة يؤدي إلى تعطل.
إليك بعض لقطات الشاشة (اعذروا الترجمة المحلية، الكلمات تعني “المظهر: قائمة المواضيع الافتراضية: ساخن، الأحدث، الأعلى، الخريطة”):
يبدو أن المكون الإضافي يصل إلى siteSettings بافتراض أنه مُعرَّف عندما لا يكون كذلك.
تقرير الخطأ الأصلي:
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)
شكرًا لك، إذا كان هذا الأمر مهمًا بما يكفي بالنسبة لك، يمكنك توظيفي لإصلاحه. نرحب بطلبات السحب (PR).
إعجاب واحد (1)