Browse Source

[tasks] Fix updating and stopping tasks from Emacs

Colin Powell 1 month ago
parent
commit
70378c9968

+ 62 - 6
vrobbler/apps/scrobbles/scrobblers.py

@@ -500,6 +500,55 @@ def todoist_scrobble_task(
     return scrobble
 
 
+def emacs_scrobble_update_task(
+    emacs_id: str, emacs_notes: dict, user_id: int
+) -> Optional[Scrobble]:
+    scrobble = Scrobble.objects.filter(
+        in_progress=True,
+        user_id=user_id,
+        log__source_id=emacs_id,
+        log__source="emacs",
+    ).first()
+
+    if not scrobble:
+        logger.info(
+            "[emacs_scrobble_update_task] no task found",
+            extra={
+                "emacs_notes": emacs_notes,
+                "user_id": user_id,
+                "media_type": Scrobble.MediaType.TASK,
+            },
+        )
+        return
+
+    notes_updated = False
+    for note in emacs_notes:
+        existing_note_ts = [
+            n.get("timestamp") for n in scrobble.log.get("notes", [])
+        ]
+        if not scrobble.log.get('notes"'):
+            scrobble.log["notes"] = []
+        if note.get("timestamp") not in existing_note_ts:
+            scrobble.log["notes"].append(
+                {note.get("timestamp"): note.get("content")}
+            )
+            notes_updated = True
+
+    if notes_updated:
+        scrobble.save(update_fields=["log"])
+
+        logger.info(
+            "[emacs_scrobble_update_task] emacs note added",
+            extra={
+                "emacs_note": emacs_notes,
+                "user_id": user_id,
+                "media_type": Scrobble.MediaType.TASK,
+            },
+        )
+
+    return scrobble
+
+
 def emacs_scrobble_task(
     task_data: dict,
     user_id: int,
@@ -509,6 +558,7 @@ def emacs_scrobble_task(
 
     prefix = ""
     suffix = ""
+
     source_id = task_data.get("source_id")
     for label in task_data.get("labels"):
         if label in TODOIST_TITLE_PREFIX_LABELS:
@@ -516,14 +566,13 @@ def emacs_scrobble_task(
         if label in TODOIST_TITLE_SUFFIX_LABELS:
             suffix = label
 
-    if not prefix and suffix:
+    if not prefix and not suffix:
         logger.warning(
             "Missing a prefix and suffix tag for task",
             extra={"emacs_scrobble_task": task_data},
         )
 
     title = " ".join([prefix.capitalize(), suffix.capitalize()])
-
     task = Task.find_or_create(title)
 
     timestamp = pendulum.parse(task_data.get("updated_at", timezone.now()))
@@ -531,10 +580,9 @@ def emacs_scrobble_task(
         user_id=user_id,
         in_progress=True,
         log__source_id=source_id,
-        log__source=task_data.get("source"),
+        log__source="emacs",
         task=task,
     ).last()
-    print(in_progress_scrobble)
 
     if not in_progress_scrobble and stopped:
         logger.info(
@@ -547,7 +595,7 @@ def emacs_scrobble_task(
 
     if in_progress_scrobble and started:
         logger.info(
-            "[todoist_scrobble_task] cannot start already started task",
+            "[emacs_scrobble_task] cannot start already started task",
             extra={
                 "emacs_id": source_id,
             },
@@ -559,7 +607,7 @@ def emacs_scrobble_task(
         logger.info(
             "[emacs_scrobble_task] finishing",
             extra={
-                "emacs_id": emacs_task["emacs_id"],
+                "emacs_id": source_id,
             },
         )
         in_progress_scrobble.stop(timestamp=timestamp, force_finish=True)
@@ -568,6 +616,14 @@ def emacs_scrobble_task(
     if in_progress_scrobble:
         return in_progress_scrobble
 
+    notes = task_data.pop("notes")
+    if notes:
+        task_data["notes"] = []
+        for note in notes:
+            task_data["notes"].append(
+                {note.get("timestamp"): note.get("content")}
+            )
+
     scrobble_dict = {
         "user_id": user_id,
         "timestamp": timestamp,

+ 1 - 6
vrobbler/apps/scrobbles/urls.py

@@ -36,11 +36,6 @@ urlpatterns = [
         views.web_scrobbler_webhook,
         name="web-scrobbler-webhook",
     ),
-    path(
-        "webhook/emacs/",
-        views.emacs_webhook,
-        name="emacs-webhook",
-    ),
     path(
         "webhook/gps/",
         views.gps_webhook,
@@ -57,13 +52,13 @@ urlpatterns = [
         name="mopidy-webhook",
     ),
     path("webhook/todoist/", todoist_webhook, name="todoist-webhook"),
+    path("webhook/emacs/", emacs_webhook, name="emacs_webhook"),
     path("export/", views.export, name="export"),
     path(
         "imports/",
         views.ScrobbleImportListView.as_view(),
         name="import-detail",
     ),
-    path("webhook/emacs/", emacs_webhook, name="emacs_webhook"),
     path("export/", views.export, name="export"),
     path(
         "imports/",

+ 0 - 31
vrobbler/apps/scrobbles/views.py

@@ -524,37 +524,6 @@ def gps_webhook(request):
     return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
 
 
-@csrf_exempt
-@permission_classes([IsAuthenticated])
-@api_view(["POST"])
-def emacs_webhook(request):
-    try:
-        data_dict = json.loads(request.data)
-    except TypeError:
-        data_dict = request.data
-
-    logger.info(
-        "[emacs_webhook] called",
-        extra={
-            "post_data": data_dict,
-            "user_id": 1,
-        },
-    )
-    data_dict["source"] = "orgmode"
-    data_dict["source_id"] = data_dict.pop("emacs_id")
-
-    user_id = request.user.id
-    if not user_id:
-        user_id = 1
-
-    scrobble = emacs_scrobble_task(data_dict, user_id)
-
-    if not scrobble:
-        return Response({"data": data_dict}, status=status.HTTP_200_OK)
-
-    return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
-
-
 @csrf_exempt
 @permission_classes([IsAuthenticated])
 @api_view(["POST"])

+ 2 - 1
vrobbler/apps/tasks/models.py

@@ -50,7 +50,8 @@ class Task(LongPlayScrobblableMixin):
         url = ""
         scrobble = self.scrobbles(user_id).first()
         if scrobble:
-            url = TODOIST_TASK_URL.format(id=scrobble.logdata.todoist_id)
+            if scrobble.log.get("source") == "todoist":
+                url = TODOIST_TASK_URL.format(id=scrobble.logdata.todist_id)
         return url
 
     def subtitle_for_user(self, user_id):

+ 28 - 20
vrobbler/apps/tasks/webhooks.py

@@ -1,3 +1,4 @@
+import json
 import logging
 
 from django.views.decorators.csrf import csrf_exempt
@@ -8,6 +9,7 @@ from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from scrobbles.scrobblers import (
     emacs_scrobble_task,
+    emacs_scrobble_update_task,
     todoist_scrobble_task,
     todoist_scrobble_update_task,
 )
@@ -124,38 +126,44 @@ def todoist_webhook(request):
 @permission_classes([IsAuthenticated])
 @api_view(["POST"])
 def emacs_webhook(request):
-    post_data = request.data
+    try:
+        post_data = json.loads(request.data)
+    except TypeError:
+        post_data = request.data
     logger.info(
         "[emacs_webhook] called",
         extra={"post_data": post_data},
     )
-    print(post_data)
-    emacs_task = post_data
-
-    task_started = emacs_task.get("state") == "STRT"
-    task_stopped = emacs_task.get("state") == "DONE"
+    task_in_progress = post_data.get("state") == "STRT"
+    task_stopped = post_data.get("state") == "DONE"
+    post_data["source_id"] = post_data.pop("emacs_id")
 
-    user_id = (
-        UserProfile.objects.filter(todoist_user_id=post_data.get("user_id"))
-        .first()
-        .user_id
-    )
+    # TODO: Figure out why token auth is not working
+    user_id = request.user.id
+    if not user_id:
+        user_id = 1
 
     scrobble = None
-    if emacs_task:
+    if post_data.get("source_id"):
         scrobble = emacs_scrobble_task(
-            emacs_task, user_id, stopped=task_stopped
+            post_data, user_id, started=task_in_progress, stopped=task_stopped
         )
 
-    if scrobble and task_started:
-        scrobble = emacs_scrobble_update_task(
-            emacs_task.get("notes"),
-            user_id,
-        )
+    if scrobble and task_in_progress:
+        if post_data.get("notes"):
+            scrobble = emacs_scrobble_update_task(
+                post_data.get("source_id"),
+                post_data.get("notes"),
+                user_id,
+            )
+        if scrobble:
+            return Response(
+                {"scrobble_id": scrobble.id}, status=status.HTTP_200_OK
+            )
 
     if not scrobble:
         logger.info(
-            "[todoist_webhook] finished with no note or task found",
+            "[emacs_webhook] finished with no note or task found",
             extra={"scrobble_id": None},
         )
         return Response(
@@ -164,7 +172,7 @@ def emacs_webhook(request):
         )
 
     logger.info(
-        "[todoist_webhook] finished",
+        "[emacs_webhook] finished",
         extra={"scrobble_id": scrobble.id},
     )
     return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)

+ 1 - 0
vrobbler/templates/tasks/task_detail.html

@@ -62,6 +62,7 @@
                         <td>{{scrobble.timestamp}}</td>
                         <td><a href="{{scrobble.get_media_source_url}}">{{scrobble.logdata.description}}</a></td>
                         <td>{{scrobble.source}}</td>
+                        <td>{{scrobble.log.notes}}</td>
                     </tr>
                     {% endfor %}
                 </tbody>