Bladeren bron

[tasks] First try at adding an emacs webhook

Colin Powell 1 maand geleden
bovenliggende
commit
c871087496

+ 89 - 0
vrobbler/apps/scrobbles/scrobblers.py

@@ -500,6 +500,95 @@ def todoist_scrobble_task(
     return scrobble
 
 
+def emacs_scrobble_task(
+    task_data: dict,
+    user_id: int,
+    started: bool = False,
+    stopped: bool = False,
+) -> Scrobble | None:
+
+    prefix = ""
+    suffix = ""
+    source_id = task_data.get("source_id")
+    for label in task_data.get("labels"):
+        if label in TODOIST_TITLE_PREFIX_LABELS:
+            prefix = label
+        if label in TODOIST_TITLE_SUFFIX_LABELS:
+            suffix = label
+
+    if not prefix and 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()))
+    in_progress_scrobble = Scrobble.objects.filter(
+        user_id=user_id,
+        in_progress=True,
+        log__source_id=source_id,
+        log__source=task_data.get("source"),
+        task=task,
+    ).last()
+    print(in_progress_scrobble)
+
+    if not in_progress_scrobble and stopped:
+        logger.info(
+            "[emacs_scrobble_task] cannot stop already stopped task",
+            extra={
+                "emacs_id": source_id,
+            },
+        )
+        return
+
+    if in_progress_scrobble and started:
+        logger.info(
+            "[todoist_scrobble_task] cannot start already started task",
+            extra={
+                "emacs_id": source_id,
+            },
+        )
+        return in_progress_scrobble
+
+    # Finish an in-progress scrobble
+    if in_progress_scrobble and stopped:
+        logger.info(
+            "[emacs_scrobble_task] finishing",
+            extra={
+                "emacs_id": emacs_task["emacs_id"],
+            },
+        )
+        in_progress_scrobble.stop(timestamp=timestamp, force_finish=True)
+        return in_progress_scrobble
+
+    if in_progress_scrobble:
+        return in_progress_scrobble
+
+    scrobble_dict = {
+        "user_id": user_id,
+        "timestamp": timestamp,
+        "playback_position_seconds": 0,
+        "source": "Org-mode",
+        "log": task_data,
+    }
+
+    logger.info(
+        "[emacs_scrobble_task] creating",
+        extra={
+            "task_id": task.id,
+            "user_id": user_id,
+            "scrobble_dict": scrobble_dict,
+            "media_type": Scrobble.MediaType.TASK,
+        },
+    )
+    scrobble = Scrobble.create_or_update(task, user_id, scrobble_dict)
+    return scrobble
+
+
 def manual_scrobble_task(url: str, user_id: int, action: Optional[str] = None):
     source_id = re.findall(r"\d+", url)[0]
 

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

@@ -1,6 +1,6 @@
 from django.urls import path
 from scrobbles import views
-from tasks.webhooks import todoist_webhook
+from tasks.webhooks import todoist_webhook, emacs_webhook
 
 app_name = "scrobbles"
 
@@ -63,6 +63,13 @@ urlpatterns = [
         views.ScrobbleImportListView.as_view(),
         name="import-detail",
     ),
+    path("webhook/emacs/", emacs_webhook, name="emacs_webhook"),
+    path("export/", views.export, name="export"),
+    path(
+        "imports/",
+        views.ScrobbleImportListView.as_view(),
+        name="import-detail",
+    ),
     path(
         "imports/tsv/<slug:slug>/",
         views.ScrobbleTSVImportDetailView.as_view(),

+ 10 - 8
vrobbler/apps/scrobbles/views.py

@@ -525,6 +525,7 @@ def gps_webhook(request):
 
 
 @csrf_exempt
+@permission_classes([IsAuthenticated])
 @api_view(["POST"])
 def emacs_webhook(request):
     try:
@@ -539,18 +540,19 @@ def emacs_webhook(request):
             "user_id": 1,
         },
     )
+    data_dict["source"] = "orgmode"
+    data_dict["source_id"] = data_dict.pop("emacs_id")
 
-    # TODO Fix this so we have to authenticate!
-    user_id = 1
-    if request.user.id:
-        user_id = request.user.id
+    user_id = request.user.id
+    if not user_id:
+        user_id = 1
 
-    # scrobble = gpslogger_scrobble_location(data_dict, user_id)
+    scrobble = emacs_scrobble_task(data_dict, user_id)
 
-    # if not scrobble:
-    #    return Response({}, status=status.HTTP_200_OK)
+    if not scrobble:
+        return Response({"data": data_dict}, status=status.HTTP_200_OK)
 
-    return Response({"post_data": post_data}, status=status.HTTP_200_OK)
+    return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
 
 
 @csrf_exempt

+ 53 - 3
vrobbler/apps/tasks/webhooks.py

@@ -1,16 +1,16 @@
 import logging
 
-import pendulum
 from django.views.decorators.csrf import csrf_exempt
+from profiles.models import UserProfile
 from rest_framework import status
 from rest_framework.decorators import api_view, permission_classes
 from rest_framework.permissions import IsAuthenticated
 from rest_framework.response import Response
 from scrobbles.scrobblers import (
+    emacs_scrobble_task,
     todoist_scrobble_task,
     todoist_scrobble_update_task,
 )
-from profiles.models import UserProfile
 
 logger = logging.getLogger(__name__)
 
@@ -29,7 +29,7 @@ def todoist_webhook(request):
     todoist_type, todoist_event = post_data.get("event_name").split(":")
     event_data = post_data.get("event_data", {})
     is_item_type = todoist_type == "item"
-    is_note_type = todoist_type == "note"
+    is_note_type = todoist_tyllll = "note"
     new_labels = event_data.get("labels", [])
     old_labels = (
         post_data.get("event_data_extra", {})
@@ -118,3 +118,53 @@ def todoist_webhook(request):
         extra={"scrobble_id": scrobble.id},
     )
     return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
+
+
+@csrf_exempt
+@permission_classes([IsAuthenticated])
+@api_view(["POST"])
+def emacs_webhook(request):
+    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"
+
+    user_id = (
+        UserProfile.objects.filter(todoist_user_id=post_data.get("user_id"))
+        .first()
+        .user_id
+    )
+
+    scrobble = None
+    if emacs_task:
+        scrobble = emacs_scrobble_task(
+            emacs_task, user_id, stopped=task_stopped
+        )
+
+    if scrobble and task_started:
+        scrobble = emacs_scrobble_update_task(
+            emacs_task.get("notes"),
+            user_id,
+        )
+
+    if not scrobble:
+        logger.info(
+            "[todoist_webhook] finished with no note or task found",
+            extra={"scrobble_id": None},
+        )
+        return Response(
+            {"error": "No scrobble found to be updated"},
+            status=status.HTTP_304_NOT_MODIFIED,
+        )
+
+    logger.info(
+        "[todoist_webhook] finished",
+        extra={"scrobble_id": scrobble.id},
+    )
+    return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)