発散解像度 -divergence resolution-
Signed-off-by: Shin'ya Minazuki <shinyoukai@laidback.moe>
This commit is contained in:
parent
1ff613dee6
commit
01bb65f8da
457 changed files with 929 additions and 602 deletions
0
api/funkwhale_api/history/__init__.py
Normal file
0
api/funkwhale_api/history/__init__.py
Normal file
16
api/funkwhale_api/history/activities.py
Normal file
16
api/funkwhale_api/history/activities.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from funkwhale_api.activity import record
|
||||
from funkwhale_api.common import channels
|
||||
|
||||
from . import serializers
|
||||
|
||||
record.registry.register_serializer(serializers.ListeningActivitySerializer)
|
||||
|
||||
|
||||
@record.registry.register_consumer("history.Listening")
|
||||
def broadcast_listening_to_instance_activity(data, obj):
|
||||
if obj.user.privacy_level not in ["instance", "everyone"]:
|
||||
return
|
||||
|
||||
channels.group_send(
|
||||
"instance_activity", {"type": "event.send", "text": "", "data": data}
|
||||
)
|
||||
10
api/funkwhale_api/history/admin.py
Normal file
10
api/funkwhale_api/history/admin.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
from funkwhale_api.common import admin
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
@admin.register(models.Listening)
|
||||
class ListeningAdmin(admin.ModelAdmin):
|
||||
list_display = ["track", "creation_date", "user", "session_key"]
|
||||
search_fields = ["track__name", "user__username"]
|
||||
list_select_related = ["user", "track"]
|
||||
14
api/funkwhale_api/history/factories.py
Normal file
14
api/funkwhale_api/history/factories.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import factory
|
||||
|
||||
from funkwhale_api.factories import NoUpdateOnCreate, registry
|
||||
from funkwhale_api.music import factories
|
||||
from funkwhale_api.users.factories import UserFactory
|
||||
|
||||
|
||||
@registry.register
|
||||
class ListeningFactory(NoUpdateOnCreate, factory.django.DjangoModelFactory):
|
||||
user = factory.SubFactory(UserFactory)
|
||||
track = factory.SubFactory(factories.TrackFactory)
|
||||
|
||||
class Meta:
|
||||
model = "history.Listening"
|
||||
19
api/funkwhale_api/history/filters.py
Normal file
19
api/funkwhale_api/history/filters.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import django_filters
|
||||
|
||||
from funkwhale_api.common import filters as common_filters
|
||||
from funkwhale_api.moderation import filters as moderation_filters
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class ListeningFilter(moderation_filters.HiddenContentFilterSet):
|
||||
username = django_filters.CharFilter("user__username")
|
||||
domain = django_filters.CharFilter("user__actor__domain_id")
|
||||
scope = common_filters.ActorScopeFilter(actor_field="user__actor", distinct=True)
|
||||
|
||||
class Meta:
|
||||
model = models.Listening
|
||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[
|
||||
"LISTENING"
|
||||
]
|
||||
fields = []
|
||||
60
api/funkwhale_api/history/migrations/0001_initial.py
Normal file
60
api/funkwhale_api/history/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("music", "0008_auto_20160529_1456"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="Listening",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
verbose_name="ID",
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
auto_created=True,
|
||||
),
|
||||
),
|
||||
(
|
||||
"end_date",
|
||||
models.DateTimeField(
|
||||
null=True, blank=True, default=django.utils.timezone.now
|
||||
),
|
||||
),
|
||||
(
|
||||
"session_key",
|
||||
models.CharField(null=True, blank=True, max_length=100),
|
||||
),
|
||||
(
|
||||
"track",
|
||||
models.ForeignKey(
|
||||
related_name="listenings",
|
||||
to="music.Track",
|
||||
on_delete=models.CASCADE,
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
related_name="listenings",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
on_delete=models.CASCADE,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"ordering": ("-end_date",)},
|
||||
)
|
||||
]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Generated by Django 2.0.3 on 2018-03-25 14:33
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [("history", "0001_initial")]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="listening", options={"ordering": ("-creation_date",)}
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="listening", old_name="end_date", new_name="creation_date"
|
||||
),
|
||||
]
|
||||
0
api/funkwhale_api/history/migrations/__init__.py
Normal file
0
api/funkwhale_api/history/migrations/__init__.py
Normal file
25
api/funkwhale_api/history/models.py
Normal file
25
api/funkwhale_api/history/models.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from funkwhale_api.music.models import Track
|
||||
|
||||
|
||||
class Listening(models.Model):
|
||||
creation_date = models.DateTimeField(default=timezone.now, null=True, blank=True)
|
||||
track = models.ForeignKey(
|
||||
Track, related_name="listenings", on_delete=models.CASCADE
|
||||
)
|
||||
user = models.ForeignKey(
|
||||
"users.User",
|
||||
related_name="listenings",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
session_key = models.CharField(max_length=100, null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ("-creation_date",)
|
||||
|
||||
def get_activity_url(self):
|
||||
return f"{self.user.get_activity_url()}/listenings/tracks/{self.pk}"
|
||||
58
api/funkwhale_api/history/serializers.py
Normal file
58
api/funkwhale_api/history/serializers.py
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
|
||||
from funkwhale_api.activity import serializers as activity_serializers
|
||||
from funkwhale_api.federation import serializers as federation_serializers
|
||||
from funkwhale_api.music.serializers import TrackActivitySerializer, TrackSerializer
|
||||
from funkwhale_api.users.serializers import UserActivitySerializer, UserBasicSerializer
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class ListeningActivitySerializer(activity_serializers.ModelSerializer):
|
||||
type = serializers.SerializerMethodField()
|
||||
object = TrackActivitySerializer(source="track")
|
||||
actor = UserActivitySerializer(source="user")
|
||||
published = serializers.DateTimeField(source="creation_date")
|
||||
|
||||
class Meta:
|
||||
model = models.Listening
|
||||
fields = ["id", "local_id", "object", "type", "actor", "published"]
|
||||
|
||||
def get_actor(self, obj):
|
||||
return UserActivitySerializer(obj.user).data
|
||||
|
||||
def get_type(self, obj):
|
||||
return "Listen"
|
||||
|
||||
|
||||
class ListeningSerializer(serializers.ModelSerializer):
|
||||
track = TrackSerializer(read_only=True)
|
||||
user = UserBasicSerializer(read_only=True)
|
||||
actor = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = models.Listening
|
||||
fields = ("id", "user", "track", "creation_date", "actor")
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data["user"] = self.context["user"]
|
||||
|
||||
return super().create(validated_data)
|
||||
|
||||
@extend_schema_field(federation_serializers.APIActorSerializer)
|
||||
def get_actor(self, obj):
|
||||
actor = obj.user.actor
|
||||
if actor:
|
||||
return federation_serializers.APIActorSerializer(actor).data
|
||||
|
||||
|
||||
class ListeningWriteSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Listening
|
||||
fields = ("id", "user", "track", "creation_date")
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data["user"] = self.context["user"]
|
||||
|
||||
return super().create(validated_data)
|
||||
8
api/funkwhale_api/history/urls.py
Normal file
8
api/funkwhale_api/history/urls.py
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
from funkwhale_api.common import routers
|
||||
|
||||
from . import views
|
||||
|
||||
router = routers.OptionalSlashRouter()
|
||||
router.register(r"listenings", views.ListeningViewSet, "listenings")
|
||||
|
||||
urlpatterns = router.urls
|
||||
64
api/funkwhale_api/history/views.py
Normal file
64
api/funkwhale_api/history/views.py
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
from django.db.models import Prefetch
|
||||
from rest_framework import mixins, viewsets
|
||||
|
||||
from config import plugins
|
||||
from funkwhale_api.activity import record
|
||||
from funkwhale_api.common import fields, permissions
|
||||
from funkwhale_api.music import utils as music_utils
|
||||
from funkwhale_api.music.models import Track
|
||||
from funkwhale_api.users.oauth import permissions as oauth_permissions
|
||||
|
||||
from . import filters, models, serializers
|
||||
|
||||
|
||||
class ListeningViewSet(
|
||||
mixins.CreateModelMixin,
|
||||
mixins.ListModelMixin,
|
||||
mixins.RetrieveModelMixin,
|
||||
viewsets.GenericViewSet,
|
||||
):
|
||||
serializer_class = serializers.ListeningSerializer
|
||||
queryset = models.Listening.objects.all().select_related(
|
||||
"user__actor__attachment_icon"
|
||||
)
|
||||
|
||||
permission_classes = [
|
||||
oauth_permissions.ScopePermission,
|
||||
permissions.OwnerPermission,
|
||||
]
|
||||
required_scope = "listenings"
|
||||
anonymous_policy = "setting"
|
||||
owner_checks = ["write"]
|
||||
filterset_class = filters.ListeningFilter
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.request.method.lower() in ["head", "get", "options"]:
|
||||
return serializers.ListeningSerializer
|
||||
return serializers.ListeningWriteSerializer
|
||||
|
||||
def perform_create(self, serializer):
|
||||
r = super().perform_create(serializer)
|
||||
plugins.trigger_hook(
|
||||
plugins.LISTENING_CREATED,
|
||||
listening=serializer.instance,
|
||||
confs=plugins.get_confs(self.request.user),
|
||||
)
|
||||
record.send(serializer.instance)
|
||||
return r
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
queryset = queryset.filter(
|
||||
fields.privacy_level_query(self.request.user, "user__privacy_level")
|
||||
)
|
||||
tracks = Track.objects.with_playable_uploads(
|
||||
music_utils.get_actor_from_request(self.request)
|
||||
).select_related(
|
||||
"artist", "album__artist", "attributed_to", "artist__attachment_cover"
|
||||
)
|
||||
return queryset.prefetch_related(Prefetch("track", queryset=tracks))
|
||||
|
||||
def get_serializer_context(self):
|
||||
context = super().get_serializer_context()
|
||||
context["user"] = self.request.user
|
||||
return context
|
||||
Loading…
Add table
Add a link
Reference in a new issue