| 1 | from django.db import models |
| 2 | from . import settings |
| 3 | import requests |
| 4 | |
| 5 | |
| 6 | class Location(models.Model): |
| 7 | ip = models.GenericIPAddressField(primary_key=True) |
| 8 | city = models.CharField(max_length=100, null=True) |
| 9 | region = models.CharField(max_length=100, null=True) |
| 10 | country = models.CharField(max_length=100, null=True) |
| 11 | loc = models.CharField(max_length=60, null=True) |
| 12 | org = models.CharField(max_length=100, null=True) |
| 13 | postal = models.CharField(max_length=20, null=True) |
| 14 | timezone = models.CharField(max_length=50, null=True) |
| 15 | bogon = models.BooleanField(default=False) |
| 16 | success = models.BooleanField(default=False) |
| 17 | |
| 18 | def download(self): |
| 19 | try: |
| 20 | data = requests.get(f'http://ipinfo.io/{self.ip}/json').json() |
| 21 | except: |
| 22 | return |
| 23 | self.success = True |
| 24 | self.city = data.get('city') |
| 25 | self.region = data.get('region') |
| 26 | self.country = data.get('country') |
| 27 | self.loc = data.get('loc') |
| 28 | self.org = data.get('org') |
| 29 | self.postal = data.get('postal') |
| 30 | self.timezone = data.get('timezone') |
| 31 | self.bogon = data.get('bogon') |
| 32 | return data |
| 33 | |
| 34 | def save(self, *args, **kwargs): |
| 35 | if settings.LIVE_LOGGER_DOWNLOAD_IPINFO and not self.success: |
| 36 | self.download() |
| 37 | super().save(*args, **kwargs) |
| 38 | |
| 39 | def __str__(self): |
| 40 | return self.ip |
| 41 | |
| 42 | |
| 43 | class Log(models.Model): |
| 44 | meta = models.JSONField() |
| 45 | messages = models.JSONField(default=list) |
| 46 | json = models.JSONField(default=dict) |
| 47 | start_time = models.DateTimeField() |
| 48 | end_time = models.DateTimeField() |
| 49 | location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True) |
| 50 | user = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True) |
| 51 | status_code = models.IntegerField(null=True) |
| 52 | |
| 53 | def save(self, *args, **kwargs): |
| 54 | kwargs.pop('loc', None) |
| 55 | kwargs.pop('is_new', None) |
| 56 | meta = kwargs.pop('meta', self.meta).copy() |
| 57 | (loc, is_new) = Location.objects.update_or_create(ip=meta['REMOTE_ADDR'], defaults={ |
| 58 | 'ip': meta['REMOTE_ADDR'] |
| 59 | }) |
| 60 | for key, val in meta.items(): |
| 61 | meta[key] = str(val) |
| 62 | self.location = loc |
| 63 | self.is_new = is_new |
| 64 | self.meta = meta |
| 65 | overflow = Log.objects.count() - settings.LIVE_LOGGER_STORAGE_LENGTH |
| 66 | if overflow > 0: |
| 67 | ids_to_delete = Log.objects.all().order_by('id')[:overflow].values_list('id', flat=True) |
| 68 | Log.objects.filter(id__in=list(ids_to_delete)).delete() |
| 69 | super().save(*args, **kwargs) |
| 70 | |
| 71 | def __str__(self): |
| 72 | return self.meta['PATH_INFO'] |
| 73 | |
| 74 | def __call__(self, message): |
| 75 | self.messages += [message] |
| 76 | return self |