Compare commits

...

8 Commits
17.0 ... 17.2

Author SHA1 Message Date
125da84f4e [tasks] Fix emacs scrobbling of tasks 2025-06-27 11:32:09 -04:00
36ceb4c7fe [release] 17.1 2025-06-27 10:52:50 -04:00
88a3831975 [tasks] Make tasks use user profile string 2025-06-27 10:48:05 -04:00
63361964ca [tasks] Add optional user context labels to get title 2025-06-27 10:37:09 -04:00
40b54b27f4 [tasks] Actually add the new utils file 2025-06-26 14:50:11 -04:00
a7eca4b9a7 [tasks] Actually get title consistently 2025-06-26 14:09:17 -04:00
d152412e99 [books] Add optional details key to log data for books 2025-06-25 10:21:26 -04:00
3ba6c6b6e4 [project] Add new bug in tasks
Though honestly, it will probably be a config setting in the Emacs hook,
but we'll see. Actually, maybe the emacs hook code should end up in this
repo somewhere 🤔
2025-06-24 14:25:20 -04:00
7 changed files with 53 additions and 64 deletions

View File

@ -1,6 +1,7 @@
#+title: TODOs
* Backlog [6/23]
* Backlog [0/17]
** TODO [#A] Tasks from org-mode should properlly update notes and leave them out of the body :vrobbler:bug:tasks:
** TODO [#A] Fix small bug in views for TV series where next episode is now None :vrobbler:bug:personal:videos:
#+begin_src python
@ -47,7 +48,6 @@ Would be nice to have some loose connection to the actual event in my Garmin pro
Could be as simple as a JSON form on the scrobble detail page (do I have have one of those yet?).
** TODO [#B] Explore a good way to show notes and descriptions from scrobbles to users :personal:project:scrobbling:vrobbler:spike:
** TODO [#B] Add webdav syncing to retroarch imports :vrobbler:videogames:webdav:feature:project:personal:
** TODO [#B] Fix task app to only use one tag for the context a task was done in and allow configurable contexts by user profile :personal:vrobbler:feature:tasks:project:
** TODO [#B] Add CSV endpoint for book scrobbles that LibraryThing can ingest :personal:project:books:feature:export:
https://app.todoist.com/app/task/add-a-csv-endpoint-for-users-book-reads-that-library-thing-can-ingest-6X7QPMRp265xMXqg#comment-6X7QrXq6gJjMP4hg
** TODO [#C] Fix bug where podcast scrobbling creates duplicate Podcast :project:vrobbler:scrobbling:podcasts:bug:personal:
@ -352,8 +352,13 @@ it's annoying.
** TODO [#C] User should be able to enable auto trail tracking via amail reader with Garmin LiveTrack URLs :vrobbler:trails:project:feature:personal:
** TODO [#C] Allow users to see tasks on calendar view :vrobbler:personal:project:templates:feature:
https://codepen.io/oliviale/pen/QYqybo
** TODO [#C] Come pu with a possible flow using WebDAV and super-productivity for tasks :personal:feature:project:vrobbler:tasks:
* Version 17.0
** TODO [#C] Come up with a possible flow using WebDAV and super-productivity for tasks :personal:feature:project:vrobbler:tasks:
* Version 17.1 [1/1]
** DONE [#B] Fix task app to only use one tag for the context a task was done in and allow configurable contexts by user profile :personal:vrobbler:feature:tasks:project:
:PROPERTIES:
:ID: 1ec89c57-0bb8-3401-33bd-ba65127ed36b
:END:
* Version 17.0 [6/6]
** DONE [#A] Fix bug in new task label lookup for Emacs/Org-mode :vrobbler:bug:tasks:
:PROPERTIES:
:ID: 683fb109-dfc4-85e4-80f0-ea618434f61e

View File

@ -56,7 +56,7 @@ class UserProfile(TimeStampedModel):
return pytz.timezone(self.timezone)
@cached_property
def task_context_tags(self) -> list:
def task_context_tags(self) -> list[str]:
tag_list = [
t.strip().capitalize()
for t in self.task_context_tags_str.split(",")

View File

@ -135,6 +135,7 @@ class BookLogData(LongPlayLogData):
page_start: Optional[int] = None
page_end: Optional[int] = None
serial_scrobble_id: Optional[int] = None
details: Optional[str] = None
@dataclass

View File

@ -31,12 +31,9 @@ from tasks.models import Task
from videogames.howlongtobeat import lookup_game_from_hltb
from videogames.models import VideoGame
from videos.models import Video
from tasks.utils import get_title_from_labels
from webpages.models import WebPage
from vrobbler.apps.tasks.constants import (
TODOIST_TITLE_LABELS
)
logger = logging.getLogger(__name__)
@ -412,23 +409,9 @@ def todoist_scrobble_task(
user_id: int,
started: bool = False,
stopped: bool = False,
context_list: list[str] = [],
) -> Scrobble:
prefix = ""
suffix = ""
# TODO look up the user profile and instead of checking PREFIX/SUFFIX, check against
# user.profile.task_context_tags which will result in context-based tag titles
# We'd also have to migrate existing tasks to the new context based ones (maybe)
for label in todoist_task["todoist_label_list"]:
if label in TODOIST_TITLE_LABELS:
title = label
if not prefix and suffix:
logger.warning(
"Missing a prefix and suffix tag for task",
extra={"todoist_scrobble_task": todoist_task},
)
title = get_title_from_labels(todoist_task.get("todoist_label_list", []), context_list)
task = Task.find_or_create(title)
timestamp = pendulum.parse(todoist_task.get("updated_at", timezone.now()))
@ -550,23 +533,11 @@ def emacs_scrobble_task(
user_id: int,
started: bool = False,
stopped: bool = False,
context_list: list[str] = [],
) -> Scrobble | None:
prefix = ""
suffix = ""
source_id = task_data.get("source_id")
for label in task_data.get("labels", []):
if label in TODOIST_TITLE_LABELS:
title = label
title = get_title_from_labels(task_data.get("labels", []), context_list)
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()))

View File

@ -1,15 +0,0 @@
TODOIST_TITLE_LABELS = [
"bug",
"feature",
"errand",
"chore",
"admin",
"computer",
"farm",
"baking",
"meeting",
"habit",
"research",
"exercise",
"lifeevent",
]

View File

@ -0,0 +1,20 @@
import logging
from django.conf import settings
logger = logging.getLogger(__name__)
def get_title_from_labels(labels: list[str], user_context_labels: list[str] = []) -> str:
title = "Unknown"
task_context_labels: list = user_context_labels or settings.DEFAULT_TASK_CONTEXT_TAG_LIST
for label in labels:
# TODO We may also want to take a user list of labels instead
if label in task_context_labels:
title = label.capitalize()
if title == "Unknown":
logger.warning(
"Missing a prefix and suffix tag for task",
extra={"labels": labels},
)
return title

View File

@ -71,9 +71,9 @@ def todoist_webhook(request):
"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,
"is_deleted": (
True if event_data.get("is_deleted") == "true" else False
),
}
if (is_added and not todoist_note) or (is_updated and not todoist_task):
@ -90,16 +90,17 @@ def todoist_webhook(request):
)
return Response({}, status=status.HTTP_304_NOT_MODIFIED)
user_id = (
UserProfile.objects.filter(todoist_user_id=post_data.get("user_id"))
.first()
.user_id
)
user_profile = UserProfile.objects.filter(
todoist_user_id=post_data.get("user_id", None)
).first()
scrobble = None
if todoist_task:
scrobble = todoist_scrobble_task(
todoist_task, user_id, stopped=task_stopped
todoist_task,
user_profile.user_id,
stopped=task_stopped,
context_list=user_profile.task_context_tags,
)
if todoist_note:
@ -143,10 +144,16 @@ def emacs_webhook(request):
if not user_id:
user_id = 1
user_profile = UserProfile.objects.filter(user_id=user_id)
scrobble = None
if post_data.get("source_id"):
scrobble = emacs_scrobble_task(
post_data, user_id, started=task_in_progress, stopped=task_stopped
post_data,
user_id,
started=task_in_progress,
stopped=task_stopped,
context_list=user_profile.task_context_tags,
)
if not scrobble: