lib.itmens/catalog/performance/models.py

414 lines
11 KiB
Python
Raw Normal View History

2023-06-05 17:22:34 -04:00
from functools import cached_property
2024-05-27 15:44:12 -04:00
from typing import TYPE_CHECKING
2023-01-05 03:06:13 -05:00
from django.db import models
from django.utils.translation import gettext_lazy as _
from ninja import Schema
2024-03-10 20:55:50 -04:00
from catalog.common import (
ExternalResource,
IdType,
Item,
ItemCategory,
ItemSchema,
ItemType,
jsondata,
)
2023-06-05 02:04:52 -04:00
from catalog.common.utils import DEFAULT_ITEM_COVER
2023-06-06 13:21:27 -04:00
class CrewMemberSchema(Schema):
name: str
role: str | None
class PerformanceSchema(ItemSchema):
orig_title: str | None = None
other_title: list[str]
genre: list[str]
language: list[str]
opening_date: str | None = None
closing_date: str | None = None
director: list[str]
playwright: list[str]
orig_creator: list[str]
composer: list[str]
choreographer: list[str]
performer: list[str]
actor: list[CrewMemberSchema]
crew: list[CrewMemberSchema]
official_site: str | None = None
class PerformanceProductionSchema(ItemSchema):
orig_title: str | None = None
other_title: list[str]
language: list[str]
opening_date: str | None = None
closing_date: str | None = None
director: list[str]
playwright: list[str]
orig_creator: list[str]
composer: list[str]
choreographer: list[str]
performer: list[str]
actor: list[CrewMemberSchema]
crew: list[CrewMemberSchema]
official_site: str | None = None
2023-06-05 17:22:34 -04:00
_CREW_SCHEMA = {
"type": "list",
"items": {
"type": "dict",
"keys": {
2024-03-10 20:55:50 -04:00
"name": {"type": "string", "title": _("name")},
"role": {"type": "string", "title": _("role")},
2023-06-05 17:22:34 -04:00
},
"required": ["role", "name"],
},
"uniqueItems": True,
}
_ACTOR_SCHEMA = {
"type": "list",
"items": {
"type": "dict",
"keys": {
2024-03-10 20:55:50 -04:00
"name": {
"type": "string",
"title": _("name"),
"placeholder": _("required"),
},
"role": {
"type": "string",
"title": _("role"),
"placeholder": _("optional"),
},
2023-06-05 17:22:34 -04:00
},
"required": ["name"],
},
"uniqueItems": True,
}
2023-06-05 20:20:20 -04:00
def _crew_by_role(crew):
roles = set([c["role"] for c in crew if c.get("role")])
r = {key: [] for key in roles}
for c in crew:
r[c["role"]].append(c["name"])
return r
class Performance(Item):
2024-05-27 15:44:12 -04:00
if TYPE_CHECKING:
productions: models.QuerySet["PerformanceProduction"]
2023-06-05 02:04:52 -04:00
type = ItemType.Performance
2023-06-05 18:57:52 -04:00
child_class = "PerformanceProduction"
2022-12-11 23:20:28 +00:00
category = ItemCategory.Performance
2022-12-29 23:57:02 -05:00
url_path = "performance"
2023-06-05 02:04:52 -04:00
orig_title = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("original name"), blank=True, default="", max_length=500
2023-06-05 02:04:52 -04:00
)
2023-02-15 23:45:12 -05:00
other_title = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("other title"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=200),
2023-02-15 23:45:12 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-02-15 23:45:12 -05:00
default=list,
)
genre = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("genre"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=200),
2023-06-05 11:45:57 -04:00
null=False,
blank=False,
2023-02-15 23:45:12 -05:00
default=list,
)
2023-06-05 02:04:52 -04:00
language = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("language"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=200),
2023-01-05 03:06:13 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-01-05 03:06:13 -05:00
default=list,
)
2023-02-15 23:45:12 -05:00
director = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("director"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-01-05 03:06:13 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-01-05 03:06:13 -05:00
default=list,
)
2023-02-15 23:45:12 -05:00
playwright = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("playwright"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-01-05 03:06:13 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-01-05 03:06:13 -05:00
default=list,
)
2023-06-05 14:00:09 -04:00
orig_creator = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("original creator"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 14:00:09 -04:00
null=False,
blank=True,
default=list,
)
2023-02-15 23:45:12 -05:00
composer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("composer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-02-15 23:45:12 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-02-15 23:45:12 -05:00
default=list,
)
choreographer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("choreographer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-02-15 23:45:12 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
default=list,
)
2023-06-05 17:22:34 -04:00
actor = jsondata.JSONField(
2024-03-10 20:55:50 -04:00
verbose_name=_("actor"),
2023-06-05 17:22:34 -04:00
null=False,
blank=True,
default=list,
schema=_ACTOR_SCHEMA,
)
performer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("performer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 11:45:57 -04:00
null=False,
blank=True,
2023-02-15 23:45:12 -05:00
default=list,
)
troupe = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("troupe"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-02-15 23:45:12 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-02-15 23:45:12 -05:00
default=list,
)
2023-06-05 17:22:34 -04:00
crew = jsondata.JSONField(
2024-03-10 20:55:50 -04:00
verbose_name=_("crew"),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
2023-06-05 17:22:34 -04:00
schema=_CREW_SCHEMA,
2023-06-05 02:04:52 -04:00
)
location = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("theater"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-02-15 23:45:12 -05:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-02-15 23:45:12 -05:00
default=list,
)
opening_date = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("opening date"), max_length=100, null=True, blank=True
2023-06-05 11:45:57 -04:00
)
closing_date = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("closing date"), max_length=100, null=True, blank=True
2023-02-15 23:45:12 -05:00
)
official_site = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("website"), max_length=1000, null=True, blank=True
2023-02-15 23:45:12 -05:00
)
METADATA_COPY_LIST = [
"title",
"brief",
2023-06-05 02:04:52 -04:00
"orig_title",
2023-02-15 23:45:12 -05:00
"other_title",
"genre",
2023-06-05 02:04:52 -04:00
"language",
"opening_date",
"closing_date",
"troupe",
"location",
2023-06-05 02:04:52 -04:00
"director",
"playwright",
2023-06-05 14:00:09 -04:00
"orig_creator",
2023-06-05 02:04:52 -04:00
"composer",
"choreographer",
2023-06-05 17:22:34 -04:00
"actor",
"performer",
2023-06-05 02:04:52 -04:00
"crew",
"official_site",
]
2023-06-05 03:39:37 -04:00
@cached_property
def all_productions(self):
return (
self.productions.all()
.order_by("metadata__opening_date", "title")
2023-06-05 03:39:37 -04:00
.filter(is_deleted=False, merged_to_item=None)
)
2023-06-05 20:20:20 -04:00
@cached_property
def crew_by_role(self):
return _crew_by_role(self.crew)
@property
def child_items(self):
return self.all_productions
2023-06-05 02:04:52 -04:00
class PerformanceProduction(Item):
type = ItemType.PerformanceProduction
category = ItemCategory.Performance
url_path = "performance/production"
show = models.ForeignKey(
Performance, null=True, on_delete=models.SET_NULL, related_name="productions"
)
orig_title = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("original title"), blank=True, default="", max_length=500
2023-06-05 02:04:52 -04:00
)
other_title = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("other title"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=200),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
language = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("language"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=200),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
director = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("director"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
playwright = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("playwright"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
2023-06-05 14:00:09 -04:00
orig_creator = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("original creator"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 14:00:09 -04:00
null=False,
blank=True,
default=list,
)
2023-06-05 02:04:52 -04:00
composer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("composer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
choreographer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("choreographer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
default=list,
)
2023-06-05 17:22:34 -04:00
actor = jsondata.JSONField(
2024-03-10 20:55:50 -04:00
verbose_name=_("actor"),
2023-06-05 17:22:34 -04:00
null=False,
blank=True,
default=list,
schema=_ACTOR_SCHEMA,
)
performer = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("performer"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 11:45:57 -04:00
null=False,
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
troupe = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("troupe"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
2023-06-05 17:22:34 -04:00
crew = jsondata.JSONField(
2024-03-10 20:55:50 -04:00
verbose_name=_("crew"),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
2023-06-05 17:22:34 -04:00
schema=_CREW_SCHEMA,
2023-06-05 02:04:52 -04:00
)
location = jsondata.ArrayField(
2024-03-10 20:55:50 -04:00
verbose_name=_("theater"),
2023-06-05 17:55:39 -04:00
base_field=models.CharField(blank=False, default="", max_length=500),
2023-06-05 02:04:52 -04:00
null=False,
2023-06-05 11:45:57 -04:00
blank=True,
2023-06-05 02:04:52 -04:00
default=list,
)
opening_date = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("opening date"), max_length=100, null=True, blank=False
2023-06-05 11:45:57 -04:00
)
closing_date = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("closing date"), max_length=100, null=True, blank=True
2023-06-05 02:04:52 -04:00
)
official_site = jsondata.CharField(
2024-03-10 20:55:50 -04:00
verbose_name=_("website"), max_length=1000, null=True, blank=True
2023-06-05 02:04:52 -04:00
)
METADATA_COPY_LIST = [
"title",
"brief",
"orig_title",
"other_title",
"language",
"opening_date",
"closing_date",
"troupe",
"location",
2023-02-15 23:45:12 -05:00
"director",
"playwright",
2023-06-05 14:00:09 -04:00
"orig_creator",
2023-02-15 23:45:12 -05:00
"composer",
"choreographer",
2023-06-05 17:22:34 -04:00
"actor",
"performer",
2023-06-05 02:04:52 -04:00
"crew",
2023-02-15 23:45:12 -05:00
"official_site",
]
2023-06-05 02:04:52 -04:00
@property
2024-05-27 15:44:12 -04:00
def parent_item(self) -> Performance | None: # type:ignore
2023-06-05 02:04:52 -04:00
return self.show
2024-05-27 15:44:12 -04:00
def set_parent_item(self, value: Performance | None): # type:ignore
2023-06-05 18:57:52 -04:00
self.show = value
@classmethod
def lookup_id_type_choices(cls):
id_types = [
IdType.DoubanDramaVersion,
]
return [(i.value, i.label) for i in id_types]
2023-06-05 02:04:52 -04:00
@property
2023-06-05 02:46:26 -04:00
def display_title(self):
2023-06-05 18:57:52 -04:00
return f"{self.show.title if self.show else ''} {self.title}"
2023-06-05 02:04:52 -04:00
@property
2024-05-27 15:44:12 -04:00
def cover_image_url(self) -> str | None:
2023-06-05 02:04:52 -04:00
return (
2024-05-27 15:44:12 -04:00
self.cover.url # type:ignore
2023-06-05 02:04:52 -04:00
if self.cover and self.cover != DEFAULT_ITEM_COVER
2024-06-02 14:50:07 -04:00
else self.show.cover_image_url if self.show else None
2023-06-05 02:04:52 -04:00
)
2024-05-27 15:44:12 -04:00
def update_linked_items_from_external_resource(self, resource: ExternalResource):
2023-06-05 02:04:52 -04:00
for r in resource.required_resources:
if r["model"] == "Performance":
2024-05-27 15:44:12 -04:00
res = ExternalResource.objects.filter(
2023-06-05 02:04:52 -04:00
id_type=r["id_type"], id_value=r["id_value"]
).first()
2024-05-27 15:44:12 -04:00
if res and res.item:
self.show = res.item
2023-06-05 20:20:20 -04:00
@cached_property
def crew_by_role(self):
return _crew_by_role(self.crew)