PYRSS-Website/apps/home/models.py
2024-06-17 02:02:59 +01:00

269 lines
6.8 KiB
Python

# -*- encoding: utf-8 -*-
import logging
from pathlib import Path
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
log = logging.getLogger(__name__)
class SavedGuilds(models.Model):
"""
Represents a saved Discord Guild (aka Server).
These are shown in the UI on the sidebar, and can be selected
to see associated Subscriptions.
"""
id = models.AutoField(primary_key=True)
# Have to use charfield instead of positiveBigIntegerField due to an Sqlite
# issue that rounds down the value
# https://github.com/sequelize/sequelize/issues/9335
guild_id = models.CharField(
verbose_name=_("guild id"),
max_length=128,
help_text=_("Discord snowflake ID for the represented guild.")
)
name = models.CharField(
max_length=128,
help_text=_("Name of the represented guild.")
)
icon = models.CharField(
max_length=128,
help_text=_("Hash for the represented guild's icon.")
)
added_by = models.ForeignKey(
verbose_name=_("added by"),
to="authentication.DiscordUser",
on_delete=models.CASCADE,
help_text=_("The user who added created this instance.")
)
permissions = models.CharField(
max_length=64,
help_text=_("Guild permissions for the user who added this instance.")
)
owner = models.BooleanField(
default=False,
help_text=_("Does the 'added by' user own this guild?")
)
class Meta:
"""
Metadata for the SavedGuilds Model.
"""
verbose_name = "saved guild"
verbose_name_plural = "saved guilds"
get_latest_by = "-creation_datetime"
constraints = [
# Prevent servers from having subscriptions with duplicate names
models.UniqueConstraint(
fields=["added_by", "guild_id"],
name="unique added_by & guild_id pair"
)
]
def __str__(self) -> str:
return self.name
class SubChannel(models.Model):
"""
Represents a Discord TextChannel, saved against a Subscription.
SubChannels are used as targets to send content from Subscriptions.
"""
id = models.AutoField(primary_key=True)
# Have to use charfield instead of positiveBigIntegerField due to an Sqlite
# issue that rounds down the value
# https://github.com/sequelize/sequelize/issues/9335
channel_id = models.CharField(
verbose_name=_("channel id"),
max_length=128,
help_text=_("Discord snowflake ID for the represented Channel.")
)
subscription = models.ForeignKey(
to="home.Subscription",
on_delete=models.CASCADE,
help_text=_("The linked Subscription, must be unique.")
)
class Meta:
"""
Metadata for the SubChannel Model.
"""
verbose_name = "SubChannel"
verbose_name_plural = "SubChannels"
get_latest_by = "id"
constraints = [
# Prevent servers from having subscriptions with duplicate names
models.UniqueConstraint(
fields=["channel_id", "subscription"],
name="unique channel id and subscription pair")
]
def __str__(self) -> str:
return self.channel_id
class Filter(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(
max_length=32,
null=False,
blank=False
)
keywords = models.CharField(
max_length=128,
null=True,
blank=True
)
regex = models.CharField(
max_length=128,
null=True,
blank=True
)
whitelist = models.BooleanField(default=False)
# Have to use charfield instead of positiveBigIntegerField due to an Sqlite
# issue that rounds down the value
# https://github.com/sequelize/sequelize/issues/9335
guild_id = models.CharField(
max_length=128
)
class Meta:
"""
Metadata for the Filter Model.
"""
verbose_name = "filter"
verbose_name_plural = "filters"
get_latest_by = "id"
constraints = [
models.UniqueConstraint(
fields=["name", "guild_id"],
name="unique name & guild id pair"
)
]
def __str__(self) -> str:
return self.name
class Subscription(models.Model):
"""
The Subscription Model.
'Subscription' in the context of PYRSS is an RSS Feed with various settings.
"""
id = models.AutoField(primary_key=True)
name = models.CharField(
max_length=32,
null=False,
blank=False
)
url = models.URLField()
# NOTE:
# Have to use charfield instead of positiveBigIntegerField due to an Sqlite
# issue that rounds down the value
# https://github.com/sequelize/sequelize/issues/9335
guild_id = models.CharField(
max_length=128
)
creation_datetime = models.DateTimeField(
default=timezone.now,
editable=False
)
extra_notes = models.CharField(
max_length=250,
null=True,
blank=True,
)
uwuify = models.BooleanField(default=False)
filters = models.ManyToManyField(to="home.Filter", blank=True)
active = models.BooleanField(default=True)
class Meta:
"""
Metadata for the Subscription Model.
"""
verbose_name = "subscription"
verbose_name_plural = "subscriptions"
get_latest_by = "-creation_datetime"
constraints = [
# Prevent servers from having subscriptions with duplicate names
models.UniqueConstraint(fields=["name", "guild_id"], name="unique name & server pair")
]
@property
def channels_count(self) -> int:
"""
Returns the number of 'SubChannel' objects assocaited
with this subscription.
"""
return len(SubChannel.objects.filter(subscription=self))
def save(self, *args, **kwargs):
new_text = "New " if self._state.adding else ""
log.debug("%sSubscription Saved %s", new_text, self.id)
super().save(*args, **kwargs)
def __str__(self) -> str:
return self.name
class TrackedContent(models.Model):
"""
Tracked Content Model
'Tracked Content' identifies articles and tracks them being sent.
This is used to ensure duplicate articles aren't sent in feeds.
"""
guid = models.CharField(
primary_key=True,
max_length=128
)
title = models.CharField(max_length=128)
url = models.URLField(unique=True)
subscription = models.ForeignKey(to=Subscription, on_delete=models.CASCADE)
blocked = models.BooleanField(default=False)
creation_datetime = models.DateTimeField(
default=timezone.now,
editable=False
)
def __str__(self) -> str:
return self.title