diff --git a/vrobbler/apps/scrobbles/scrobblers.py b/vrobbler/apps/scrobbles/scrobblers.py index 058a47e..abc9f6e 100644 --- a/vrobbler/apps/scrobbles/scrobblers.py +++ b/vrobbler/apps/scrobbles/scrobblers.py @@ -321,6 +321,34 @@ def todoist_scrobble_task_finish( return scrobble +def todoist_scrobble_update_task( + todoist_note: dict, user_id: int +) -> Optional[Scrobble]: + scrobble = Scrobble.objects.filter( + in_progress=True, + user_id=user_id, + log__task_id=todoist_note.get("task_id"), + ).first() + + if scrobble: + existing_notes = scrobble.log.get("notes", {}) + existing_notes[todoist_note.get("todoist_id")] = todoist_note.get( + "content" + ) + scrobble.log["notes"] = existing_notes + scrobble.save(update_fields=["log"]) + logger.info( + "[todoist_scrobble_update_task] todoist note added", + extra={ + "todoist_note": todoist_note, + "user_id": user_id, + "media_type": Scrobble.MediaType.TASK, + }, + ) + + return scrobble + + def todoist_scrobble_task(todoist_task: dict, user_id: int) -> Scrobble: prefix = "" diff --git a/vrobbler/apps/tasks/models.py b/vrobbler/apps/tasks/models.py index 72181e6..e1236a3 100644 --- a/vrobbler/apps/tasks/models.py +++ b/vrobbler/apps/tasks/models.py @@ -24,6 +24,7 @@ class TaskLogData(LongPlayLogData): serial_scrobble_id: Optional[int] = None long_play_complete: Optional[bool] = None timestamp_utc: Optional[datetime] = None + notes: Optional[list[dict]] = None class Task(LongPlayScrobblableMixin): diff --git a/vrobbler/apps/tasks/todoist.py b/vrobbler/apps/tasks/todoist.py index 4a19725..262db80 100644 --- a/vrobbler/apps/tasks/todoist.py +++ b/vrobbler/apps/tasks/todoist.py @@ -30,17 +30,10 @@ def get_todoist_access_token(user_id: int, state: str, code: str): "[get_todoist_access_token] called", extra={"state": state, "code": code}, ) - user_profile = UserProfile.objects.filter(user_id=user_id).first() + user_profile = UserProfile.objects.filter(todoist_state=state).first() if not user_profile: - raise Exception - - if user_profile.todoist_state != state: - logger.info( - "[get_todoist_access_token] state mismatch", - extra={"user_id": user_id, "state": state}, - ) - raise Exception + raise Exception("Could not find profile") post_data = { "client_id": settings.TODOIST_CLIENT_ID, diff --git a/vrobbler/apps/tasks/webhooks.py b/vrobbler/apps/tasks/webhooks.py index 6e62847..246394a 100644 --- a/vrobbler/apps/tasks/webhooks.py +++ b/vrobbler/apps/tasks/webhooks.py @@ -9,6 +9,7 @@ from rest_framework.response import Response from scrobbles.scrobblers import ( todoist_scrobble_task, todoist_scrobble_task_finish, + todoist_scrobble_update_task, ) from profiles.models import UserProfile @@ -24,25 +25,44 @@ def todoist_webhook(request): "[todoist_webhook] called", extra={"post_data": post_data}, ) + todoist_task = {} + todoist_note = {} todoist_type, todoist_event = post_data.get("event_name").split(":") event_data = post_data.get("event_data", {}) - todoist_task = { - "todoist_id": event_data.get("id"), - "todoist_label_list": event_data.get("labels"), - "todoist_type": todoist_type, - "todoist_event": todoist_event, - "updated_at": event_data.get("updated_at"), - "todoist_project_id": event_data.get("project_id"), - "description": event_data.get("content"), - "details": event_data.get("description"), - } + is_item_type = todoist_type == "item" + is_note_type = todoist_type == "note" - is_not_item_type = todoist_task["todoist_type"] != "item" - is_not_updated = todoist_task["todoist_event"] not in ["updated"] + is_updated = todoist_event == ["updated"] + is_added = todoist_event == ["added"] - if is_not_item_type or is_not_updated: + if is_item_type: + todoist_task = { + "todoist_id": event_data.get("id"), + "todoist_label_list": event_data.get("labels"), + "todoist_type": todoist_type, + "todoist_event": todoist_event, + "updated_at": event_data.get("updated_at"), + "todoist_project_id": event_data.get("project_id"), + "description": event_data.get("content"), + "details": event_data.get("description"), + } + if is_note_type: + task_data = event_data.get("item", {}) + todoist_note = { + "todoist_id": task_data.get("id"), + "todoist_label_list": task_data.get("labels"), + "todoist_type": todoist_type, + "todoist_event": todoist_event, + "updated_at": task_data.get("updated_at"), + "details": task_data.get("description"), + "notes": event_data.get("content"), + "is_deleted": True + if event_data.get("is_deleted") == "true" + else False, + } + else: logger.info( - "[todoist_webhook] ignoring wrong todoist type or event", + "[todoist_webhook] ignoring wrong todoist type", extra={ "todoist_type": todoist_task["todoist_type"], "todoist_event": todoist_task["todoist_event"], @@ -55,13 +75,17 @@ def todoist_webhook(request): .first() .user_id ) - # TODO huge hack, find a way to populate user id from Todoist - scrobble = todoist_scrobble_task(todoist_task, user_id) + + if todoist_task and todoist_event == "updated": + scrobble = todoist_scrobble_task(todoist_task, user_id) + + if todoist_note and todoist_event == "added": + scrobble = todoist_scrobble_update_task(todoist_note, user_id) if not scrobble: return Response( {"error": "No scrobble found to be updated"}, - status=status.HTTP_400_BAD_REQUEST, + status=status.HTTP_304_NOT_MODIFIED, ) logger.info(