[tasks] Fix source url generation
This commit is contained in:
@ -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
|
||||||
|
|||||||
@ -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()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user