SciPost Code Repository

Skip to content
Snippets Groups Projects
Commit 40317d3a authored by George Katsikas's avatar George Katsikas :goat:
Browse files

add new task base objects

parent fa9eb328
No related branches found
No related tags found
No related merge requests found
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from abc import abstractmethod
from collections.abc import Callable, Collection
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
from django.db.models import Q, QuerySet
from django.template import Template, loader
from django.utils import timezone
if TYPE_CHECKING:
from django.contrib.auth.models import User
from tasks.tasks.task_action import TaskAction
@dataclass
class Task:
user: int
kind: "type[TaskKind]"
data: dict = field(default_factory=dict)
@property
def actions(self) -> Collection["TaskAction"]:
return [action(self) for action in self.kind.actions]
@property
def as_html(self) -> str:
return self.kind.template().render({"task": self})
@property
def title(self) -> str:
return self.kind.task_title.format(**self.data)
@property
def due_date(self) -> timezone.datetime:
return self.data.get("due_date", self.kind.get_default_due_date())
class TaskKind:
name: str
task_title: str
description: str = ""
actions: Collection[Callable[[Task], "TaskAction"]]
template_name: str = "tasks/task.html"
@staticmethod
@abstractmethod
def get_queryset() -> "QuerySet":
"""Return a queryset of task data from which Task instances are created."""
pass
@staticmethod
@abstractmethod
def search_query(text: str) -> Q:
"""Create a filter query for a given text."""
return Q()
@classmethod
def search(cls, text: str) -> "QuerySet":
"""Return a queryset of tasks that match the search text."""
search_query = cls.search_query(text)
return cls.get_queryset().filter(search_query)
@classmethod
def get_tasks(cls) -> Collection[Task]:
return [Task(user=1, kind=cls, data=data) for data in cls.get_task_data()]
@classmethod
def get_task_data(cls) -> Collection[dict]:
"""Maps the queryset to a collection of dictionaries to be used as task data."""
return [{"object": obj} for obj in cls.get_queryset()]
@classmethod
def template(cls) -> Template:
return loader.get_template(cls.template_name)
@staticmethod
@abstractmethod
def is_user_eligible(user: "User") -> bool:
return user.is_staff
@staticmethod
def get_default_due_date() -> timezone.datetime:
return timezone.now()
__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from collections.abc import Callable
from dataclasses import dataclass, field
from typing import Literal
from django.urls import reverse_lazy
from .task import Task
@dataclass
class TaskAction:
tag: Literal["a", "button"]
css_class: str = "btn"
content: str = ""
kwargs: dict = field(default_factory=dict)
@staticmethod
def attrs_str(attrs: dict) -> str:
return " ".join(f'{k}="{v}"' for k, v in attrs.items())
@property
def attrs(self) -> dict:
return self.kwargs.get("attrs", {})
@property
def as_html(self) -> str:
element = '<{tag} {attrs} class="{css_class}">{content}</{tag}>'
return element.format(
tag=self.tag,
attrs=self.attrs_str(self.attrs),
css_class=self.css_class,
content=self.content,
)
class ViewAction(TaskAction):
def __init__(self, url: str, content: str = "View"):
self.url = url
return super().__init__(
tag="a",
content=content,
kwargs={"attrs": {"href": self.url}},
)
@staticmethod
def default_builder(
reverse_url_str: str, content: str = "View"
) -> Callable[[Task], TaskAction]:
def action(task: Task) -> TaskAction:
return ViewAction(
reverse_lazy(reverse_url_str, kwargs={"pk": task.data["object"].pk}),
content,
)
return action
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment