[tasks] Fix updating and stopping tasks from Emacs
This commit is contained in:
@ -500,6 +500,55 @@ def todoist_scrobble_task(
|
|||||||
return scrobble
|
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(
|
def emacs_scrobble_task(
|
||||||
task_data: dict,
|
task_data: dict,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
@ -509,6 +558,7 @@ def emacs_scrobble_task(
|
|||||||
|
|
||||||
prefix = ""
|
prefix = ""
|
||||||
suffix = ""
|
suffix = ""
|
||||||
|
|
||||||
source_id = task_data.get("source_id")
|
source_id = task_data.get("source_id")
|
||||||
for label in task_data.get("labels"):
|
for label in task_data.get("labels"):
|
||||||
if label in TODOIST_TITLE_PREFIX_LABELS:
|
if label in TODOIST_TITLE_PREFIX_LABELS:
|
||||||
@ -516,14 +566,13 @@ def emacs_scrobble_task(
|
|||||||
if label in TODOIST_TITLE_SUFFIX_LABELS:
|
if label in TODOIST_TITLE_SUFFIX_LABELS:
|
||||||
suffix = label
|
suffix = label
|
||||||
|
|
||||||
if not prefix and suffix:
|
if not prefix and not suffix:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Missing a prefix and suffix tag for task",
|
"Missing a prefix and suffix tag for task",
|
||||||
extra={"emacs_scrobble_task": task_data},
|
extra={"emacs_scrobble_task": task_data},
|
||||||
)
|
)
|
||||||
|
|
||||||
title = " ".join([prefix.capitalize(), suffix.capitalize()])
|
title = " ".join([prefix.capitalize(), suffix.capitalize()])
|
||||||
|
|
||||||
task = Task.find_or_create(title)
|
task = Task.find_or_create(title)
|
||||||
|
|
||||||
timestamp = pendulum.parse(task_data.get("updated_at", timezone.now()))
|
timestamp = pendulum.parse(task_data.get("updated_at", timezone.now()))
|
||||||
@ -531,10 +580,9 @@ def emacs_scrobble_task(
|
|||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
in_progress=True,
|
in_progress=True,
|
||||||
log__source_id=source_id,
|
log__source_id=source_id,
|
||||||
log__source=task_data.get("source"),
|
log__source="emacs",
|
||||||
task=task,
|
task=task,
|
||||||
).last()
|
).last()
|
||||||
print(in_progress_scrobble)
|
|
||||||
|
|
||||||
if not in_progress_scrobble and stopped:
|
if not in_progress_scrobble and stopped:
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -547,7 +595,7 @@ def emacs_scrobble_task(
|
|||||||
|
|
||||||
if in_progress_scrobble and started:
|
if in_progress_scrobble and started:
|
||||||
logger.info(
|
logger.info(
|
||||||
"[todoist_scrobble_task] cannot start already started task",
|
"[emacs_scrobble_task] cannot start already started task",
|
||||||
extra={
|
extra={
|
||||||
"emacs_id": source_id,
|
"emacs_id": source_id,
|
||||||
},
|
},
|
||||||
@ -559,7 +607,7 @@ def emacs_scrobble_task(
|
|||||||
logger.info(
|
logger.info(
|
||||||
"[emacs_scrobble_task] finishing",
|
"[emacs_scrobble_task] finishing",
|
||||||
extra={
|
extra={
|
||||||
"emacs_id": emacs_task["emacs_id"],
|
"emacs_id": source_id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
in_progress_scrobble.stop(timestamp=timestamp, force_finish=True)
|
in_progress_scrobble.stop(timestamp=timestamp, force_finish=True)
|
||||||
@ -568,6 +616,14 @@ def emacs_scrobble_task(
|
|||||||
if in_progress_scrobble:
|
if in_progress_scrobble:
|
||||||
return 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 = {
|
scrobble_dict = {
|
||||||
"user_id": user_id,
|
"user_id": user_id,
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
|
|||||||
@ -36,11 +36,6 @@ urlpatterns = [
|
|||||||
views.web_scrobbler_webhook,
|
views.web_scrobbler_webhook,
|
||||||
name="web-scrobbler-webhook",
|
name="web-scrobbler-webhook",
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"webhook/emacs/",
|
|
||||||
views.emacs_webhook,
|
|
||||||
name="emacs-webhook",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"webhook/gps/",
|
"webhook/gps/",
|
||||||
views.gps_webhook,
|
views.gps_webhook,
|
||||||
@ -57,13 +52,13 @@ urlpatterns = [
|
|||||||
name="mopidy-webhook",
|
name="mopidy-webhook",
|
||||||
),
|
),
|
||||||
path("webhook/todoist/", todoist_webhook, name="todoist-webhook"),
|
path("webhook/todoist/", todoist_webhook, name="todoist-webhook"),
|
||||||
|
path("webhook/emacs/", emacs_webhook, name="emacs_webhook"),
|
||||||
path("export/", views.export, name="export"),
|
path("export/", views.export, name="export"),
|
||||||
path(
|
path(
|
||||||
"imports/",
|
"imports/",
|
||||||
views.ScrobbleImportListView.as_view(),
|
views.ScrobbleImportListView.as_view(),
|
||||||
name="import-detail",
|
name="import-detail",
|
||||||
),
|
),
|
||||||
path("webhook/emacs/", emacs_webhook, name="emacs_webhook"),
|
|
||||||
path("export/", views.export, name="export"),
|
path("export/", views.export, name="export"),
|
||||||
path(
|
path(
|
||||||
"imports/",
|
"imports/",
|
||||||
|
|||||||
@ -524,37 +524,6 @@ def gps_webhook(request):
|
|||||||
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
|
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
|
@csrf_exempt
|
||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
@api_view(["POST"])
|
@api_view(["POST"])
|
||||||
|
|||||||
@ -50,7 +50,8 @@ class Task(LongPlayScrobblableMixin):
|
|||||||
url = ""
|
url = ""
|
||||||
scrobble = self.scrobbles(user_id).first()
|
scrobble = self.scrobbles(user_id).first()
|
||||||
if scrobble:
|
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
|
return url
|
||||||
|
|
||||||
def subtitle_for_user(self, user_id):
|
def subtitle_for_user(self, user_id):
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
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 rest_framework.response import Response
|
||||||
from scrobbles.scrobblers import (
|
from scrobbles.scrobblers import (
|
||||||
emacs_scrobble_task,
|
emacs_scrobble_task,
|
||||||
|
emacs_scrobble_update_task,
|
||||||
todoist_scrobble_task,
|
todoist_scrobble_task,
|
||||||
todoist_scrobble_update_task,
|
todoist_scrobble_update_task,
|
||||||
)
|
)
|
||||||
@ -124,38 +126,44 @@ def todoist_webhook(request):
|
|||||||
@permission_classes([IsAuthenticated])
|
@permission_classes([IsAuthenticated])
|
||||||
@api_view(["POST"])
|
@api_view(["POST"])
|
||||||
def emacs_webhook(request):
|
def emacs_webhook(request):
|
||||||
post_data = request.data
|
try:
|
||||||
|
post_data = json.loads(request.data)
|
||||||
|
except TypeError:
|
||||||
|
post_data = request.data
|
||||||
logger.info(
|
logger.info(
|
||||||
"[emacs_webhook] called",
|
"[emacs_webhook] called",
|
||||||
extra={"post_data": post_data},
|
extra={"post_data": post_data},
|
||||||
)
|
)
|
||||||
print(post_data)
|
task_in_progress = post_data.get("state") == "STRT"
|
||||||
emacs_task = post_data
|
task_stopped = post_data.get("state") == "DONE"
|
||||||
|
post_data["source_id"] = post_data.pop("emacs_id")
|
||||||
|
|
||||||
task_started = emacs_task.get("state") == "STRT"
|
# TODO: Figure out why token auth is not working
|
||||||
task_stopped = emacs_task.get("state") == "DONE"
|
user_id = request.user.id
|
||||||
|
if not user_id:
|
||||||
user_id = (
|
user_id = 1
|
||||||
UserProfile.objects.filter(todoist_user_id=post_data.get("user_id"))
|
|
||||||
.first()
|
|
||||||
.user_id
|
|
||||||
)
|
|
||||||
|
|
||||||
scrobble = None
|
scrobble = None
|
||||||
if emacs_task:
|
if post_data.get("source_id"):
|
||||||
scrobble = emacs_scrobble_task(
|
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:
|
if scrobble and task_in_progress:
|
||||||
scrobble = emacs_scrobble_update_task(
|
if post_data.get("notes"):
|
||||||
emacs_task.get("notes"),
|
scrobble = emacs_scrobble_update_task(
|
||||||
user_id,
|
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:
|
if not scrobble:
|
||||||
logger.info(
|
logger.info(
|
||||||
"[todoist_webhook] finished with no note or task found",
|
"[emacs_webhook] finished with no note or task found",
|
||||||
extra={"scrobble_id": None},
|
extra={"scrobble_id": None},
|
||||||
)
|
)
|
||||||
return Response(
|
return Response(
|
||||||
@ -164,7 +172,7 @@ def emacs_webhook(request):
|
|||||||
)
|
)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"[todoist_webhook] finished",
|
"[emacs_webhook] finished",
|
||||||
extra={"scrobble_id": scrobble.id},
|
extra={"scrobble_id": scrobble.id},
|
||||||
)
|
)
|
||||||
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
|
return Response({"scrobble_id": scrobble.id}, status=status.HTTP_200_OK)
|
||||||
|
|||||||
@ -62,6 +62,7 @@
|
|||||||
<td>{{scrobble.timestamp}}</td>
|
<td>{{scrobble.timestamp}}</td>
|
||||||
<td><a href="{{scrobble.get_media_source_url}}">{{scrobble.logdata.description}}</a></td>
|
<td><a href="{{scrobble.get_media_source_url}}">{{scrobble.logdata.description}}</a></td>
|
||||||
<td>{{scrobble.source}}</td>
|
<td>{{scrobble.source}}</td>
|
||||||
|
<td>{{scrobble.log.notes}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user