unique content rule backend
This commit is contained in:
parent
6942fcc12e
commit
b91d38dc81
@ -1,15 +1,24 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from urllib.parse import unquote
|
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from apps.home.models import SubChannel, Filter, Subscription, SavedGuilds, TrackedContent, ArticleMutator, GuildSettings
|
from apps.home.models import (
|
||||||
|
SubChannel,
|
||||||
|
Filter,
|
||||||
|
Subscription,
|
||||||
|
SavedGuilds,
|
||||||
|
TrackedContent,
|
||||||
|
ArticleMutator,
|
||||||
|
GuildSettings,
|
||||||
|
UniqueContentRule
|
||||||
|
)
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
#region Dynamic Model
|
||||||
# This DynamicModelSerializer is from a StackOverflow user in an obscure thread.
|
# This DynamicModelSerializer is from a StackOverflow user in an obscure thread.
|
||||||
# I wish that I could remember which thread, because god bless that man.
|
# I wish that I could remember which thread, because god bless that man.
|
||||||
|
|
||||||
@ -109,6 +118,8 @@ class DynamicModelSerializer(serializers.ModelSerializer):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
#region Sub Channel
|
||||||
|
|
||||||
class SubChannelSerializer(DynamicModelSerializer):
|
class SubChannelSerializer(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for SubChannel Model.
|
Serializer for SubChannel Model.
|
||||||
@ -119,6 +130,8 @@ class SubChannelSerializer(DynamicModelSerializer):
|
|||||||
fields = ("id", "channel_id", "channel_name", "subscription")
|
fields = ("id", "channel_id", "channel_name", "subscription")
|
||||||
|
|
||||||
|
|
||||||
|
#region Filter
|
||||||
|
|
||||||
class FilterSerializer(DynamicModelSerializer):
|
class FilterSerializer(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the Filter Model.
|
Serializer for the Filter Model.
|
||||||
@ -129,6 +142,8 @@ class FilterSerializer(DynamicModelSerializer):
|
|||||||
fields = ("id", "name", "matching_algorithm", "match", "is_insensitive", "is_whitelist", "guild_id")
|
fields = ("id", "name", "matching_algorithm", "match", "is_insensitive", "is_whitelist", "guild_id")
|
||||||
|
|
||||||
|
|
||||||
|
#region Article Mutator
|
||||||
|
|
||||||
class ArticleMutatorSerializer(DynamicModelSerializer):
|
class ArticleMutatorSerializer(DynamicModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -136,6 +151,20 @@ class ArticleMutatorSerializer(DynamicModelSerializer):
|
|||||||
fields = ("id", "name", "value")
|
fields = ("id", "name", "value")
|
||||||
|
|
||||||
|
|
||||||
|
#region Unique Content Rule
|
||||||
|
|
||||||
|
class UniqueContentRuleSerializer(DynamicModelSerializer):
|
||||||
|
"""
|
||||||
|
Serializer for the UniqueContentRule model.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = UniqueContentRule
|
||||||
|
fields = ("id", "name", "value")
|
||||||
|
|
||||||
|
|
||||||
|
#region Subscription (GET)
|
||||||
|
|
||||||
class SubscriptionSerializer_GET(DynamicModelSerializer):
|
class SubscriptionSerializer_GET(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the Subscription Model.
|
Serializer for the Subscription Model.
|
||||||
@ -143,16 +172,20 @@ class SubscriptionSerializer_GET(DynamicModelSerializer):
|
|||||||
|
|
||||||
article_title_mutators = ArticleMutatorSerializer(many=True)
|
article_title_mutators = ArticleMutatorSerializer(many=True)
|
||||||
article_desc_mutators = ArticleMutatorSerializer(many=True)
|
article_desc_mutators = ArticleMutatorSerializer(many=True)
|
||||||
|
unique_content_rules = UniqueContentRuleSerializer(many=True)
|
||||||
active = serializers.BooleanField(initial=True)
|
active = serializers.BooleanField(initial=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Subscription
|
model = Subscription
|
||||||
fields = (
|
fields = (
|
||||||
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes", "filters",
|
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes", "filters",
|
||||||
"article_title_mutators", "article_desc_mutators", "article_fetch_image", "published_threshold", "embed_colour", "active"
|
"article_title_mutators", "article_desc_mutators", "article_fetch_image", "published_threshold", "embed_colour",
|
||||||
|
"unique_content_rules", "active"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#region Subscription (POST)
|
||||||
|
|
||||||
class SubscriptionSerializer_POST(DynamicModelSerializer):
|
class SubscriptionSerializer_POST(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the Subscription Model.
|
Serializer for the Subscription Model.
|
||||||
@ -162,10 +195,13 @@ class SubscriptionSerializer_POST(DynamicModelSerializer):
|
|||||||
model = Subscription
|
model = Subscription
|
||||||
fields = (
|
fields = (
|
||||||
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes", "filters",
|
"id", "name", "url", "guild_id", "channels_count", "creation_datetime", "extra_notes", "filters",
|
||||||
"article_title_mutators", "article_desc_mutators", "article_fetch_image", "published_threshold", "embed_colour", "active"
|
"article_title_mutators", "article_desc_mutators", "article_fetch_image", "published_threshold", "embed_colour",
|
||||||
|
"unique_content_rules", "active"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#region Saved Guild
|
||||||
|
|
||||||
class SavedGuildSerializer(DynamicModelSerializer):
|
class SavedGuildSerializer(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the SavedGuild model.
|
Serializer for the SavedGuild model.
|
||||||
@ -176,6 +212,8 @@ class SavedGuildSerializer(DynamicModelSerializer):
|
|||||||
fields = ("id", "guild_id", "name", "icon", "added_by", "permissions", "owner")
|
fields = ("id", "guild_id", "name", "icon", "added_by", "permissions", "owner")
|
||||||
|
|
||||||
|
|
||||||
|
#region Guild Setting
|
||||||
|
|
||||||
class GuildSettingsSerializer(DynamicModelSerializer):
|
class GuildSettingsSerializer(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the GuildSettings model.
|
Serializer for the GuildSettings model.
|
||||||
@ -186,6 +224,8 @@ class GuildSettingsSerializer(DynamicModelSerializer):
|
|||||||
fields = ("id", "guild_id", "default_embed_colour", "active")
|
fields = ("id", "guild_id", "default_embed_colour", "active")
|
||||||
|
|
||||||
|
|
||||||
|
#region Tracked Content (GET)
|
||||||
|
|
||||||
class TrackedContentSerializer_GET(DynamicModelSerializer):
|
class TrackedContentSerializer_GET(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the TrackedContent model.
|
Serializer for the TrackedContent model.
|
||||||
@ -196,16 +236,10 @@ class TrackedContentSerializer_GET(DynamicModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = TrackedContent
|
model = TrackedContent
|
||||||
fields = ("id", "guid", "title", "url", "subscription", "channel_id", "message_id", "blocked", "creation_datetime")
|
fields = ("id", "guid", "title", "url", "subscription", "channel_id", "message_id", "blocked", "creation_datetime")
|
||||||
|
|
||||||
# def to_representation(self, instance):
|
|
||||||
# representation = super().to_representation(instance)
|
|
||||||
# log.info(representation.get("guid", "nothing"))
|
|
||||||
# if 'guid' in representation:
|
|
||||||
# representation['guid'] = unquote(representation['guid'])
|
|
||||||
# log.info(representation.get("guid", "nothing"))
|
|
||||||
# return representation
|
|
||||||
|
|
||||||
|
|
||||||
|
#region Tracked Content (POST)
|
||||||
|
|
||||||
class TrackedContentSerializer_POST(DynamicModelSerializer):
|
class TrackedContentSerializer_POST(DynamicModelSerializer):
|
||||||
"""
|
"""
|
||||||
Serializer for the TrackedContent model.
|
Serializer for the TrackedContent model.
|
||||||
|
@ -18,7 +18,9 @@ from .views import (
|
|||||||
ArticleMutator_ListView,
|
ArticleMutator_ListView,
|
||||||
ArticleMutator_DetailView,
|
ArticleMutator_DetailView,
|
||||||
GuildSettings_ListView,
|
GuildSettings_ListView,
|
||||||
GuildSettings_DetailView
|
GuildSettings_DetailView,
|
||||||
|
UniqueContentRule_ListView,
|
||||||
|
UniqueContentRule_DetailView
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@ -62,4 +64,9 @@ urlpatterns = [
|
|||||||
path("", ArticleMutator_ListView.as_view(), name="article-mutator"),
|
path("", ArticleMutator_ListView.as_view(), name="article-mutator"),
|
||||||
path("<int:pk>/", ArticleMutator_DetailView.as_view(), name="article-mutator-detail")
|
path("<int:pk>/", ArticleMutator_DetailView.as_view(), name="article-mutator-detail")
|
||||||
])),
|
])),
|
||||||
|
|
||||||
|
path("unique-content-rule/", include([
|
||||||
|
path("", UniqueContentRule_ListView.as_view(), name="unique-content-rule"),
|
||||||
|
path("<int:pk>/", UniqueContentRule_DetailView.as_view(), name="unique-content-rule-detail")
|
||||||
|
])),
|
||||||
]
|
]
|
||||||
|
@ -11,7 +11,7 @@ from rest_framework.pagination import PageNumberPagination
|
|||||||
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
|
from rest_framework.authentication import SessionAuthentication, TokenAuthentication
|
||||||
from rest_framework.parsers import MultiPartParser, FormParser
|
from rest_framework.parsers import MultiPartParser, FormParser
|
||||||
|
|
||||||
from apps.home.models import SubChannel, Filter, Subscription, SavedGuilds, TrackedContent, ArticleMutator, GuildSettings
|
from apps.home.models import SubChannel, Filter, Subscription, SavedGuilds, TrackedContent, ArticleMutator, GuildSettings, UniqueContentRule
|
||||||
from apps.authentication.models import DiscordUser
|
from apps.authentication.models import DiscordUser
|
||||||
from .metadata import ExpandedMetadata
|
from .metadata import ExpandedMetadata
|
||||||
from .serializers import (
|
from .serializers import (
|
||||||
@ -23,7 +23,8 @@ from .serializers import (
|
|||||||
TrackedContentSerializer_GET,
|
TrackedContentSerializer_GET,
|
||||||
TrackedContentSerializer_POST,
|
TrackedContentSerializer_POST,
|
||||||
ArticleMutatorSerializer,
|
ArticleMutatorSerializer,
|
||||||
GuildSettingsSerializer
|
GuildSettingsSerializer,
|
||||||
|
UniqueContentRuleSerializer
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -113,6 +114,44 @@ class SubChannel_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
return SubChannel.objects.filter(subscription__guild_id__in=guild_ids)
|
return SubChannel.objects.filter(subscription__guild_id__in=guild_ids)
|
||||||
|
|
||||||
|
|
||||||
|
#region Unique Content Rule
|
||||||
|
|
||||||
|
class UniqueContentRule_ListView(generics.ListAPIView):
|
||||||
|
"""
|
||||||
|
View to provide a list of UniqueContentRule model instances.
|
||||||
|
Can also be used to create a new instance.
|
||||||
|
|
||||||
|
Supports GET, POST
|
||||||
|
"""
|
||||||
|
|
||||||
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
pagination_class = DefaultPagination
|
||||||
|
serializer_class = UniqueContentRuleSerializer
|
||||||
|
metadata_class = ExpandedMetadata
|
||||||
|
queryset = UniqueContentRule.objects.all().order_by("id")
|
||||||
|
|
||||||
|
filter_backends = [filters.SearchFilter, rest_filters.DjangoFilterBackend, filters.OrderingFilter]
|
||||||
|
filterset_fields = ["id", "name", "value"]
|
||||||
|
|
||||||
|
|
||||||
|
class UniqueContentRule_DetailView(generics.RetrieveAPIView):
|
||||||
|
"""
|
||||||
|
View to provide details on a particular UniqueContentRule model instances.
|
||||||
|
|
||||||
|
Supports: GET
|
||||||
|
"""
|
||||||
|
|
||||||
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
parser_classes = [MultiPartParser, FormParser]
|
||||||
|
|
||||||
|
serializer_class = UniqueContentRuleSerializer
|
||||||
|
queryset = UniqueContentRule.objects.all().order_by("id")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# =================================================================================================
|
# =================================================================================================
|
||||||
#region Filter
|
#region Filter
|
||||||
|
|
||||||
@ -570,7 +609,7 @@ class TrackedContent_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
# =================================================================================================
|
# =================================================================================================
|
||||||
#region Article Mutator
|
#region Article Mutator
|
||||||
|
|
||||||
class ArticleMutator_ListView(generics.ListCreateAPIView):
|
class ArticleMutator_ListView(generics.ListAPIView):
|
||||||
"""
|
"""
|
||||||
View to provide a list of ArticleMutator model instances.
|
View to provide a list of ArticleMutator model instances.
|
||||||
Can also be used to create a new instance.
|
Can also be used to create a new instance.
|
||||||
@ -589,28 +628,12 @@ class ArticleMutator_ListView(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
serializer_class = ArticleMutatorSerializer
|
serializer_class = ArticleMutatorSerializer
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
serializer = self.get_serializer(data=request.data)
|
|
||||||
serializer.is_valid(raise_exception=True)
|
|
||||||
|
|
||||||
try:
|
class ArticleMutator_DetailView(generics.RetrieveAPIView):
|
||||||
self.perform_create(serializer)
|
|
||||||
except IntegrityError as err:
|
|
||||||
return Response(
|
|
||||||
{"detail": str(err)},
|
|
||||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
||||||
exception=True
|
|
||||||
)
|
|
||||||
|
|
||||||
headers = self.get_success_headers(serializer.data)
|
|
||||||
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
|
|
||||||
|
|
||||||
|
|
||||||
class ArticleMutator_DetailView(generics.RetrieveUpdateDestroyAPIView):
|
|
||||||
"""
|
"""
|
||||||
View to provide details on a particular ArticleMutator model instances.
|
View to provide details on a particular ArticleMutator model instances.
|
||||||
|
|
||||||
Supports: GET, PUT, PATCH, DELETE
|
Supports: GET
|
||||||
"""
|
"""
|
||||||
|
|
||||||
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
authentication_classes = [SessionAuthentication, TokenAuthentication]
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
# Generated by Django 5.0.4 on 2024-09-13 23:30
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('home', '0022_populate_guild_settings'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UniqueContentRule',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||||
|
('name', models.CharField(max_length=64)),
|
||||||
|
('value', models.CharField(max_length=32)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subscription',
|
||||||
|
name='unique_content_rules',
|
||||||
|
field=models.ManyToManyField(to='home.uniquecontentrule'),
|
||||||
|
),
|
||||||
|
]
|
22
apps/home/migrations/0024_initial_uniquecontentrule_data.py
Normal file
22
apps/home/migrations/0024_initial_uniquecontentrule_data.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 5.0.4 on 2024-09-13 23:32
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
def add_rules(apps, schema_editor):
|
||||||
|
Rules = apps.get_model("home", "UniqueContentRule")
|
||||||
|
Rules.objects.create(name="GUID", value="GUID")
|
||||||
|
Rules.objects.create(name="ID", value="ID")
|
||||||
|
Rules.objects.create(name="URL", value="URL")
|
||||||
|
Rules.objects.create(name="Title", value="TITLE")
|
||||||
|
Rules.objects.create(name="Content Hash", value="CONTENT")
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('home', '0023_uniquecontentrule_subscription_unique_content_rules'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(add_rules)
|
||||||
|
]
|
@ -277,6 +277,11 @@ class Subscription(models.Model):
|
|||||||
|
|
||||||
filters = models.ManyToManyField(to="home.Filter", blank=True)
|
filters = models.ManyToManyField(to="home.Filter", blank=True)
|
||||||
|
|
||||||
|
unique_content_rules = models.ManyToManyField(
|
||||||
|
to="home.UniqueContentRule",
|
||||||
|
blank=False
|
||||||
|
);
|
||||||
|
|
||||||
article_title_mutators = models.ManyToManyField(
|
article_title_mutators = models.ManyToManyField(
|
||||||
to="home.ArticleMutator",
|
to="home.ArticleMutator",
|
||||||
related_name="title_mutated_subscriptions",
|
related_name="title_mutated_subscriptions",
|
||||||
@ -386,6 +391,8 @@ class TrackedContent(models.Model):
|
|||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
|
||||||
|
#region Article Mutator
|
||||||
|
|
||||||
class ArticleMutator(models.Model):
|
class ArticleMutator(models.Model):
|
||||||
|
|
||||||
id = models.AutoField(primary_key=True)
|
id = models.AutoField(primary_key=True)
|
||||||
@ -394,3 +401,16 @@ class ArticleMutator(models.Model):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
#region UniqueContentRules
|
||||||
|
|
||||||
|
class UniqueContentRule(models.Model):
|
||||||
|
|
||||||
|
id = models.AutoField(primary_key=True)
|
||||||
|
name = models.CharField(max_length=64)
|
||||||
|
value = models.CharField(max_length=32)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.name
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user