音楽で楽しみましょう!-Let's have fun with music!-
Signed-off-by: Shin'ya Minazuki <shinyoukai@laidback.moe>
This commit is contained in:
parent
7c3206bf83
commit
54c6d22102
517 changed files with 637 additions and 639 deletions
122
api/funquail_api/audio/models.py
Normal file
122
api/funquail_api/audio/models.py
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
import uuid
|
||||
|
||||
from django.contrib.contenttypes.fields import GenericRelation
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import models
|
||||
from django.db.models import JSONField
|
||||
from django.db.models.signals import post_delete
|
||||
from django.dispatch import receiver
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
|
||||
from funkwhale_api.federation import keys
|
||||
from funkwhale_api.federation import models as federation_models
|
||||
from funkwhale_api.federation import utils as federation_utils
|
||||
from funkwhale_api.users import models as user_models
|
||||
|
||||
|
||||
def empty_dict():
|
||||
return {}
|
||||
|
||||
|
||||
class ChannelQuerySet(models.QuerySet):
|
||||
def external_rss(self, include=True):
|
||||
from funkwhale_api.federation import actors
|
||||
|
||||
query = models.Q(
|
||||
attributed_to=actors.get_service_actor(),
|
||||
actor__preferred_username__startswith="rssfeed-",
|
||||
)
|
||||
if include:
|
||||
return self.filter(query)
|
||||
return self.exclude(query)
|
||||
|
||||
def subscribed(self, actor):
|
||||
if not actor:
|
||||
return self.none()
|
||||
|
||||
subscriptions = actor.emitted_follows.filter(
|
||||
approved=True, target__channel__isnull=False
|
||||
)
|
||||
return self.filter(actor__in=subscriptions.values_list("target", flat=True))
|
||||
|
||||
|
||||
class Channel(models.Model):
|
||||
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||
artist = models.OneToOneField(
|
||||
"music.Artist", on_delete=models.CASCADE, related_name="channel"
|
||||
)
|
||||
# the owner of the channel
|
||||
attributed_to = models.ForeignKey(
|
||||
"federation.Actor", on_delete=models.CASCADE, related_name="owned_channels"
|
||||
)
|
||||
# the federation actor created for the channel
|
||||
# (the one people can follow to receive updates)
|
||||
actor = models.OneToOneField(
|
||||
"federation.Actor", on_delete=models.CASCADE, related_name="channel"
|
||||
)
|
||||
|
||||
library = models.OneToOneField(
|
||||
"music.Library", on_delete=models.CASCADE, related_name="channel"
|
||||
)
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
rss_url = models.URLField(max_length=500, null=True, blank=True)
|
||||
|
||||
# metadata to enhance rss feed
|
||||
metadata = JSONField(
|
||||
default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder, blank=True
|
||||
)
|
||||
|
||||
fetches = GenericRelation(
|
||||
"federation.Fetch",
|
||||
content_type_field="object_content_type",
|
||||
object_id_field="object_id",
|
||||
)
|
||||
objects = ChannelQuerySet.as_manager()
|
||||
|
||||
@property
|
||||
def fid(self):
|
||||
if not self.is_external_rss:
|
||||
return self.actor.fid
|
||||
|
||||
@property
|
||||
def is_local(self) -> bool:
|
||||
return self.actor.is_local
|
||||
|
||||
@property
|
||||
def is_external_rss(self):
|
||||
return self.actor.preferred_username.startswith("rssfeed-")
|
||||
|
||||
def get_absolute_url(self):
|
||||
suffix = self.uuid
|
||||
if self.actor.is_local:
|
||||
suffix = self.actor.preferred_username
|
||||
else:
|
||||
suffix = self.actor.full_username
|
||||
return federation_utils.full_url(f"/channels/{suffix}")
|
||||
|
||||
def get_rss_url(self):
|
||||
if not self.artist.is_local or self.is_external_rss:
|
||||
return self.rss_url
|
||||
|
||||
return federation_utils.full_url(
|
||||
reverse(
|
||||
"api:v1:channels-rss",
|
||||
kwargs={"composite": self.actor.preferred_username},
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def generate_actor(username, **kwargs):
|
||||
actor_data = user_models.get_actor_data(username, **kwargs)
|
||||
private, public = keys.get_key_pair()
|
||||
actor_data["private_key"] = private.decode("utf-8")
|
||||
actor_data["public_key"] = public.decode("utf-8")
|
||||
|
||||
return federation_models.Actor.objects.create(**actor_data)
|
||||
|
||||
|
||||
@receiver(post_delete, sender=Channel)
|
||||
def delete_channel_related_objs(instance, **kwargs):
|
||||
instance.library.delete()
|
||||
instance.artist.delete()
|
||||
Loading…
Add table
Add a link
Reference in a new issue