1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- import logging
- from typing import Dict
- from uuid import uuid4
- from django.contrib.auth import get_user_model
- from django.conf import settings
- from django.db import models
- from django.urls import reverse
- from django_extensions.db.models import TimeStampedModel
- from scrobbles.mixins import ScrobblableMixin
- logger = logging.getLogger(__name__)
- BNULL = {"blank": True, "null": True}
- User = get_user_model()
- class GeoLocation(ScrobblableMixin):
- COMPLETION_PERCENT = getattr(settings, "LOCATION_COMPLETION_PERCENT", 100)
- uuid = models.UUIDField(default=uuid4, editable=False, **BNULL)
- lat = models.FloatField()
- lon = models.FloatField()
- altitude = models.FloatField(**BNULL)
- class Meta:
- unique_together = [["lat", "lon", "altitude"]]
- def __str__(self):
- return f"{self.lat} x {self.lon}"
- def get_absolute_url(self):
- return reverse(
- "locations:geo_location_detail", kwargs={"slug": self.uuid}
- )
- @property
- def truncated_lat(self):
- return float(str(self.lat)[:-3])
- @property
- def truncated_lan(self):
- return float(str(self.lon)[:-3])
- @classmethod
- def find_or_create(cls, data_dict: Dict) -> "GeoLocation":
- """Given a data dict from GPSLogger, does the heavy lifting of looking up
- the location, creating if if doesn't exist yet.
- """
- # TODO Add constants for all these data keys
- if "lat" not in data_dict.keys() or "lon" not in data_dict.keys():
- logger.error("No lat or lon keys in data dict")
- return
- lat_int, lat_places = data_dict.get("lat", "").split(".")
- lon_int, lon_places = data_dict.get("lon", "").split(".")
- alt_int, alt_places = data_dict.get("alt", "").split(".")
- truncated_lat = lat_places[0:5]
- truncated_lon = lon_places[0:5]
- truncated_alt = alt_places[0:3]
- data_dict["lat"] = float(".".join([lat_int, truncated_lat]))
- data_dict["lon"] = float(".".join([lon_int, truncated_lon]))
- data_dict["altitude"] = float(".".join([alt_int, truncated_alt]))
- location = cls.objects.filter(
- lat=data_dict.get("lat"),
- lon=data_dict.get("lon"),
- altitude=data_dict.get("alt"),
- ).first()
- if not location:
- location = cls.objects.create(
- lat=data_dict.get("lat"),
- lon=data_dict.get("lon"),
- altitude=data_dict.get("alt"),
- )
- return location
- class RawGeoLocation(TimeStampedModel):
- user = models.ForeignKey(User, on_delete=models.CASCADE)
- lat = models.FloatField()
- lon = models.FloatField()
- altitude = models.FloatField(**BNULL)
- speed = models.FloatField(**BNULL)
- timestamp = models.DateTimeField(**BNULL)
|