ausglamr/blogs/models/blog.py
Hugh Rundle 8dc69f2a9e
fix blog announcements and update tests
Blog announcements were using the string "None" as the author, now they should not.
Updated tests accordingly.
Fixed email test being captured by bot trap.
2025-02-03 16:26:06 +11:00

152 lines
4.5 KiB
Python

"""blog models"""
import re
from django.db import models
from django.utils import timezone
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from .utils import Announcement, Category, ContentWarning
def validate_ap_address(value):
"""is the activitypub address valid?"""
p = re.compile("@(.*)@((\w|-)*)\.((\w)*)")
m = p.match(value)
if not m:
raise ValidationError(
_("%(value)s should be in the form '@user@domain.tld'"),
params={"value": value},
)
class BlogData(models.Model):
"""Base bloggy data"""
title = models.CharField(max_length=2000)
author_name = models.CharField(max_length=1000, null=True, blank=True)
url = models.URLField(max_length=2000, unique=True)
description = models.TextField(null=True, blank=True)
updateddate = models.DateTimeField()
pubdate = models.DateTimeField(null=True, default=timezone.now)
class Meta:
"""This is an abstract model for common data"""
abstract = True
def __str__(self):
"""display for admin dropdowns"""
return self.title
def get_absolute_url(self):
"""override"""
return self.url
def save(self, *args, **kwargs):
if not self.updateddate:
self.updateddate = timezone.now()
super().save(*args, **kwargs)
class Blog(BlogData):
"""A blog"""
feed = models.URLField(max_length=2000)
category = models.CharField(choices=Category.choices, max_length=4)
added = models.DateTimeField(default=timezone.now)
approved = models.BooleanField(default=False)
announced = models.BooleanField(default=False)
failing = models.BooleanField(default=False, blank=True, null=True)
suspended = models.BooleanField(default=False, blank=True, null=True)
suspension_lifted = models.DateTimeField(blank=True, null=True)
active = models.BooleanField(null=True, default=True)
activitypub_account_name = models.CharField(
max_length=200, blank=True, null=True, validators=[validate_ap_address]
)
contact_email = models.EmailField(blank=True, null=True)
def announce(self):
"""queue announcement"""
if self.activitypub_account_name:
author = f" by {self.activitypub_account_name}"
elif self.author_name:
author = f" by {self.author_name}"
else:
author = ""
category = Category(self.category).label
status = f"{self.title}{author} has been added to Aus GLAMR! \n\nIt's about {category}\n\n{self.url}"
Announcement.objects.create(status=status)
self.announced = True
super().save()
def set_failing(self):
"""set the blog feed as failing"""
self.failing = True
super().save()
def set_success(self, updateddate):
"""
set failing to false
set the updateddate to a datetime
"""
self.failing = False
self.updateddate = updateddate
super().save()
class Article(BlogData):
"""A blog post"""
blog = models.ForeignKey(Blog, on_delete=models.CASCADE, related_name="articles")
guid = models.CharField(max_length=2000)
tags = models.ManyToManyField("Tag", related_name="articles")
# pylint: disable=undefined-variable
def announce(self):
"""queue a blog post announcement"""
summary = []
warnings = ContentWarning.objects.all()
for warning in warnings:
for text in [self.title, self.description]:
label = warning.is_in(text)
if label:
summmary.append(label)
for tag in self.tags.all(): # pylint: disable=E1133
label = warning.is_in(tag.name)
if label:
summmary.append(label)
summary_text = ", ".join(summary) if len(summary) > 0 else None
author = self.blog.activitypub_account_name or self.author_name
if self.blog.activitypub_account_name:
author = f"{self.blog.activitypub_account_name} "
elif self.author_name:
author = f"{self.author_name} "
else:
author = ""
status = f"{self.title} ({author}on {self.blog.title})\n\n{self.url}"
Announcement.objects.create(status=status, summary=summary_text)
class Tag(models.Model):
"""An article tag"""
name = models.CharField(max_length=100, unique=True)
def __str__(self):
"""display for admin dropdowns"""
return self.name