[tasks] Fix source url generation

This commit is contained in:
2024-09-30 17:10:28 -04:00
parent 183469ebe5
commit 3c0a75755b
5 changed files with 88 additions and 12 deletions

View File

@ -99,7 +99,7 @@ class BoardGameScoreLogData(JSONDataclass):
@dataclass @dataclass
class BoardGameLogData(LongPlayLogData): class BoardGameLogData(LongPlayLogData):
serial_scrobble_id: Optional[int] = None serial_scrobble_id: Optional[int] = None
long_play_complete: bool = False long_play_complete: Optional[bool] = None
players: Optional[list[BoardGameScoreLogData]] = None players: Optional[list[BoardGameScoreLogData]] = None
location: Optional[str] = None location: Optional[str] = None
geo_location_id: Optional[int] = None geo_location_id: Optional[int] = None

View File

@ -114,10 +114,24 @@ class LongPlayScrobblableMixin(ScrobblableMixin):
def get_longplay_finish_url(self): def get_longplay_finish_url(self):
return reverse("scrobbles:longplay-finish", kwargs={"uuid": self.uuid}) return reverse("scrobbles:longplay-finish", kwargs={"uuid": self.uuid})
def first_long_play_scrobble_for_user(self, user) -> Optional["Scrobble"]:
return (
get_scrobbles_for_media(self, user)
.filter(
log__long_play_complete=False,
log__serial_scrobble_id__isnull=True,
)
.order_by("timestamp")
.first()
)
def last_long_play_scrobble_for_user(self, user) -> Optional["Scrobble"]: def last_long_play_scrobble_for_user(self, user) -> Optional["Scrobble"]:
return ( return (
get_scrobbles_for_media(self, user) get_scrobbles_for_media(self, user)
.filter(long_play_complete=False) .filter(
.order_by("-timestamp") log__long_play_complete=False,
.first() log__serial_scrobble_id__isnull=False,
)
.order_by("timestamp")
.last()
) )

View File

@ -48,10 +48,14 @@ def get_scrobbles_for_media(media_obj, user: User) -> models.QuerySet:
media_query = models.Q(book=media_obj) media_query = models.Q(book=media_obj)
if media_class == "VideoGame": if media_class == "VideoGame":
media_query = models.Q(video_game=media_obj) media_query = models.Q(video_game=media_obj)
if media_class == "Brickset":
media_query = models.Q(brickset=media_obj)
if media_class == "Task":
media_query = models.Q(task=media_obj)
if not media_query: if not media_query:
logger.warn("Do not know about media {media_class} 🙍") logger.warn(f"Do not know about media {media_class} 🙍")
return [] return QuerySet()
return Scrobble.objects.filter(media_query, user=user) return Scrobble.objects.filter(media_query, user=user)

View File

@ -0,0 +1,31 @@
# Generated by Django 4.2.16 on 2024-09-30 20:46
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("tasks", "0001_initial"),
]
operations = [
migrations.AddField(
model_name="task",
name="source",
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name="task",
name="source_url_pattern",
field=models.CharField(
blank=True,
choices=[
("Shortcut", "https://app.shortcut.com/sure/story/{id}"),
("Todoist", "https://app.todoist.com/app/task/{id}"),
],
max_length=255,
null=True,
),
),
]

View File

@ -1,30 +1,43 @@
from dataclasses import dataclass
from enum import Enum from enum import Enum
from typing import Optional from typing import Optional
from django.apps import apps from django.apps import apps
from django.db import models from django.db import models
from django.urls import reverse from django.urls import reverse
from scrobbles.dataclasses import LongPlayLogData from scrobbles.dataclasses import LongPlayLogData
from scrobbles.mixins import ScrobblableMixin from scrobbles.mixins import LongPlayScrobblableMixin
BNULL = {"blank": True, "null": True} BNULL = {"blank": True, "null": True}
TASK_SOURCE_URL_PATTERNS = [
("https://app.shortcut.com/sure/story/{id}", "Shortcut"),
("https://app.todoist.com/app/task/{id}", "Todoist"),
]
@dataclass
class TaskLogData(LongPlayLogData): class TaskLogData(LongPlayLogData):
serial_scrobble_id: Optional[int] source_id: Optional[str] = None
long_play_complete: bool = False serial_scrobble_id: Optional[int] = None
long_play_complete: Optional[bool] = None
class TaskType(Enum): class TaskType(Enum):
WOODS = "Professional" PRO = "Professional"
ROAD = "Amateur" AMATEUR = "Amateur"
class Task(ScrobblableMixin): class Task(LongPlayScrobblableMixin):
"""Basically a holder for task sources ... Shortcut, JIRA, Todoist, Org-mode """Basically a holder for task sources ... Shortcut, JIRA, Todoist, Org-mode
and any other otherwise generic tasks. and any other otherwise generic tasks.
""" """
source = models.CharField(max_length=255, **BNULL)
source_url_pattern = models.CharField(
max_length=255, choices=TASK_SOURCE_URL_PATTERNS, **BNULL
)
description = models.TextField(**BNULL) description = models.TextField(**BNULL)
def __str__(self): def __str__(self):
@ -37,6 +50,20 @@ class Task(ScrobblableMixin):
def logdata_cls(self): def logdata_cls(self):
return TaskLogData return TaskLogData
def source_url_for_user(self, user_id):
url = str(self.source_url_pattern).replace("{id}", "")
scrobble = self.scrobbles(user_id).first()
if scrobble.logdata.source_id and self.source_url_pattern:
url = str(self.source_url_pattern).format(
id=scrobble.logdata.source_id
)
return url
def subtitle_for_user(self, user_id):
scrobble = self.scrobbles(user_id).first()
return scrobble.logdata.source_id or ""
@classmethod @classmethod
def find_or_create(cls, title: str) -> "Task": def find_or_create(cls, title: str) -> "Task":
return cls.objects.filter(title=title).first() return cls.objects.filter(title=title).first()