[locations] Fix scrobbling logic for locations

This commit is contained in:
2024-02-12 13:47:15 -05:00
parent 13124aca6b
commit 6b80d107b0

View File

@ -5,6 +5,8 @@ import logging
from typing import Optional from typing import Optional
from uuid import uuid4 from uuid import uuid4
from pendulum import DateTime
from boardgames.models import BoardGame from boardgames.models import BoardGame
from books.koreader import process_koreader_sqlite_file from books.koreader import process_koreader_sqlite_file
from books.models import Book from books.models import Book
@ -701,6 +703,11 @@ class Scrobble(TimeStampedModel):
if self.is_stale: if self.is_stale:
logger.info(f"No - stale - {self.id} - {self.source}") logger.info(f"No - stale - {self.id} - {self.source}")
updatable = False updatable = False
if self.media_obj.__class__.__name__ == "GeoLocation":
logger.info(
f"Yes - geolocation is always updatable - {self.id} - {self.source}"
)
updateable = True
return updatable return updatable
@ -768,21 +775,9 @@ class Scrobble(TimeStampedModel):
# Do some funny stuff if it's a geo location # Do some funny stuff if it's a geo location
if mtype == cls.MediaType.GEO_LOCATION: if mtype == cls.MediaType.GEO_LOCATION:
moved_location = cls.user_has_moved_locations(media, user_id) scrobble = cls.check_location_for_finish(
if not moved_location: media, scrobble_data, user_id
logger.info( )
f"[scrobbling] updating {scrobble.id} for {mtype} {media.id} from {source}",
{"scrobble_data": scrobble_data, "media": media},
)
return scrobble.update(scrobble_data)
else:
logger.info(
f"[scrobbling] finishing {scrobble.id} for {mtype} {media.id} from {source}",
{"scrobble_data": scrobble_data, "media": media},
)
scrobble.stop()
# Just blank our scrobble so we create a new one
scrobble = None
if scrobble and scrobble.can_be_updated: if scrobble and scrobble.can_be_updated:
logger.info( logger.info(
@ -800,42 +795,53 @@ class Scrobble(TimeStampedModel):
return cls.create(scrobble_data) return cls.create(scrobble_data)
@classmethod @classmethod
def user_has_moved_locations( def check_location_for_finish(
cls, location: GeoLocation, user_id: int cls, location: GeoLocation, scrobble_data: dict, user_id: int
) -> bool: ) -> Optional["Scrobble"]:
moved_location = False
scrobble = ( scrobble = (
cls.objects.filter( cls.objects.filter(
media_type=cls.MediaType.GEO_LOCATION, user_id=user_id media_type=cls.MediaType.GEO_LOCATION,
user_id=user_id,
timestamp__lte=scrobble_data.get("timestamp"),
) )
.order_by("-timestamp") .order_by("-timestamp")
.first() .first()
) )
if not scrobble: if not scrobble:
logger.info( logger.info(
f"[scrobbling] No existing location scrobbles, {location} should be created" f"[scrobbling] No existing location scrobbles, location {location.id} should be new scrobble"
) )
moved_location = True return scrobble
else: if scrobble.media_obj == location:
if scrobble.media_obj == location: 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] New location {location} and last location {scrobble.media_obj} are the same" )
) return scrobble
moved_location = False
if scrobble.media_obj != location: logger.info(
logger.info( f"[scrobbling] new location {location.id} and old location {scrobble.media_obj.id} are different, checking proximity"
f"[scrobbling] New location {location} and last location {scrobble.media_obj} are different" )
) past_scrobbles = Scrobble.objects.filter(
past_scrobbles = Scrobble.objects.filter( media_type="GeoLocation",
media_type="GeoLocation", user_id=user_id,
user_id=user_id, ).order_by("-timestamp")[1:POINTS_FOR_MOVEMENT_HISTORY]
).order_by("-timestamp")[1:POINTS_FOR_MOVEMENT_HISTORY] past_points = [s.media_obj for s in past_scrobbles]
past_points = [s.media_obj for s in past_scrobbles]
moved_location = location.has_moved(past_points) if not location.has_moved(past_points):
return moved_location 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
logger.info(
f"[scrobbling] finishing {scrobble.id} so we can create new one for {location.id}",
)
scrobble.stop()
scrobble = None
return scrobble
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