mirror of
https://code.eliotberriot.com/funkwhale/funkwhale.git
synced 2025-10-05 10:19:26 +02:00
See #170: cover on tracks and artists
This commit is contained in:
parent
db1cb30df8
commit
71b400a9b8
34 changed files with 582 additions and 254 deletions
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.2.9 on 2020-01-16 16:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('common', '0006_content'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='attachment',
|
||||
name='url',
|
||||
field=models.URLField(max_length=500, null=True),
|
||||
),
|
||||
]
|
|
@ -175,7 +175,12 @@ def get_file_path(instance, filename):
|
|||
|
||||
class AttachmentQuerySet(models.QuerySet):
|
||||
def attached(self, include=True):
|
||||
related_fields = ["covered_album", "mutation_attachment"]
|
||||
related_fields = [
|
||||
"covered_album",
|
||||
"mutation_attachment",
|
||||
"covered_track",
|
||||
"covered_artist",
|
||||
]
|
||||
query = None
|
||||
for field in related_fields:
|
||||
field_query = ~models.Q(**{field: None})
|
||||
|
@ -195,7 +200,7 @@ class AttachmentQuerySet(models.QuerySet):
|
|||
|
||||
class Attachment(models.Model):
|
||||
# Remote URL where the attachment can be fetched
|
||||
url = models.URLField(max_length=500, unique=True, null=True)
|
||||
url = models.URLField(max_length=500, null=True)
|
||||
uuid = models.UUIDField(unique=True, db_index=True, default=uuid.uuid4)
|
||||
# Actor associated with the attachment
|
||||
actor = models.ForeignKey(
|
||||
|
|
|
@ -85,8 +85,6 @@ class MutationSerializer(serializers.Serializer):
|
|||
|
||||
|
||||
class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer):
|
||||
serialized_relations = {}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# we force partial mode, because update mutations are partial
|
||||
kwargs.setdefault("partial", True)
|
||||
|
@ -105,13 +103,14 @@ class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer):
|
|||
return super().validate(validated_data)
|
||||
|
||||
def db_serialize(self, validated_data):
|
||||
serialized_relations = self.get_serialized_relations()
|
||||
data = {}
|
||||
# ensure model fields are serialized properly
|
||||
for key, value in list(validated_data.items()):
|
||||
if not isinstance(value, models.Model):
|
||||
data[key] = value
|
||||
continue
|
||||
field = self.serialized_relations[key]
|
||||
field = serialized_relations[key]
|
||||
data[key] = getattr(value, field)
|
||||
return data
|
||||
|
||||
|
@ -120,7 +119,7 @@ class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer):
|
|||
# we use our serialized_relations configuration
|
||||
# to ensure we store ids instead of model instances in our json
|
||||
# payload
|
||||
for field, attr in self.serialized_relations.items():
|
||||
for field, attr in self.get_serialized_relations().items():
|
||||
try:
|
||||
obj = data[field]
|
||||
except KeyError:
|
||||
|
@ -139,10 +138,13 @@ class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer):
|
|||
return get_update_previous_state(
|
||||
obj,
|
||||
*list(validated_data.keys()),
|
||||
serialized_relations=self.serialized_relations,
|
||||
serialized_relations=self.get_serialized_relations(),
|
||||
handlers=self.get_previous_state_handlers(),
|
||||
)
|
||||
|
||||
def get_serialized_relations(self):
|
||||
return {}
|
||||
|
||||
def get_previous_state_handlers(self):
|
||||
return {}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from django.core.files.base import ContentFile
|
||||
from django.utils.deconstruct import deconstructible
|
||||
|
||||
import bleach.sanitizer
|
||||
import logging
|
||||
import markdown
|
||||
import os
|
||||
import shutil
|
||||
|
@ -13,6 +15,8 @@ from django.conf import settings
|
|||
from django import urls
|
||||
from django.db import models, transaction
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def rename_file(instance, field_name, new_name, allow_missing_file=False):
|
||||
field = getattr(instance, field_name)
|
||||
|
@ -306,3 +310,41 @@ def attach_content(obj, field, content_data):
|
|||
setattr(obj, field, content_obj)
|
||||
obj.save(update_fields=[field])
|
||||
return content_obj
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def attach_file(obj, field, file_data, fetch=False):
|
||||
from . import models
|
||||
from . import tasks
|
||||
|
||||
existing = getattr(obj, "{}_id".format(field))
|
||||
if existing:
|
||||
getattr(obj, field).delete()
|
||||
|
||||
if not file_data:
|
||||
return
|
||||
|
||||
extensions = {"image/jpeg": "jpg", "image/png": "png", "image/gif": "gif"}
|
||||
extension = extensions.get(file_data["mimetype"], "jpg")
|
||||
attachment = models.Attachment(mimetype=file_data["mimetype"])
|
||||
|
||||
filename = "cover-{}.{}".format(obj.uuid, extension)
|
||||
if "url" in file_data:
|
||||
attachment.url = file_data["url"]
|
||||
else:
|
||||
f = ContentFile(file_data["content"])
|
||||
attachment.file.save(filename, f, save=False)
|
||||
|
||||
if not attachment.file and fetch:
|
||||
try:
|
||||
tasks.fetch_remote_attachment(attachment, filename=filename, save=False)
|
||||
except Exception as e:
|
||||
logger.warn("Cannot download attachment at url %s: %s", attachment.url, e)
|
||||
attachment = None
|
||||
|
||||
if attachment:
|
||||
attachment.save()
|
||||
|
||||
setattr(obj, field, attachment)
|
||||
obj.save(update_fields=[field])
|
||||
return attachment
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue