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

View File

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