From dbaf1896286affe48a97af67c94c99975fd8e467 Mon Sep 17 00:00:00 2001 From: Colin Powell Date: Tue, 15 Oct 2024 21:29:50 -0400 Subject: [PATCH] [scrobbles] Fix scrobbling duplicate tasks --- vrobbler/apps/scrobbles/dataclasses.py | 4 ++++ vrobbler/apps/scrobbles/mixins.py | 4 ++-- vrobbler/apps/scrobbles/models.py | 14 ++++++------- vrobbler/apps/scrobbles/scrobblers.py | 27 +++++++++++++++++++------- vrobbler/apps/tasks/constants.py | 2 +- vrobbler/apps/tasks/webhooks.py | 3 --- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/vrobbler/apps/scrobbles/dataclasses.py b/vrobbler/apps/scrobbles/dataclasses.py index cc0856d..5e91cbc 100644 --- a/vrobbler/apps/scrobbles/dataclasses.py +++ b/vrobbler/apps/scrobbles/dataclasses.py @@ -31,6 +31,10 @@ class JSONDataclass(JSONWizard): return json.dumps(self.asdict) +@dataclass +class ScrobbleLogData(JSONDataclass): + description: Optional[str] = None + class LongPlayLogData(JSONDataclass): serial_scrobble_id: Optional[int] long_play_complete: bool = False diff --git a/vrobbler/apps/scrobbles/mixins.py b/vrobbler/apps/scrobbles/mixins.py index 8d01b01..efc6d72 100644 --- a/vrobbler/apps/scrobbles/mixins.py +++ b/vrobbler/apps/scrobbles/mixins.py @@ -87,8 +87,8 @@ class ScrobblableMixin(TimeStampedModel): @property def logdata_cls(self) -> None: - logger.warning("logdata_cls() not implemented yet") - return None + from scrobbles.dataclasses import ScrobbleLogData + return ScrobbleLogData @property def subtitle(self) -> str: diff --git a/vrobbler/apps/scrobbles/models.py b/vrobbler/apps/scrobbles/models.py index cef2f81..cafd361 100644 --- a/vrobbler/apps/scrobbles/models.py +++ b/vrobbler/apps/scrobbles/models.py @@ -612,16 +612,14 @@ class Scrobble(TimeStampedModel): @property def logdata(self) -> Optional[logdata.JSONDataclass]: - if not self.media_obj.logdata_cls: - logger.warn( - f"Media type has no log data class, you should add one!", - extra={"media_type": self.media_type, "scrobble_id": self.id}, - ) - return None + if self.media_obj: + logdata_cls = self.media_obj.logdata_cls + else: + logdata_cls = logdata.ScrobbleLogData log_dict = self.log if isinstance(self.log, str): - # There's nothing stopping django from saving a string ina JSONField :( + # There's nothing stopping django from saving a string in a JSONField :( logger.warning( "[scrobbles] Received string in JSON data in log", extra={"log": self.log}, @@ -631,7 +629,7 @@ class Scrobble(TimeStampedModel): if not log_dict: log_dict = {} - return self.media_obj.logdata_cls.from_dict(log_dict) + return logdata_cls.from_dict(log_dict) def redirect_url(self, user_id) -> str: user = User.objects.filter(id=user_id).first() diff --git a/vrobbler/apps/scrobbles/scrobblers.py b/vrobbler/apps/scrobbles/scrobblers.py index 641236a..c66dad4 100644 --- a/vrobbler/apps/scrobbles/scrobblers.py +++ b/vrobbler/apps/scrobbles/scrobblers.py @@ -347,7 +347,7 @@ def todoist_scrobble_task(todoist_task: dict, user_id: int) -> Scrobble: if not prefix and suffix: logger.warning( "Missing a prefix and suffix tag for task", - extra={"todoist_task": todoist_task}, + extra={"todoist_scrobble_task": todoist_task}, ) title = " ".join([prefix.capitalize(), suffix.capitalize()]) @@ -359,13 +359,26 @@ def todoist_scrobble_task(todoist_task: dict, user_id: int) -> Scrobble: log__todoist_id=todoist_task.get("todoist_id"), task=task, ).last() - is_no_longer_in_progress = ( - "inprogress" not in todoist_task["todoist_label_list"] + in_progress_in_todoist = ( + "inprogress" in todoist_task["todoist_label_list"] ) - if in_progress_scrobble - if is_no_longer_in_progress: - scrobble = todoist_scrobble_task_finish(todoist_task, user_id) - return in_progress_scrobble + if not in_progress_scrobble and not in_progress_in_todoist: + logger.info( + "[todoist_scrobble_task] no task in progress, and no inprogress label found", + extra={ + "todoist_type": todoist_task["todoist_type"], + "todoist_event": todoist_task["todoist_event"], + "todoist_id": todoist_task["todoist_id"], + }, + ) + return + + if in_progress_scrobble and not in_progress_in_todoist: + scrobble = todoist_scrobble_task_finish(todoist_task, user_id) + + # TODO this logic probably belongs in create_or_update + if in_progress_scrobble: + return scrobble # TODO Should use updated_at from TOdoist, but parsing isn't working scrobble_dict = { diff --git a/vrobbler/apps/tasks/constants.py b/vrobbler/apps/tasks/constants.py index ac01ddf..c6ca6a1 100644 --- a/vrobbler/apps/tasks/constants.py +++ b/vrobbler/apps/tasks/constants.py @@ -3,7 +3,7 @@ TODOIST_TITLE_SUFFIX_LABELS = [ "bug", "project", "errand", - "chores", + "chore", "admin", "meeting", "habit", diff --git a/vrobbler/apps/tasks/webhooks.py b/vrobbler/apps/tasks/webhooks.py index 6099477..4ec4e73 100644 --- a/vrobbler/apps/tasks/webhooks.py +++ b/vrobbler/apps/tasks/webhooks.py @@ -57,9 +57,6 @@ def todoist_webhook(request): .user_id ) # TODO huge hack, find a way to populate user id from Todoist - if not user_id: - user_id = 1 - scrobble = todoist_scrobble_task(todoist_task, user_id) if not scrobble: