[locations] Check for close named locations before creating new

This commit is contained in:
2024-02-18 01:18:15 -05:00
parent 525c7c4e2b
commit 7035f01441
2 changed files with 33 additions and 14 deletions

View File

@ -107,6 +107,19 @@ class GeoLocation(ScrobblableMixin):
return has_moved
def named_in_proximity(self):
lat_min = Decimal(self.lat) - GEOLOC_PROXIMITY
lat_max = Decimal(self.lat) + GEOLOC_PROXIMITY
lon_min = Decimal(self.lon) - GEOLOC_PROXIMITY
lon_max = Decimal(self.lon) + GEOLOC_PROXIMITY
return GeoLocation.objects.filter(
title__isnull=False,
lat__lte=lat_max,
lat__gte=lat_min,
lon__lte=lon_max,
lon__gte=lon_min,
).first()
class RawGeoLocation(TimeStampedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE)

View File

@ -2,7 +2,7 @@ import calendar
import datetime
from decimal import Decimal
import logging
from typing import Optional
from typing import Iterable, Optional
from uuid import uuid4
from boardgames.models import BoardGame
@ -823,33 +823,39 @@ class Scrobble(TimeStampedModel):
logger.info(
f"[scrobbling] updating {scrobble.id} - new location {location.id} and old location {scrobble.media_obj.id} are the same"
)
return scrobble
return scrobble.update(scrobble_data)
logger.info(
f"[scrobbling] new location {location.id} and old location {scrobble.media_obj.id} are different, checking proximity"
)
past_scrobbles = Scrobble.objects.filter(
media_type="GeoLocation",
user_id=user_id,
).order_by("-timestamp")[1:POINTS_FOR_MOVEMENT_HISTORY]
past_points = [s.media_obj for s in past_scrobbles]
if not location.has_moved(past_points):
if not location.has_moved(
self.past_scrobbled_locations(POINTS_FOR_MOVEMENT_HISTORY)
):
logger.info(
f"[scrobbling] new location{location.id} and old location {scrobble.media_obj.id} are different, but close enough to not move"
)
return scrobble
return scrobble.update(scrobble_data)
logger.info(
f"[scrobbling] finishing {scrobble.id} so we can create new one for {location.id}",
)
scrobble.stop()
scrobble.stop(force_finish=True)
if existing_location := location.named_in_proximity():
logger.info(
f"[scrobbling] moved to {location.id} but named location {existing_location.id} found, using it instead"
)
scrobble_data["geo_location"] = existing_location
logger.info(
f"[scrobbling] creating for location {location.id} from GPSLogger"
)
return cls.create(scrobble_data)
def past_scrobbled_locations(self, num: int) -> Iterable["Location"]:
past_scrobbles = Scrobble.objects.filter(
media_type="GeoLocation",
user_id=self.user_id,
).order_by("-timestamp")[1:num]
return [s.geo_location for s in past_scrobbles]
def update(self, scrobble_data: dict) -> "Scrobble":
# Status is a field we get from Mopidy, which refuses to poll us
scrobble_status = scrobble_data.pop("mopidy_status", None)