kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
See #170: store and compute modification date on artists
rodzic
b5297150f0
commit
1654044a9f
|
@ -28,10 +28,17 @@ class ChannelFilter(moderation_filters.HiddenContentFilterSet):
|
|||
subscribed = django_filters.BooleanFilter(
|
||||
field_name="_", method="filter_subscribed"
|
||||
)
|
||||
ordering = django_filters.OrderingFilter(
|
||||
# tuple-mapping retains order
|
||||
fields=(
|
||||
("creation_date", "creation_date"),
|
||||
("artist__modification_date", "modification_date"),
|
||||
)
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = models.Channel
|
||||
fields = ["q", "scope", "tag", "subscribed"]
|
||||
fields = ["q", "scope", "tag", "subscribed", "ordering"]
|
||||
hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["CHANNEL"]
|
||||
|
||||
def filter_subscribed(self, queryset, name, value):
|
||||
|
|
|
@ -384,7 +384,12 @@ def get_channel_from_rss_url(url, raise_exception=False):
|
|||
library=channel.library,
|
||||
delete_existing=True,
|
||||
)
|
||||
|
||||
latest_upload_date = max([upload.creation_date for upload in uploads])
|
||||
if (
|
||||
not channel.artist.modification_date
|
||||
or channel.artist.modification_date < latest_upload_date
|
||||
):
|
||||
common_utils.update_modification_date(channel.artist)
|
||||
return channel, uploads
|
||||
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ class RelatedField(serializers.RelatedField):
|
|||
self.display_value(item),
|
||||
)
|
||||
for item in queryset
|
||||
if self.serializer
|
||||
]
|
||||
)
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import datetime
|
||||
|
||||
from django.core.files.base import ContentFile
|
||||
from django.utils.deconstruct import deconstructible
|
||||
|
||||
|
@ -14,6 +16,7 @@ from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
|
|||
from django.conf import settings
|
||||
from django import urls
|
||||
from django.db import models, transaction
|
||||
from django.utils import timezone
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -405,3 +408,17 @@ def get_mimetype_from_ext(path):
|
|||
def get_audio_mimetype(mt):
|
||||
aliases = {"audio/x-mp3": "audio/mpeg", "audio/mpeg3": "audio/mpeg"}
|
||||
return aliases.get(mt, mt)
|
||||
|
||||
|
||||
def update_modification_date(obj, field="modification_date"):
|
||||
IGNORE_DELAY = 60
|
||||
current_value = getattr(obj, field)
|
||||
now = timezone.now()
|
||||
ignore = current_value is not None and current_value < now - datetime.timedelta(
|
||||
seconds=IGNORE_DELAY
|
||||
)
|
||||
if ignore:
|
||||
setattr(obj, field, now)
|
||||
obj.__class__.objects.filter(pk=obj.pk).update(**{field: now})
|
||||
|
||||
return now
|
||||
|
|
|
@ -5,7 +5,7 @@ from . import models
|
|||
|
||||
@admin.register(models.Artist)
|
||||
class ArtistAdmin(admin.ModelAdmin):
|
||||
list_display = ["name", "mbid", "creation_date"]
|
||||
list_display = ["name", "mbid", "creation_date", "modification_date"]
|
||||
search_fields = ["name", "mbid"]
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 3.0.4 on 2020-03-19 12:49
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('music', '0050_auto_20200129_1344'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='album',
|
||||
name='cover',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='artist',
|
||||
name='modification_date',
|
||||
field=models.DateTimeField(db_index=True, default=django.utils.timezone.now),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='upload',
|
||||
name='import_status',
|
||||
field=models.CharField(choices=[('draft', 'Draft'), ('pending', 'Pending'), ('finished', 'Finished'), ('errored', 'Errored'), ('skipped', 'Skipped')], default='pending', max_length=25),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='uploadversion',
|
||||
name='mimetype',
|
||||
field=models.CharField(choices=[('audio/mpeg3', 'mp3'), ('audio/x-mp3', 'mp3'), ('audio/mpeg', 'mp3'), ('video/ogg', 'ogg'), ('audio/ogg', 'ogg'), ('audio/opus', 'opus'), ('audio/x-m4a', 'aac'), ('audio/x-m4a', 'm4a'), ('audio/x-flac', 'flac'), ('audio/flac', 'flac')], max_length=50),
|
||||
),
|
||||
]
|
|
@ -251,7 +251,7 @@ class Artist(APIModelMixin):
|
|||
choices=ARTIST_CONTENT_CATEGORY_CHOICES,
|
||||
null=True,
|
||||
)
|
||||
|
||||
modification_date = models.DateTimeField(default=timezone.now, db_index=True)
|
||||
api = musicbrainz.api.artists
|
||||
objects = ArtistQuerySet.as_manager()
|
||||
|
||||
|
|
|
@ -160,6 +160,7 @@ def serialize_artist_simple(artist):
|
|||
"mbid": str(artist.mbid),
|
||||
"name": artist.name,
|
||||
"creation_date": DATETIME_FIELD.to_representation(artist.creation_date),
|
||||
"modification_date": DATETIME_FIELD.to_representation(artist.modification_date),
|
||||
"is_local": artist.is_local,
|
||||
"content_category": artist.content_category,
|
||||
}
|
||||
|
|
|
@ -289,6 +289,8 @@ def process_upload(upload, update_denormalization=True):
|
|||
"bitrate",
|
||||
]
|
||||
)
|
||||
if channel:
|
||||
common_utils.update_modification_date(channel.artist)
|
||||
|
||||
if update_denormalization:
|
||||
models.TrackActor.create_entries(
|
||||
|
|
|
@ -129,7 +129,7 @@ class ArtistViewSet(
|
|||
required_scope = "libraries"
|
||||
anonymous_policy = "setting"
|
||||
filterset_class = filters.ArtistFilter
|
||||
ordering_fields = ("id", "name", "creation_date")
|
||||
ordering_fields = ("id", "name", "creation_date", "modification_date")
|
||||
|
||||
fetches = federation_decorators.fetches_route()
|
||||
mutations = common_decorators.mutations_route(types=["update"])
|
||||
|
@ -186,7 +186,12 @@ class AlbumViewSet(
|
|||
permission_classes = [oauth_permissions.ScopePermission]
|
||||
required_scope = "libraries"
|
||||
anonymous_policy = "setting"
|
||||
ordering_fields = ("creation_date", "release_date", "title")
|
||||
ordering_fields = (
|
||||
"creation_date",
|
||||
"release_date",
|
||||
"title",
|
||||
"artist__modification_date",
|
||||
)
|
||||
filterset_class = filters.AlbumFilter
|
||||
|
||||
fetches = federation_decorators.fetches_route()
|
||||
|
@ -335,6 +340,7 @@ class TrackViewSet(
|
|||
"position",
|
||||
"disc_number",
|
||||
"artist__name",
|
||||
"artist__modification_date",
|
||||
)
|
||||
fetches = federation_decorators.fetches_route()
|
||||
mutations = common_decorators.mutations_route(types=["update"])
|
||||
|
|
|
@ -834,9 +834,9 @@ def test_get_channel_from_rss_url(db, r_mock, mocker):
|
|||
</rss>
|
||||
"""
|
||||
parsed_feed = feedparser.parse(xml_payload)
|
||||
|
||||
r_mock.get(rss_url, text=xml_payload)
|
||||
|
||||
update_modification_date = mocker.spy(common_utils, "update_modification_date")
|
||||
feed_init = mocker.spy(serializers.RssFeedSerializer, "__init__")
|
||||
feed_save = mocker.spy(serializers.RssFeedSerializer, "save")
|
||||
item_init = mocker.spy(serializers.RssFeedItemSerializer, "__init__")
|
||||
|
@ -865,6 +865,7 @@ def test_get_channel_from_rss_url(db, r_mock, mocker):
|
|||
library=channel.library,
|
||||
delete_existing=True,
|
||||
)
|
||||
update_modification_date.assert_called_once_with(channel.artist)
|
||||
|
||||
|
||||
def test_get_channel_from_rss_honor_mrf_inbox_before_http(
|
||||
|
|
|
@ -6,6 +6,7 @@ import uuid
|
|||
from django.core.paginator import Paginator
|
||||
from django.utils import timezone
|
||||
|
||||
from funkwhale_api.common import utils as common_utils
|
||||
from funkwhale_api.federation import serializers as federation_serializers
|
||||
from funkwhale_api.federation import jsonld
|
||||
from funkwhale_api.federation import utils as federation_utils
|
||||
|
@ -1040,6 +1041,8 @@ def test_process_channel_upload_forces_artist_and_attributed_to(
|
|||
factories, mocker, faker
|
||||
):
|
||||
channel = factories["audio.Channel"](attributed_to__local=True)
|
||||
update_modification_date = mocker.spy(common_utils, "update_modification_date")
|
||||
|
||||
attachment = factories["common.Attachment"](actor=channel.attributed_to)
|
||||
import_metadata = {
|
||||
"title": "Real title",
|
||||
|
@ -1081,6 +1084,8 @@ def test_process_channel_upload_forces_artist_and_attributed_to(
|
|||
assert upload.track.attributed_to == channel.attributed_to
|
||||
assert upload.track.attachment_cover == attachment
|
||||
|
||||
update_modification_date.assert_called_once_with(channel.artist)
|
||||
|
||||
|
||||
def test_process_upload_uses_import_metadata_if_valid(factories, mocker):
|
||||
track = factories["music.Track"]()
|
||||
|
|
Ładowanie…
Reference in New Issue