import uuid from django.db import models from django.urls import reverse from django.utils import timezone from funkwhale_api.common import fields from funkwhale_api.common import models as common_models from funkwhale_api.federation import models as federation_models from funkwhale_api.federation import utils as federation_utils from funkwhale_api.music.models import Track FAVORITE_PRIVACY_LEVEL_CHOICES = [ (k, l) for k, l in fields.PRIVACY_LEVEL_CHOICES if k != "followers" ] class TrackFavoriteQuerySet(models.QuerySet, common_models.LocalFromFidQuerySet): def viewable_by(self, actor): if actor is None: return self.filter(actor__user__privacy_level="everyone") if hasattr(actor, "user"): me_query = models.Q(actor__user__privacy_level="me", actor=actor) me_query = models.Q(actor__user__privacy_level="me", actor=actor) instance_query = models.Q( actor__user__privacy_level="instance", actor__domain=actor.domain ) instance_actor_query = models.Q( actor__user__privacy_level="instance", actor__domain=actor.domain ) return self.filter( me_query | instance_query | instance_actor_query | models.Q(actor__user__privacy_level="everyone") ) class TrackFavorite(federation_models.FederationMixin): uuid = models.UUIDField(default=uuid.uuid4, unique=True) creation_date = models.DateTimeField(default=timezone.now) actor = models.ForeignKey( "federation.Actor", related_name="track_favorites", on_delete=models.CASCADE, null=False, blank=False, ) track = models.ForeignKey( Track, related_name="track_favorites", on_delete=models.CASCADE ) source = models.CharField(max_length=100, null=True, blank=True) federation_namespace = "likes" objects = TrackFavoriteQuerySet.as_manager() class Meta: unique_together = ("track", "actor") ordering = ("-creation_date",) @classmethod def add(cls, track, actor): favorite, created = cls.objects.get_or_create(actor=actor, track=track) return favorite def get_activity_url(self): return f"{self.actor.get_absolute_url()}/favorites/tracks/{self.pk}" def get_absolute_url(self): return f"/library/tracks/{self.track.pk}" def get_federation_id(self): if self.fid: return self.fid return federation_utils.full_url( reverse( f"federation:music:{self.federation_namespace}-detail", kwargs={"uuid": self.uuid}, ) ) def save(self, **kwargs): if not self.pk and not self.fid: self.fid = self.get_federation_id() return super().save(**kwargs)