mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-03 15:59:18 +02:00
Resolve "Per-user libraries" (use !368 instead)
This commit is contained in:
parent
b0ca181016
commit
2ea21994ee
144 changed files with 6749 additions and 5347 deletions
|
@ -3,6 +3,7 @@ import uuid
|
|||
|
||||
from django.conf import settings
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
@ -11,6 +12,8 @@ from funkwhale_api.common import session
|
|||
from funkwhale_api.common import utils as common_utils
|
||||
from funkwhale_api.music import utils as music_utils
|
||||
|
||||
from . import utils as federation_utils
|
||||
|
||||
TYPE_CHOICES = [
|
||||
("Person", "Person"),
|
||||
("Application", "Application"),
|
||||
|
@ -20,15 +23,43 @@ TYPE_CHOICES = [
|
|||
]
|
||||
|
||||
|
||||
def empty_dict():
|
||||
return {}
|
||||
|
||||
|
||||
class FederationMixin(models.Model):
|
||||
# federation id/url
|
||||
fid = models.URLField(unique=True, max_length=500, db_index=True)
|
||||
url = models.URLField(max_length=500, null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class ActorQuerySet(models.QuerySet):
|
||||
def local(self, include=True):
|
||||
return self.exclude(user__isnull=include)
|
||||
|
||||
def with_current_usage(self):
|
||||
qs = self
|
||||
for s in ["pending", "skipped", "errored", "finished"]:
|
||||
qs = qs.annotate(
|
||||
**{
|
||||
"_usage_{}".format(s): models.Sum(
|
||||
"libraries__files__size",
|
||||
filter=models.Q(libraries__files__import_status=s),
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
return qs
|
||||
|
||||
|
||||
class Actor(models.Model):
|
||||
ap_type = "Actor"
|
||||
|
||||
url = models.URLField(unique=True, max_length=500, db_index=True)
|
||||
fid = models.URLField(unique=True, max_length=500, db_index=True)
|
||||
url = models.URLField(max_length=500, null=True, blank=True)
|
||||
outbox_url = models.URLField(max_length=500)
|
||||
inbox_url = models.URLField(max_length=500)
|
||||
following_url = models.URLField(max_length=500, null=True, blank=True)
|
||||
|
@ -63,11 +94,14 @@ class Actor(models.Model):
|
|||
|
||||
@property
|
||||
def private_key_id(self):
|
||||
return "{}#main-key".format(self.url)
|
||||
return "{}#main-key".format(self.fid)
|
||||
|
||||
@property
|
||||
def mention_username(self):
|
||||
return "@{}@{}".format(self.preferred_username, self.domain)
|
||||
def full_username(self):
|
||||
return "{}@{}".format(self.preferred_username, self.domain)
|
||||
|
||||
def __str__(self):
|
||||
return "{}@{}".format(self.preferred_username, self.domain)
|
||||
|
||||
def save(self, **kwargs):
|
||||
lowercase_fields = ["domain"]
|
||||
|
@ -104,26 +138,98 @@ class Actor(models.Model):
|
|||
follows = self.received_follows.filter(approved=True)
|
||||
return self.followers.filter(pk__in=follows.values_list("actor", flat=True))
|
||||
|
||||
def should_autoapprove_follow(self, actor):
|
||||
return False
|
||||
|
||||
class Follow(models.Model):
|
||||
ap_type = "Follow"
|
||||
def get_user(self):
|
||||
try:
|
||||
return self.user
|
||||
except ObjectDoesNotExist:
|
||||
return None
|
||||
|
||||
def get_current_usage(self):
|
||||
actor = self.__class__.objects.filter(pk=self.pk).with_current_usage().get()
|
||||
data = {}
|
||||
for s in ["pending", "skipped", "errored", "finished"]:
|
||||
data[s] = getattr(actor, "_usage_{}".format(s)) or 0
|
||||
|
||||
data["total"] = sum(data.values())
|
||||
return data
|
||||
|
||||
|
||||
class InboxItemQuerySet(models.QuerySet):
|
||||
def local(self, include=True):
|
||||
return self.exclude(actor__user__isnull=include)
|
||||
|
||||
|
||||
class InboxItem(models.Model):
|
||||
actor = models.ForeignKey(
|
||||
Actor, related_name="inbox_items", on_delete=models.CASCADE
|
||||
)
|
||||
activity = models.ForeignKey(
|
||||
"Activity", related_name="inbox_items", on_delete=models.CASCADE
|
||||
)
|
||||
is_delivered = models.BooleanField(default=False)
|
||||
type = models.CharField(max_length=10, choices=[("to", "to"), ("cc", "cc")])
|
||||
last_delivery_date = models.DateTimeField(null=True, blank=True)
|
||||
delivery_attempts = models.PositiveIntegerField(default=0)
|
||||
|
||||
objects = InboxItemQuerySet.as_manager()
|
||||
|
||||
|
||||
class Activity(models.Model):
|
||||
actor = models.ForeignKey(
|
||||
Actor, related_name="outbox_activities", on_delete=models.CASCADE
|
||||
)
|
||||
recipients = models.ManyToManyField(
|
||||
Actor, related_name="inbox_activities", through=InboxItem
|
||||
)
|
||||
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||
fid = models.URLField(unique=True, max_length=500, null=True, blank=True)
|
||||
url = models.URLField(max_length=500, null=True, blank=True)
|
||||
payload = JSONField(default=empty_dict, max_length=50000, encoder=DjangoJSONEncoder)
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
|
||||
|
||||
class AbstractFollow(models.Model):
|
||||
ap_type = "Follow"
|
||||
fid = models.URLField(unique=True, max_length=500, null=True, blank=True)
|
||||
uuid = models.UUIDField(default=uuid.uuid4, unique=True)
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
modification_date = models.DateTimeField(auto_now=True)
|
||||
approved = models.NullBooleanField(default=None)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def get_federation_id(self):
|
||||
return federation_utils.full_url(
|
||||
"{}#follows/{}".format(self.actor.fid, self.uuid)
|
||||
)
|
||||
|
||||
|
||||
class Follow(AbstractFollow):
|
||||
actor = models.ForeignKey(
|
||||
Actor, related_name="emitted_follows", on_delete=models.CASCADE
|
||||
)
|
||||
target = models.ForeignKey(
|
||||
Actor, related_name="received_follows", on_delete=models.CASCADE
|
||||
)
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
modification_date = models.DateTimeField(auto_now=True)
|
||||
approved = models.NullBooleanField(default=None)
|
||||
|
||||
class Meta:
|
||||
unique_together = ["actor", "target"]
|
||||
|
||||
def get_federation_url(self):
|
||||
return "{}#follows/{}".format(self.actor.url, self.uuid)
|
||||
|
||||
class LibraryFollow(AbstractFollow):
|
||||
actor = models.ForeignKey(
|
||||
Actor, related_name="library_follows", on_delete=models.CASCADE
|
||||
)
|
||||
target = models.ForeignKey(
|
||||
"music.Library", related_name="received_follows", on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ["actor", "target"]
|
||||
|
||||
|
||||
class Library(models.Model):
|
||||
|
@ -167,7 +273,9 @@ class LibraryTrack(models.Model):
|
|||
artist_name = models.CharField(max_length=500)
|
||||
album_title = models.CharField(max_length=500)
|
||||
title = models.CharField(max_length=500)
|
||||
metadata = JSONField(default={}, max_length=10000, encoder=DjangoJSONEncoder)
|
||||
metadata = JSONField(
|
||||
default=empty_dict, max_length=10000, encoder=DjangoJSONEncoder
|
||||
)
|
||||
|
||||
@property
|
||||
def mbid(self):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue