1
Fork 0

geoip: save to DB

This commit is contained in:
Motiejus Jakštys 2024-01-12 12:12:13 +02:00
parent a7d1fd83ef
commit d8223b3ad4
4 changed files with 20 additions and 45 deletions

View File

@ -4,10 +4,10 @@ from .models import Signup
@admin.register(Signup) @admin.register(Signup)
class SignupAdmin(admin.ModelAdmin): class SignupAdmin(admin.ModelAdmin):
_all_fields = ["email", "created_at", "anonymized_ip", "user_agent"] _all_fields = ["email", "created_at", "anonymized_ip", "user_agent", "geoip"]
date_hierarchy = "created_at" date_hierarchy = "created_at"
list_display = ["email", "created_at", "anonymized_ip", "user_agent"] + ["place_name"] list_display = ["email", "created_at", "user_agent"] + ["place_name"]
list_filter = ["email", "user_agent"] list_filter = ["email", "user_agent"]
ordering = ["created_at"] ordering = ["created_at"]
readonly_fields = _all_fields + ["place_name"] readonly_fields = _all_fields + ["place_name"]

View File

@ -1,28 +0,0 @@
# Generated by Django 5.0 on 2023-12-14 20:13
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Signup',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('email', models.EmailField(max_length=254)),
('created_at', models.DateTimeField(auto_now_add=True)),
('anonymized_ip', models.GenericIPAddressField()),
('user_agent', models.CharField(max_length=255)),
],
),
migrations.AddConstraint(
model_name='signup',
constraint=models.UniqueConstraint(fields=('email',), name='unique_email'),
),
]

View File

@ -1,13 +1,11 @@
import geoip2
from django.db import models from django.db import models
from django.contrib.gis.geoip2 import GeoIP2
class Signup(models.Model): class Signup(models.Model):
email = models.EmailField() email = models.EmailField()
created_at = models.DateTimeField(auto_now_add = True) created_at = models.DateTimeField(auto_now_add = True)
anonymized_ip = models.GenericIPAddressField() anonymized_ip = models.GenericIPAddressField()
user_agent = models.CharField(max_length = 255) user_agent = models.CharField(max_length = 255)
geoip = models.JSONField(null = True, blank = True)
class Meta: class Meta:
constraints = [ constraints = [
@ -17,13 +15,7 @@ class Signup(models.Model):
def __str__(self): def __str__(self):
return self.email return self.email
def _city(self):
try:
return GeoIP2().city(self.anonymized_ip)
except geoip2.errors.AddressNotFoundError:
return None
def place_name(self): def place_name(self):
if city := self._city(): if geoip := self.geoip:
return "{}, {}".format(city["city"], city["country_name"]) return "{}, {}".format(geoip["city"], geoip["country_name"])
return "??" return "??"

View File

@ -1,8 +1,12 @@
import logging import logging
import geoip2
from django.contrib.gis.geoip2 import GeoIP2
from django.shortcuts import render, redirect from django.shortcuts import render, redirect
from django.urls import reverse from django.urls import reverse
from django.db import IntegrityError from django.db import IntegrityError
from django.core.exceptions import ValidationError
from django.db.utils import DatabaseError
from lib.anonymize_ip import anonymize_ip from lib.anonymize_ip import anonymize_ip
@ -21,21 +25,28 @@ def index(request):
ip = request.META.get('REMOTE_ADDR') ip = request.META.get('REMOTE_ADDR')
anonymous_ip = anonymize_ip(ip) anonymous_ip = anonymize_ip(ip)
e = Signup( try:
geoip = GeoIP2().city(anonymous_ip)
except geoip2.errors.AddressNotFoundError:
geoip = None
s = Signup(
email = request.POST.get("email"), email = request.POST.get("email"),
anonymized_ip = anonymous_ip, anonymized_ip = anonymous_ip,
user_agent = request.META["HTTP_USER_AGENT"], user_agent = request.META["HTTP_USER_AGENT"],
geoip = geoip,
) )
try: try:
e.clean_fields() s.clean_fields()
except ValidationError as e: except ValidationError as e:
return e.render(request, "signup/index.html", print(e)
return render(request, "signup/index.html",
{"error_message": e.message}) {"error_message": e.message})
logging.info("registering email={}".format(request.POST.get("email"))) logging.info("registering email={}".format(request.POST.get("email")))
try: try:
e.save() s.save()
except IntegrityError: except IntegrityError:
# email already registered, presumably # email already registered, presumably
return redirect(reverse("index") + "?success=already_subscribed") return redirect(reverse("index") + "?success=already_subscribed")