133 lines
4.6 KiB
Python
133 lines
4.6 KiB
Python
from django.db import models
|
|
from django.urls import reverse
|
|
from django.utils.text import slugify
|
|
from django.contrib.auth import get_user_model
|
|
|
|
from common import mixins
|
|
from common.upload_paths import get_upload_to_hashed_path
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class FilmStatus(models.TextChoices):
|
|
in_development = '0_dev', 'In Development'
|
|
in_production = '1_prod', 'In Production'
|
|
released = '2_released', 'Released'
|
|
|
|
|
|
class Film(mixins.CreatedUpdatedMixin, mixins.StaticThumbnailURLMixin, models.Model):
|
|
title = models.CharField(unique=True, max_length=512)
|
|
slug = models.SlugField(unique=True, blank=True)
|
|
description = models.TextField()
|
|
description.description = 'Description consisting of a few sentences.'
|
|
summary = models.TextField()
|
|
summary.description = 'Summary consisting of multiple paragraphs.'
|
|
|
|
status = models.TextField(choices=FilmStatus.choices)
|
|
release_date = models.DateField(blank=True, null=True)
|
|
release_date.description = "Past or planned release date of the film."
|
|
is_published = models.BooleanField(default=False)
|
|
is_featured = models.BooleanField(default=False)
|
|
|
|
logo = models.FileField(
|
|
upload_to=get_upload_to_hashed_path,
|
|
help_text='A PNG picture with transparency, featuring the logo.',
|
|
)
|
|
poster = models.FileField(
|
|
upload_to=get_upload_to_hashed_path, help_text='A 1508x2133 poster for the film.'
|
|
)
|
|
picture_header = models.FileField(
|
|
upload_to=get_upload_to_hashed_path, help_text='A 1920x850 header image. No text.'
|
|
)
|
|
thumbnail = models.FileField(
|
|
upload_to=get_upload_to_hashed_path, help_text='A 1920x1080 image for social media preview.'
|
|
)
|
|
youtube_link = models.URLField(blank=True)
|
|
crew = models.ManyToManyField(User, through='FilmCrew')
|
|
|
|
show_production_logs_nav_link = models.BooleanField(
|
|
default=False,
|
|
help_text='Display a link to production logs in the navigation.',
|
|
)
|
|
show_production_logs_as_featured = models.BooleanField(
|
|
default=False,
|
|
help_text='Display production logs instead of the featured gallery on the film page.',
|
|
)
|
|
show_blog_posts = models.BooleanField(
|
|
default=False,
|
|
help_text='Display latest blog posts on the film page.',
|
|
)
|
|
show_landing_page = models.BooleanField(
|
|
default=False, help_text='Show a landing page to non-subscribers instead of film content'
|
|
)
|
|
|
|
class Meta:
|
|
# Sort by release date descending,
|
|
# fall back to created date in case the film hasn't been released yet.
|
|
ordering = ('-release_date', '-date_created')
|
|
|
|
def clean(self) -> None:
|
|
super().clean()
|
|
if not self.slug:
|
|
self.slug = slugify(self.title)
|
|
|
|
def __str__(self) -> str:
|
|
return self.title
|
|
|
|
def get_absolute_url(self) -> str:
|
|
return self.url
|
|
|
|
@property
|
|
def url(self) -> str:
|
|
return reverse('film-detail', kwargs={'film_slug': self.slug})
|
|
|
|
@property
|
|
def admin_url(self) -> str:
|
|
return reverse('admin:films_film_change', args=[self.pk])
|
|
|
|
|
|
class FilmCrew(models.Model):
|
|
"""People that are involved in the film production.
|
|
|
|
Used to set their role (Director, Animator, Art Director, etc) and
|
|
display it in the production logs.
|
|
"""
|
|
|
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='film_crew')
|
|
film = models.ForeignKey(Film, on_delete=models.CASCADE)
|
|
role = models.CharField(max_length=128)
|
|
|
|
class Meta:
|
|
unique_together = ['user', 'film']
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.user.username} - {self.role}"
|
|
|
|
|
|
class FilmProductionCredit(mixins.CreatedUpdatedMixin, models.Model):
|
|
"""Production Credit for subscribers.
|
|
|
|
Credits are granted based on the amount of time a user kept their subscription
|
|
active. Credits are opt-in. This means that by default a credit will not
|
|
be displayed on the site and it will be ignored by the 'generate_production_credits_scroll'
|
|
script.
|
|
"""
|
|
|
|
film = models.ForeignKey(Film, on_delete=models.CASCADE)
|
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='production_credits')
|
|
# Populated after running a one-time script, when locking the credit list
|
|
display_name = models.CharField(max_length=128, blank=True, null=True)
|
|
is_public = models.BooleanField(
|
|
default=None,
|
|
null=True,
|
|
help_text='Display your name in the film credits.',
|
|
)
|
|
# Made not-editable after running a one-time script
|
|
is_editable = models.BooleanField(default=True)
|
|
|
|
class Meta:
|
|
unique_together = ['user', 'film']
|
|
|
|
def __str__(self) -> str:
|
|
return f"{self.user.username} - {self.film}"
|