From d8223b3ad4c9ad2b47ca76784cf2c07bed6dd789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Fri, 12 Jan 2024 12:12:13 +0200 Subject: [PATCH] geoip: save to DB --- app/signup/admin.py | 4 ++-- app/signup/migrations/0001_initial.py | 28 --------------------------- app/signup/models.py | 14 +++----------- app/signup/views.py | 19 ++++++++++++++---- 4 files changed, 20 insertions(+), 45 deletions(-) delete mode 100644 app/signup/migrations/0001_initial.py diff --git a/app/signup/admin.py b/app/signup/admin.py index 4ecd1be..9949bce 100644 --- a/app/signup/admin.py +++ b/app/signup/admin.py @@ -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"] diff --git a/app/signup/migrations/0001_initial.py b/app/signup/migrations/0001_initial.py deleted file mode 100644 index 5a2299c..0000000 --- a/app/signup/migrations/0001_initial.py +++ /dev/null @@ -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'), - ), - ] diff --git a/app/signup/models.py b/app/signup/models.py index 80e953b..6bc4755 100644 --- a/app/signup/models.py +++ b/app/signup/models.py @@ -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 "??" diff --git a/app/signup/views.py b/app/signup/views.py index 6991144..3e24669 100644 --- a/app/signup/views.py +++ b/app/signup/views.py @@ -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")