Bläddra i källkod

[locations] Refactor has moved to not use multiple points

Colin Powell 1 år sedan
förälder
incheckning
df1bfd4177

+ 24 - 41
vrobbler/apps/locations/models.py

@@ -1,4 +1,4 @@
-from decimal import Decimal
+from decimal import Decimal, getcontext
 import logging
 from typing import Dict
 from uuid import uuid4
@@ -91,47 +91,37 @@ class GeoLocation(ScrobblableMixin):
             abs(Decimal(old_lat_lon[1]) - Decimal(self.lon)),
         )
 
-    def has_moved(self, past_points: list["GeoLocation"]) -> bool:
-        """GPS jumps from time to time. This function tries to smooth out
-        when we appear to have flagging our location as having not moved if one of our last
-        3"""
+    def has_moved_for_user(self, user_id: int) -> bool:
         has_moved = False
-        has_moved_locs = []
-        for point in past_points:
-            loc_diff = self.loc_diff((point.lat, point.lon))
-            loc_has_moved = False
-            if (
-                loc_diff[0] > GEOLOC_PROXIMITY
-                or loc_diff[1] > GEOLOC_PROXIMITY
-            ):
-                loc_has_moved = True
-            logger.info(
-                f"[locations] checked whether location has moved against proximity setting",
-                extra={
-                    "location": self,
-                    "loc_diff": loc_diff,
-                    "loc_has_moved": loc_has_moved,
-                    "point": point,
-                    "geoloc_proximity": GEOLOC_PROXIMITY,
-                },
-            )
-            has_moved_locs.append(loc_has_moved)
+        user = User.objects.filter(id=user_id).first()
+        if not user:
+            return False
+
+        last_point = (
+            user.scrobble_set.filter(media_type="GeoLocation")
+            .order_by("-timestamp")
+            .first()
+        ).media_obj
 
-        # Sum up all True values, if they're more than half of our locations, we've moved
-        if sum(has_moved_locs) > int(len(past_points) / 2):
+        if not last_point:
+            return True
+
+        loc_diff = self.loc_diff((last_point.lat, last_point.lon))
+        if loc_diff[0] > GEOLOC_PROXIMITY or loc_diff[1] > GEOLOC_PROXIMITY:
             has_moved = True
-        logger.info(
-            f"[locations] finished checking for movement",
+        logger.debug(
+            f"[locations] checked whether location has moved against proximity setting",
             extra={
+                "location": self,
+                "loc_diff": loc_diff,
                 "has_moved": has_moved,
-                "has_moved_locs": has_moved_locs,
-                "past_points": past_points,
+                "point": last_point,
+                "geoloc_proximity": GEOLOC_PROXIMITY,
             },
         )
-
         return has_moved
 
-    def in_proximity(self, named=True) -> models.QuerySet:
+    def in_proximity(self, named=False) -> models.QuerySet:
         lat_min = Decimal(self.lat) - GEOLOC_PROXIMITY
         lat_max = Decimal(self.lat) + GEOLOC_PROXIMITY
         lon_min = Decimal(self.lon) - GEOLOC_PROXIMITY
@@ -143,12 +133,5 @@ class GeoLocation(ScrobblableMixin):
             lat__gte=lat_min,
             lon__lte=lon_max,
             lon__gte=lon_min,
-        )
-        logger.info(
-            f"[locations] finished looking for proximate locations",
-            extra={
-                "close_locations": close_locations,
-                "is_title_null": is_title_null,
-            },
-        )
+        ).exclude(id=self.id)
         return close_locations

+ 3 - 3
vrobbler/apps/locations/tests/test_models.py

@@ -50,8 +50,8 @@ def test_found_in_proximity_location():
     close = GeoLocation.objects.create(
         lat=lat + 0.0001, lon=lon - 0.0001, altitude=60
     )
-    assert close not in loc.in_proximity()
-    assert close in loc.in_proximity(named=False)
+    assert close not in loc.in_proximity(named=True)
+    assert close in loc.in_proximity()
 
 
 @pytest.mark.django_db
@@ -63,7 +63,7 @@ def test_not_found_in_proximity_location():
     far = GeoLocation.objects.create(
         lat=lat + 0.0002, lon=lon - 0.0001, altitude=60
     )
-    assert far not in loc.in_proximity(named=False)
+    assert far not in loc.in_proximity()
 
 
 @pytest.mark.django_db

+ 1 - 15
vrobbler/apps/scrobbles/models.py

@@ -932,10 +932,7 @@ class Scrobble(TimeStampedModel):
             )
             return scrobble
 
-        jitter_correction_locations = cls.past_scrobbled_locations(
-            user_id, POINTS_FOR_MOVEMENT_HISTORY
-        )
-        has_moved = location.has_moved(jitter_correction_locations)
+        has_moved = location.has_moved(scrobble.user.id)
         logger.info(
             f"[scrobbling] checking - has last location has moved?",
             extra={
@@ -944,7 +941,6 @@ class Scrobble(TimeStampedModel):
                 "media_type": cls.MediaType.GEO_LOCATION,
                 "media_id": location.id,
                 "has_moved": has_moved,
-                "past_locations_used": jitter_correction_locations,
             },
         )
         if not has_moved:
@@ -986,16 +982,6 @@ class Scrobble(TimeStampedModel):
         )
         return scrobble
 
-    @classmethod
-    def past_scrobbled_locations(
-        cls, user_id: int, num: int
-    ) -> list["Location"]:
-        past_scrobbles = cls.objects.filter(
-            media_type="GeoLocation",
-            user_id=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)