[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 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): class RawGeoLocation(TimeStampedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)

View File

@ -2,7 +2,7 @@ import calendar
import datetime import datetime
from decimal import Decimal from decimal import Decimal
import logging import logging
from typing import Optional from typing import Iterable, Optional
from uuid import uuid4 from uuid import uuid4
from boardgames.models import BoardGame from boardgames.models import BoardGame
@ -823,33 +823,39 @@ class Scrobble(TimeStampedModel):
logger.info( logger.info(
f"[scrobbling] updating {scrobble.id} - new location {location.id} and old location {scrobble.media_obj.id} are the same" 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( if not location.has_moved(
f"[scrobbling] new location {location.id} and old location {scrobble.media_obj.id} are different, checking proximity" self.past_scrobbled_locations(POINTS_FOR_MOVEMENT_HISTORY)
) ):
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):
logger.info( logger.info(
f"[scrobbling] new location{location.id} and old location {scrobble.media_obj.id} are different, but close enough to not move" 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( logger.info(
f"[scrobbling] finishing {scrobble.id} so we can create new one for {location.id}", 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( logger.info(
f"[scrobbling] creating for location {location.id} from GPSLogger" f"[scrobbling] creating for location {location.id} from GPSLogger"
) )
return cls.create(scrobble_data) 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": def update(self, scrobble_data: dict) -> "Scrobble":
# Status is a field we get from Mopidy, which refuses to poll us # Status is a field we get from Mopidy, which refuses to poll us
scrobble_status = scrobble_data.pop("mopidy_status", None) scrobble_status = scrobble_data.pop("mopidy_status", None)