Browse Source

[tasks] Fix source url generation

Colin Powell 9 months ago
parent
commit
3c0a75755b

+ 1 - 1
vrobbler/apps/scrobbles/dataclasses.py

@@ -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

+ 17 - 3
vrobbler/apps/scrobbles/mixins.py

@@ -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 last_long_play_scrobble_for_user(self, user) -> Optional["Scrobble"]:
+    def first_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)
-            .order_by("-timestamp")
+            .filter(
+                log__long_play_complete=False,
+                log__serial_scrobble_id__isnull=True,
+            )
+            .order_by("timestamp")
             .first()
             .first()
         )
         )
+
+    def last_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=False,
+            )
+            .order_by("timestamp")
+            .last()
+        )

+ 6 - 2
vrobbler/apps/scrobbles/utils.py

@@ -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} 🙍")
-        return []
+        logger.warn(f"Do not know about media {media_class} 🙍")
+        return QuerySet()
     return Scrobble.objects.filter(media_query, user=user)
     return Scrobble.objects.filter(media_query, user=user)
 
 
 
 

+ 31 - 0
vrobbler/apps/tasks/migrations/0002_task_source_task_source_url_pattern.py

@@ -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,
+            ),
+        ),
+    ]

+ 33 - 6
vrobbler/apps/tasks/models.py

@@ -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]
-    long_play_complete: bool = False
+    source_id: Optional[str] = None
+    serial_scrobble_id: Optional[int] = None
+    long_play_complete: Optional[bool] = None
 
 
 
 
 class TaskType(Enum):
 class TaskType(Enum):
-    WOODS = "Professional"
-    ROAD = "Amateur"
+    PRO = "Professional"
+    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()