Files @ 956f8c6fdaad
Branch filter:

Location: website/conservancy/usethesource/models.py

bsturmfels
podjango: Add "Podcast" model to support multiple podcasts

Each Cast (episode) can belong to one or more Podcast, allowing episodes to be
shared between podcasts. This enables us introductory episodes to be delivered
in their own feed, but also included in the main "The Corresponding Source"
feed.

This required adding an additional `podcast_slug` argument to most views. The
date archive views were dropped because they're not linked to from anywhere.

Added a `podcasts` view as an index of all available Podcasts.
import uuid

from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezone


def gen_message_id():
    """Generate a time-based identifier for use in "In-Reply-To" header."""
    return f'<{uuid.uuid1()}@sfconservancy.org>'


class Candidate(models.Model):
    """A source/binary release we'd like to verify CCS status of."""

    name = models.CharField('Candidate name', max_length=50)
    slug = models.SlugField(max_length=50, unique=True)
    vendor = models.CharField('Vendor name', max_length=50)
    device = models.CharField('Device name', max_length=50)
    release_date = models.DateField(null=True, blank=True)
    description = models.TextField(blank=True)
    source_url = models.URLField()
    binary_url = models.URLField(blank=True)
    show_download_disclaimer = models.BooleanField(default=True)
    ordering = models.SmallIntegerField(default=0)
    email_message_id = models.CharField(max_length=255, default=gen_message_id)

    class Meta:
        ordering = ['ordering', 'name']

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('usethesource:candidate', kwargs={'slug': self.slug})


class Comment(models.Model):
    """A comment about experiences or learnings building the candidate."""

    candidate = models.ForeignKey(Candidate, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    attribute_to = models.CharField(max_length=50, blank=True)
    time = models.DateTimeField(default=timezone.now)
    message = models.TextField()
    email_message_id = models.CharField(max_length=255, default=gen_message_id)

    def __str__(self):
        return f'{self.id}: {self.candidate.name}, {self.user}, {self.time}'

    def _find_previous_comment(self):
        try:
            return self.__class__.objects.filter(candidate=self.candidate, id__lt=self.id).latest('id')
        except self.__class__.DoesNotExist:
            return None

    def in_reply_to(self):
        """Determine the message_id of the previous comment or the candidate.

        Used for email threading.
        """
        if prev_comment := self._find_previous_comment():
            return prev_comment.email_message_id
        else:
            return self.candidate.email_message_id

    class Meta:
        ordering = ['id']