2024-01-26 04:52:38 +00:00
|
|
|
import uuid
|
|
|
|
|
2023-10-24 12:55:14 +00:00
|
|
|
from django.contrib.auth.models import User
|
|
|
|
from django.db import models
|
2024-01-30 12:19:42 +00:00
|
|
|
from django.urls import reverse
|
2024-01-31 23:05:11 +00:00
|
|
|
from django.utils import timezone
|
2023-10-24 12:55:14 +00:00
|
|
|
|
|
|
|
|
2024-01-26 06:49:03 +00:00
|
|
|
def gen_message_id():
|
|
|
|
"""Generate a time-based identifier for use in "In-Reply-To" header."""
|
|
|
|
return f'<{uuid.uuid1()}@sfconservancy.org>'
|
|
|
|
|
|
|
|
|
2023-10-24 12:55:14 +00:00
|
|
|
class Candidate(models.Model):
|
2024-01-26 04:52:38 +00:00
|
|
|
"""A source/binary release we'd like to verify CCS status of."""
|
|
|
|
|
2023-10-24 12:55:14 +00:00
|
|
|
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)
|
2024-01-26 04:52:38 +00:00
|
|
|
release_date = models.DateField(null=True, blank=True)
|
|
|
|
description = models.TextField(blank=True)
|
2023-10-24 12:55:14 +00:00
|
|
|
source_url = models.URLField()
|
|
|
|
binary_url = models.URLField(blank=True)
|
2024-03-15 07:39:49 +00:00
|
|
|
show_download_disclaimer = models.BooleanField(default=True)
|
2023-10-30 22:31:28 +00:00
|
|
|
ordering = models.SmallIntegerField(default=0)
|
2024-01-26 06:49:03 +00:00
|
|
|
email_message_id = models.CharField(max_length=255, default=gen_message_id)
|
2023-10-30 22:31:28 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
ordering = ['ordering', 'name']
|
2023-10-24 12:55:14 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.name
|
|
|
|
|
2024-01-30 12:19:42 +00:00
|
|
|
def get_absolute_url(self):
|
|
|
|
return reverse('usethesource:candidate', kwargs={'slug': self.slug})
|
|
|
|
|
2023-10-24 12:55:14 +00:00
|
|
|
|
|
|
|
class Comment(models.Model):
|
2024-01-26 04:52:38 +00:00
|
|
|
"""A comment about experiences or learnings building the candidate."""
|
|
|
|
|
2023-10-24 12:55:14 +00:00
|
|
|
candidate = models.ForeignKey(Candidate, on_delete=models.CASCADE)
|
|
|
|
user = models.ForeignKey(User, on_delete=models.PROTECT)
|
2024-03-15 07:49:48 +00:00
|
|
|
attribute_to = models.CharField(max_length=50, blank=True)
|
2024-01-31 23:05:11 +00:00
|
|
|
time = models.DateTimeField(default=timezone.now)
|
2023-10-24 12:55:14 +00:00
|
|
|
message = models.TextField()
|
2024-01-26 04:52:38 +00:00
|
|
|
email_message_id = models.CharField(max_length=255, default=gen_message_id)
|
2023-10-24 12:55:14 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
2024-01-26 04:52:38 +00:00
|
|
|
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):
|
2024-01-26 06:49:03 +00:00
|
|
|
"""Determine the message_id of the previous comment or the candidate.
|
2024-01-26 04:52:38 +00:00
|
|
|
|
|
|
|
Used for email threading.
|
|
|
|
"""
|
|
|
|
if prev_comment := self._find_previous_comment():
|
|
|
|
return prev_comment.email_message_id
|
|
|
|
else:
|
2024-01-26 06:49:03 +00:00
|
|
|
return self.candidate.email_message_id
|
2023-10-24 12:55:14 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
ordering = ['id']
|
2024-07-29 13:29:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
class SourceOffer(models.Model):
|
2024-07-29 13:44:40 +00:00
|
|
|
time = models.DateTimeField(auto_now_add=True, null=True)
|
2024-07-29 13:29:25 +00:00
|
|
|
vendor = models.CharField('Vendor name', max_length=50)
|
|
|
|
device = models.CharField('Device name', max_length=50)
|
|
|
|
photo = models.ImageField(upload_to='usethesource/offers')
|
2024-07-29 13:44:40 +00:00
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return f'{self.vendor} {self.device}'
|