Merge branch 'round-of-bugfixes' into 'develop'
Round of bugfixes for 0.21-rc2 Closes #1079 See merge request funkwhale/funkwhale!1100
This commit is contained in:
commit
35e2cb243c
|
@ -4,6 +4,7 @@ import django_filters
|
||||||
|
|
||||||
from funkwhale_api.common import fields
|
from funkwhale_api.common import fields
|
||||||
from funkwhale_api.common import filters as common_filters
|
from funkwhale_api.common import filters as common_filters
|
||||||
|
from funkwhale_api.federation import actors
|
||||||
from funkwhale_api.moderation import filters as moderation_filters
|
from funkwhale_api.moderation import filters as moderation_filters
|
||||||
|
|
||||||
from . import models
|
from . import models
|
||||||
|
@ -28,6 +29,7 @@ class ChannelFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
subscribed = django_filters.BooleanFilter(
|
subscribed = django_filters.BooleanFilter(
|
||||||
field_name="_", method="filter_subscribed"
|
field_name="_", method="filter_subscribed"
|
||||||
)
|
)
|
||||||
|
external = django_filters.BooleanFilter(field_name="_", method="filter_external")
|
||||||
ordering = django_filters.OrderingFilter(
|
ordering = django_filters.OrderingFilter(
|
||||||
# tuple-mapping retains order
|
# tuple-mapping retains order
|
||||||
fields=(
|
fields=(
|
||||||
|
@ -38,7 +40,7 @@ class ChannelFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Channel
|
model = models.Channel
|
||||||
fields = ["q", "scope", "tag", "subscribed", "ordering"]
|
fields = ["q", "scope", "tag", "subscribed", "ordering", "external"]
|
||||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["CHANNEL"]
|
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["CHANNEL"]
|
||||||
|
|
||||||
def filter_subscribed(self, queryset, name, value):
|
def filter_subscribed(self, queryset, name, value):
|
||||||
|
@ -56,6 +58,18 @@ class ChannelFilter(moderation_filters.HiddenContentFilterSet):
|
||||||
else:
|
else:
|
||||||
return queryset.exclude(query)
|
return queryset.exclude(query)
|
||||||
|
|
||||||
|
def filter_external(self, queryset, name, value):
|
||||||
|
query = Q(
|
||||||
|
attributed_to=actors.get_service_actor(),
|
||||||
|
actor__preferred_username__startswith="rssfeed-",
|
||||||
|
)
|
||||||
|
if value is True:
|
||||||
|
queryset = queryset.filter(query)
|
||||||
|
if value is False:
|
||||||
|
queryset = queryset.exclude(query)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class IncludeChannelsFilterSet(django_filters.FilterSet):
|
class IncludeChannelsFilterSet(django_filters.FilterSet):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -200,11 +200,9 @@ class ChannelUpdateSerializer(serializers.Serializer):
|
||||||
obj.save(update_fields=["metadata"])
|
obj.save(update_fields=["metadata"])
|
||||||
|
|
||||||
if "description" in validated_data:
|
if "description" in validated_data:
|
||||||
description_obj = common_utils.attach_content(
|
common_utils.attach_content(
|
||||||
obj.artist, "description", validated_data["description"]
|
obj.artist, "description", validated_data["description"]
|
||||||
)
|
)
|
||||||
if description_obj:
|
|
||||||
actor_update_fields.append(("summary", description_obj.rendered))
|
|
||||||
|
|
||||||
if "name" in validated_data:
|
if "name" in validated_data:
|
||||||
actor_update_fields.append(("name", validated_data["name"]))
|
actor_update_fields.append(("name", validated_data["name"]))
|
||||||
|
|
|
@ -204,7 +204,8 @@ def get_api_response(request, url):
|
||||||
except urls.exceptions.Resolver404:
|
except urls.exceptions.Resolver404:
|
||||||
return http.HttpResponseNotFound()
|
return http.HttpResponseNotFound()
|
||||||
response = match.func(request, *match.args, **match.kwargs)
|
response = match.func(request, *match.args, **match.kwargs)
|
||||||
response.render()
|
if hasattr(response, "render"):
|
||||||
|
response.render()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
from funkwhale_api.audio import filters
|
from funkwhale_api.audio import filters
|
||||||
from funkwhale_api.audio import models
|
from funkwhale_api.audio import models
|
||||||
|
|
||||||
|
@ -30,3 +32,17 @@ def test_channel_filter_subscribed_false(factories, mocker, queryset_equal_list)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert filterset.qs == [other_channel]
|
assert filterset.qs == [other_channel]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("external, expected_index", [("true", 0), ("false", 1)])
|
||||||
|
def test_channel_filter_external(
|
||||||
|
external, expected_index, factories, mocker, queryset_equal_list
|
||||||
|
):
|
||||||
|
user = factories["users.User"](with_actor=True)
|
||||||
|
channels = [factories["audio.Channel"](external=True), factories["audio.Channel"]()]
|
||||||
|
qs = models.Channel.objects.all()
|
||||||
|
filterset = filters.ChannelFilter(
|
||||||
|
{"external": external}, request=mocker.Mock(user=user), queryset=qs
|
||||||
|
)
|
||||||
|
|
||||||
|
assert filterset.qs == [channels[expected_index]]
|
||||||
|
|
|
@ -184,9 +184,6 @@ def test_channel_serializer_update(factories, mocker):
|
||||||
sorted(channel.artist.tagged_items.values_list("tag__name", flat=True))
|
sorted(channel.artist.tagged_items.values_list("tag__name", flat=True))
|
||||||
== data["tags"]
|
== data["tags"]
|
||||||
)
|
)
|
||||||
assert channel.actor.summary == common_utils.render_html(
|
|
||||||
data["description"]["text"], "text/markdown"
|
|
||||||
)
|
|
||||||
assert channel.artist.description.text == data["description"]["text"]
|
assert channel.artist.description.text == data["description"]["text"]
|
||||||
assert channel.artist.description.content_type == "text/markdown"
|
assert channel.artist.description.content_type == "text/markdown"
|
||||||
assert channel.actor.name == data["name"]
|
assert channel.actor.name == data["name"]
|
||||||
|
|
|
@ -352,7 +352,7 @@ $sidebar-color: #2D2F33;
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
background: $sidebar-color;
|
background: $sidebar-color;
|
||||||
z-index: auto;
|
z-index: 1;
|
||||||
@include media(">desktop") {
|
@include media(">desktop") {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
|
@ -13,12 +13,11 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!isLoading && objects.length === 0">
|
<template v-if="!isLoading && objects.length === 0">
|
||||||
<div class="ui placeholder segment">
|
<empty-state @refresh="fetchData('tracks/')" :refresh="true">
|
||||||
<div class="ui icon header">
|
<p>
|
||||||
<i class="music icon"></i>
|
<translate translate-context="Content/Channels/*">You may need to subscribe to this channel to see its content.</translate>
|
||||||
No results matching your query
|
</p>
|
||||||
</div>
|
</empty-state>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -18,12 +18,11 @@
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!isLoading && objects.length === 0">
|
<template v-if="!isLoading && objects.length === 0">
|
||||||
<div class="ui placeholder segment">
|
<empty-state @refresh="fetchData('albums/')" :refresh="true">
|
||||||
<div class="ui icon header">
|
<p>
|
||||||
<i class="compact disc icon"></i>
|
<translate translate-context="Content/Channels/*">You may need to subscribe to this channel to see its contents.</translate>
|
||||||
No results matching your query
|
</p>
|
||||||
</div>
|
</empty-state>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<h3 class="ui header" >
|
<h3 class="ui header" >
|
||||||
<translate translate-context="*/*/*">New channels</translate>
|
<translate translate-context="*/*/*">New channels</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<channels-widget :show-modification-date="true" :limit="12" :filters="{ordering: '-creation_date'}"></channels-widget>
|
<channels-widget :show-modification-date="true" :limit="12" :filters="{ordering: '-creation_date', external: 'false'}"></channels-widget>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="ui head vertical stripe segment container">
|
<div class="ui head vertical stripe segment container">
|
||||||
<div class="ui stackable grid" v-if="object">
|
<div class="ui stackable grid" v-if="object">
|
||||||
<div class="ui five wide column">
|
<div class="ui five wide column">
|
||||||
<div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em; z-index: 5">
|
<div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;">
|
||||||
<i class="ellipsis vertical icon"></i>
|
<i class="ellipsis vertical icon"></i>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div v-if="isLoading" class="ui centered active inline loader"></div>
|
<div v-if="isLoading" class="ui centered active inline loader"></div>
|
||||||
<div class="ui stackable grid" v-else-if="object">
|
<div class="ui stackable grid" v-else-if="object">
|
||||||
<div class="ui five wide column">
|
<div class="ui five wide column">
|
||||||
<div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em; z-index: 5">
|
<div class="ui pointing dropdown icon small basic right floated button" ref="dropdown" v-dropdown="{direction: 'downward'}" style="position: absolute; right: 1em; top: 1em;">
|
||||||
<i class="ellipsis vertical icon"></i>
|
<i class="ellipsis vertical icon"></i>
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Reference in New Issue