Resolve "value too long for type character varying(255) during import_files"
This commit is contained in:
parent
1d323b8e2f
commit
6908f4bf74
|
@ -76,9 +76,9 @@ class ChannelMetadataSerializer(serializers.Serializer):
|
||||||
|
|
||||||
|
|
||||||
class ChannelCreateSerializer(serializers.Serializer):
|
class ChannelCreateSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
name = serializers.CharField(max_length=federation_models.MAX_LENGTHS["ACTOR_NAME"])
|
||||||
username = serializers.CharField(
|
username = serializers.CharField(
|
||||||
max_length=music_models.MAX_LENGTHS["ARTIST_NAME"],
|
max_length=federation_models.MAX_LENGTHS["ACTOR_NAME"],
|
||||||
validators=[users_serializers.ASCIIUsernameValidator()],
|
validators=[users_serializers.ASCIIUsernameValidator()],
|
||||||
)
|
)
|
||||||
description = common_serializers.ContentSerializer(allow_null=True)
|
description = common_serializers.ContentSerializer(allow_null=True)
|
||||||
|
@ -159,7 +159,7 @@ NOOP = object()
|
||||||
|
|
||||||
|
|
||||||
class ChannelUpdateSerializer(serializers.Serializer):
|
class ChannelUpdateSerializer(serializers.Serializer):
|
||||||
name = serializers.CharField(max_length=music_models.MAX_LENGTHS["ARTIST_NAME"])
|
name = serializers.CharField(max_length=federation_models.MAX_LENGTHS["ACTOR_NAME"])
|
||||||
description = common_serializers.ContentSerializer(allow_null=True)
|
description = common_serializers.ContentSerializer(allow_null=True)
|
||||||
tags = tags_serializers.TagsListField()
|
tags = tags_serializers.TagsListField()
|
||||||
content_category = serializers.ChoiceField(
|
content_category = serializers.ChoiceField(
|
||||||
|
@ -385,9 +385,7 @@ def get_channel_from_rss_url(url, raise_exception=False):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if parsed_feed.feed.get("rights"):
|
if parsed_feed.feed.get("rights"):
|
||||||
track_defaults["copyright"] = parsed_feed.feed.rights[
|
track_defaults["copyright"] = parsed_feed.feed.rights
|
||||||
: music_models.MAX_LENGTHS["COPYRIGHT"]
|
|
||||||
]
|
|
||||||
for entry in entries[: settings.PODCASTS_RSS_FEED_MAX_ITEMS]:
|
for entry in entries[: settings.PODCASTS_RSS_FEED_MAX_ITEMS]:
|
||||||
logger.debug("Importing feed item %s", entry.id)
|
logger.debug("Importing feed item %s", entry.id)
|
||||||
s = RssFeedItemSerializer(data=entry)
|
s = RssFeedItemSerializer(data=entry)
|
||||||
|
@ -547,9 +545,7 @@ class RssFeedSerializer(serializers.Serializer):
|
||||||
**artist_kwargs,
|
**artist_kwargs,
|
||||||
defaults={
|
defaults={
|
||||||
"attributed_to": service_actor,
|
"attributed_to": service_actor,
|
||||||
"name": validated_data["title"][
|
"name": validated_data["title"],
|
||||||
: music_models.MAX_LENGTHS["ARTIST_NAME"]
|
|
||||||
],
|
|
||||||
"content_category": "podcast",
|
"content_category": "podcast",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -752,16 +748,12 @@ class RssFeedItemSerializer(serializers.Serializer):
|
||||||
{
|
{
|
||||||
"disc_number": validated_data.get("itunes_season", 1) or 1,
|
"disc_number": validated_data.get("itunes_season", 1) or 1,
|
||||||
"position": validated_data.get("itunes_episode", 1) or 1,
|
"position": validated_data.get("itunes_episode", 1) or 1,
|
||||||
"title": validated_data["title"][
|
"title": validated_data["title"],
|
||||||
: music_models.MAX_LENGTHS["TRACK_TITLE"]
|
|
||||||
],
|
|
||||||
"artist": channel.artist,
|
"artist": channel.artist,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if "rights" in validated_data:
|
if "rights" in validated_data:
|
||||||
track_defaults["copyright"] = validated_data["rights"][
|
track_defaults["copyright"] = validated_data["rights"]
|
||||||
: music_models.MAX_LENGTHS["COPYRIGHT"]
|
|
||||||
]
|
|
||||||
|
|
||||||
if "published_parsed" in validated_data:
|
if "published_parsed" in validated_data:
|
||||||
track_defaults["creation_date"] = datetime.datetime.fromtimestamp(
|
track_defaults["creation_date"] = datetime.datetime.fromtimestamp(
|
||||||
|
|
|
@ -30,6 +30,10 @@ TYPE_CHOICES = [
|
||||||
("Service", "Service"),
|
("Service", "Service"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
MAX_LENGTHS = {
|
||||||
|
"ACTOR_NAME": 200,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def empty_dict():
|
def empty_dict():
|
||||||
return {}
|
return {}
|
||||||
|
@ -188,7 +192,7 @@ class Actor(models.Model):
|
||||||
followers_url = models.URLField(max_length=500, null=True, blank=True)
|
followers_url = models.URLField(max_length=500, null=True, blank=True)
|
||||||
shared_inbox_url = models.URLField(max_length=500, null=True, blank=True)
|
shared_inbox_url = models.URLField(max_length=500, null=True, blank=True)
|
||||||
type = models.CharField(choices=TYPE_CHOICES, default="Person", max_length=25)
|
type = models.CharField(choices=TYPE_CHOICES, default="Person", max_length=25)
|
||||||
name = models.CharField(max_length=200, null=True, blank=True)
|
name = models.CharField(max_length=MAX_LENGTHS["ACTOR_NAME"], null=True, blank=True)
|
||||||
domain = models.ForeignKey(Domain, on_delete=models.CASCADE, related_name="actors")
|
domain = models.ForeignKey(Domain, on_delete=models.CASCADE, related_name="actors")
|
||||||
summary = models.CharField(max_length=500, null=True, blank=True)
|
summary = models.CharField(max_length=500, null=True, blank=True)
|
||||||
summary_obj = models.ForeignKey(
|
summary_obj = models.ForeignKey(
|
||||||
|
|
|
@ -1796,7 +1796,7 @@ class ChannelUploadSerializer(jsonld.JsonLdSerializer):
|
||||||
id = serializers.URLField(max_length=500)
|
id = serializers.URLField(max_length=500)
|
||||||
type = serializers.ChoiceField(choices=[contexts.AS.Audio])
|
type = serializers.ChoiceField(choices=[contexts.AS.Audio])
|
||||||
url = LinkListSerializer(keep_mediatype=["audio/*"], min_length=1)
|
url = LinkListSerializer(keep_mediatype=["audio/*"], min_length=1)
|
||||||
name = TruncatedCharField(truncate_length=music_models.MAX_LENGTHS["TRACK_TITLE"])
|
name = serializers.CharField()
|
||||||
published = serializers.DateTimeField(required=False)
|
published = serializers.DateTimeField(required=False)
|
||||||
duration = serializers.IntegerField(min_value=0, required=False)
|
duration = serializers.IntegerField(min_value=0, required=False)
|
||||||
position = serializers.IntegerField(min_value=0, allow_null=True, required=False)
|
position = serializers.IntegerField(min_value=0, allow_null=True, required=False)
|
||||||
|
@ -1804,8 +1804,7 @@ class ChannelUploadSerializer(jsonld.JsonLdSerializer):
|
||||||
album = serializers.URLField(max_length=500, required=False)
|
album = serializers.URLField(max_length=500, required=False)
|
||||||
license = serializers.URLField(allow_null=True, required=False)
|
license = serializers.URLField(allow_null=True, required=False)
|
||||||
attributedTo = serializers.URLField(max_length=500, required=False)
|
attributedTo = serializers.URLField(max_length=500, required=False)
|
||||||
copyright = TruncatedCharField(
|
copyright = serializers.CharField(
|
||||||
truncate_length=music_models.MAX_LENGTHS["COPYRIGHT"],
|
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Generated by Django 3.2.16 on 2022-11-18 21:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('music', '0056_alter_artist_content_category'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='album',
|
||||||
|
name='title',
|
||||||
|
field=models.TextField(),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='artist',
|
||||||
|
name='name',
|
||||||
|
field=models.TextField(),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='track',
|
||||||
|
name='copyright',
|
||||||
|
field=models.TextField(blank=True, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='track',
|
||||||
|
name='title',
|
||||||
|
field=models.TextField(),
|
||||||
|
),
|
||||||
|
]
|
|
@ -37,14 +37,6 @@ from . import importers, metadata, utils
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
MAX_LENGTHS = {
|
|
||||||
"ARTIST_NAME": 255,
|
|
||||||
"ALBUM_TITLE": 255,
|
|
||||||
"TRACK_TITLE": 255,
|
|
||||||
"COPYRIGHT": 500,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ARTIST_CONTENT_CATEGORY_CHOICES = [
|
ARTIST_CONTENT_CATEGORY_CHOICES = [
|
||||||
("music", "music"),
|
("music", "music"),
|
||||||
("podcast", "podcast"),
|
("podcast", "podcast"),
|
||||||
|
@ -213,7 +205,7 @@ class ArtistQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
|
||||||
|
|
||||||
|
|
||||||
class Artist(APIModelMixin):
|
class Artist(APIModelMixin):
|
||||||
name = models.CharField(max_length=MAX_LENGTHS["ARTIST_NAME"])
|
name = models.TextField()
|
||||||
federation_namespace = "artists"
|
federation_namespace = "artists"
|
||||||
musicbrainz_model = "artist"
|
musicbrainz_model = "artist"
|
||||||
musicbrainz_mapping = {
|
musicbrainz_mapping = {
|
||||||
|
@ -338,7 +330,7 @@ class AlbumQuerySet(common_models.LocalFromFidQuerySet, models.QuerySet):
|
||||||
|
|
||||||
|
|
||||||
class Album(APIModelMixin):
|
class Album(APIModelMixin):
|
||||||
title = models.CharField(max_length=MAX_LENGTHS["ALBUM_TITLE"])
|
title = models.TextField()
|
||||||
artist = models.ForeignKey(Artist, related_name="albums", on_delete=models.CASCADE)
|
artist = models.ForeignKey(Artist, related_name="albums", on_delete=models.CASCADE)
|
||||||
release_date = models.DateField(null=True, blank=True, db_index=True)
|
release_date = models.DateField(null=True, blank=True, db_index=True)
|
||||||
release_group_id = models.UUIDField(null=True, blank=True)
|
release_group_id = models.UUIDField(null=True, blank=True)
|
||||||
|
@ -496,7 +488,7 @@ def get_artist(release_list):
|
||||||
|
|
||||||
class Track(APIModelMixin):
|
class Track(APIModelMixin):
|
||||||
mbid = models.UUIDField(db_index=True, null=True, blank=True)
|
mbid = models.UUIDField(db_index=True, null=True, blank=True)
|
||||||
title = models.CharField(max_length=MAX_LENGTHS["TRACK_TITLE"])
|
title = models.TextField()
|
||||||
artist = models.ForeignKey(Artist, related_name="tracks", on_delete=models.CASCADE)
|
artist = models.ForeignKey(Artist, related_name="tracks", on_delete=models.CASCADE)
|
||||||
disc_number = models.PositiveIntegerField(null=True, blank=True)
|
disc_number = models.PositiveIntegerField(null=True, blank=True)
|
||||||
position = models.PositiveIntegerField(null=True, blank=True)
|
position = models.PositiveIntegerField(null=True, blank=True)
|
||||||
|
@ -520,9 +512,7 @@ class Track(APIModelMixin):
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
related_name="attributed_tracks",
|
related_name="attributed_tracks",
|
||||||
)
|
)
|
||||||
copyright = models.CharField(
|
copyright = models.TextField(null=True, blank=True)
|
||||||
max_length=MAX_LENGTHS["COPYRIGHT"], null=True, blank=True
|
|
||||||
)
|
|
||||||
description = models.ForeignKey(
|
description = models.ForeignKey(
|
||||||
"common.Content", null=True, blank=True, on_delete=models.SET_NULL
|
"common.Content", null=True, blank=True, on_delete=models.SET_NULL
|
||||||
)
|
)
|
||||||
|
|
|
@ -563,9 +563,7 @@ def _get_track(data, attributed_to=None, **forced_values):
|
||||||
else:
|
else:
|
||||||
album_artists = getter(data, "album", "artists", default=artists) or artists
|
album_artists = getter(data, "album", "artists", default=artists) or artists
|
||||||
album_artist_data = album_artists[0]
|
album_artist_data = album_artists[0]
|
||||||
album_artist_name = truncate(
|
album_artist_name = album_artist_data.get("name")
|
||||||
album_artist_data.get("name"), models.MAX_LENGTHS["ARTIST_NAME"]
|
|
||||||
)
|
|
||||||
if album_artist_name == artist_name:
|
if album_artist_name == artist_name:
|
||||||
album_artist = artist
|
album_artist = artist
|
||||||
else:
|
else:
|
||||||
|
@ -609,9 +607,7 @@ def _get_track(data, attributed_to=None, **forced_values):
|
||||||
# get / create album
|
# get / create album
|
||||||
if "album" in data:
|
if "album" in data:
|
||||||
album_data = data["album"]
|
album_data = data["album"]
|
||||||
album_title = truncate(
|
album_title = album_data["title"]
|
||||||
album_data["title"], models.MAX_LENGTHS["ALBUM_TITLE"]
|
|
||||||
)
|
|
||||||
album_fid = album_data.get("fid", None)
|
album_fid = album_data.get("fid", None)
|
||||||
|
|
||||||
if album_mbid:
|
if album_mbid:
|
||||||
|
@ -647,11 +643,7 @@ def _get_track(data, attributed_to=None, **forced_values):
|
||||||
else:
|
else:
|
||||||
album = None
|
album = None
|
||||||
# get / create track
|
# get / create track
|
||||||
track_title = (
|
track_title = forced_values["title"] if "title" in forced_values else data["title"]
|
||||||
forced_values["title"]
|
|
||||||
if "title" in forced_values
|
|
||||||
else truncate(data["title"], models.MAX_LENGTHS["TRACK_TITLE"])
|
|
||||||
)
|
|
||||||
position = (
|
position = (
|
||||||
forced_values["position"]
|
forced_values["position"]
|
||||||
if "position" in forced_values
|
if "position" in forced_values
|
||||||
|
@ -670,7 +662,7 @@ def _get_track(data, attributed_to=None, **forced_values):
|
||||||
copyright = (
|
copyright = (
|
||||||
forced_values["copyright"]
|
forced_values["copyright"]
|
||||||
if "copyright" in forced_values
|
if "copyright" in forced_values
|
||||||
else truncate(data.get("copyright"), models.MAX_LENGTHS["COPYRIGHT"])
|
else data.get("copyright")
|
||||||
)
|
)
|
||||||
description = (
|
description = (
|
||||||
{"text": forced_values["description"], "content_type": "text/markdown"}
|
{"text": forced_values["description"], "content_type": "text/markdown"}
|
||||||
|
@ -736,7 +728,7 @@ def _get_track(data, attributed_to=None, **forced_values):
|
||||||
def get_artist(artist_data, attributed_to, from_activity_id):
|
def get_artist(artist_data, attributed_to, from_activity_id):
|
||||||
artist_mbid = artist_data.get("mbid", None)
|
artist_mbid = artist_data.get("mbid", None)
|
||||||
artist_fid = artist_data.get("fid", None)
|
artist_fid = artist_data.get("fid", None)
|
||||||
artist_name = truncate(artist_data["name"], models.MAX_LENGTHS["ARTIST_NAME"])
|
artist_name = artist_data["name"]
|
||||||
|
|
||||||
if artist_mbid:
|
if artist_mbid:
|
||||||
query = Q(mbid=artist_mbid)
|
query = Q(mbid=artist_mbid)
|
||||||
|
|
|
@ -80,32 +80,6 @@ def test_can_create_track_from_file_metadata_attributed_to(factories, mocker):
|
||||||
assert track.artist.attributed_to == actor
|
assert track.artist.attributed_to == actor
|
||||||
|
|
||||||
|
|
||||||
def test_can_create_track_from_file_metadata_truncates_too_long_values(
|
|
||||||
factories, mocker
|
|
||||||
):
|
|
||||||
metadata = {
|
|
||||||
"title": "a" * 5000,
|
|
||||||
"artists": [{"name": "b" * 5000}],
|
|
||||||
"album": {"title": "c" * 5000, "release_date": datetime.date(2012, 8, 15)},
|
|
||||||
"position": 4,
|
|
||||||
"disc_number": 2,
|
|
||||||
"copyright": "d" * 5000,
|
|
||||||
}
|
|
||||||
|
|
||||||
track = tasks.get_track_from_import_metadata(metadata)
|
|
||||||
|
|
||||||
assert track.title == metadata["title"][: models.MAX_LENGTHS["TRACK_TITLE"]]
|
|
||||||
assert track.copyright == metadata["copyright"][: models.MAX_LENGTHS["COPYRIGHT"]]
|
|
||||||
assert (
|
|
||||||
track.album.title
|
|
||||||
== metadata["album"]["title"][: models.MAX_LENGTHS["ALBUM_TITLE"]]
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
track.artist.name
|
|
||||||
== metadata["artists"][0]["name"][: models.MAX_LENGTHS["ARTIST_NAME"]]
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_can_create_track_from_file_metadata_featuring(factories):
|
def test_can_create_track_from_file_metadata_featuring(factories):
|
||||||
metadata = {
|
metadata = {
|
||||||
"title": "Whole Lotta Love",
|
"title": "Whole Lotta Love",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Allow arbritrary length names for artists, albums and tracks
|
Loading…
Reference in New Issue