AudioCollection to import job and track file creation

merge-requests/154/head
Eliot Berriot 2018-04-05 23:26:41 +02:00
rodzic 4d6e894b62
commit 363acca53d
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: DD6965E2476E5C27
4 zmienionych plików z 114 dodań i 2 usunięć

Wyświetl plik

@ -0,0 +1,18 @@
# Generated by Django 2.0.3 on 2018-04-05 16:35
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('federation', '0004_followrequest'),
]
operations = [
migrations.AddField(
model_name='actor',
name='followers',
field=models.ManyToManyField(related_name='following', through='federation.Follow', to='federation.Actor'),
),
]

Wyświetl plik

@ -0,0 +1,47 @@
# Generated by Django 2.0.3 on 2018-04-05 18:30
from django.conf import settings
import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('federation', '0005_actor_followers'),
('music', '0022_importbatch_import_request'),
]
operations = [
migrations.AddField(
model_name='importbatch',
name='federation_actor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='import_batches', to='federation.Actor'),
),
migrations.AddField(
model_name='importbatch',
name='federation_source',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='importjob',
name='federation_source',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='importjob',
name='metadata',
field=django.contrib.postgres.fields.jsonb.JSONField(default={}),
),
migrations.AlterField(
model_name='importbatch',
name='source',
field=models.CharField(choices=[('api', 'api'), ('shell', 'shell'), ('federation', 'federation')], default='api', max_length=30),
),
migrations.AlterField(
model_name='importbatch',
name='submitted_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='imports', to=settings.AUTH_USER_MODEL),
),
]

Wyświetl plik

@ -8,6 +8,7 @@ import markdown
from django.conf import settings from django.conf import settings
from django.db import models from django.db import models
from django.contrib.postgres.fields import JSONField
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files import File from django.core.files import File
from django.db.models.signals import post_save from django.db.models.signals import post_save
@ -65,6 +66,7 @@ class APIModelMixin(models.Model):
pass pass
return cleaned_data return cleaned_data
class Artist(APIModelMixin): class Artist(APIModelMixin):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@ -90,10 +92,19 @@ class Artist(APIModelMixin):
t.append(tag) t.append(tag)
return set(t) return set(t)
@classmethod
def get_or_create_from_name(cls, name, **kwargs):
kwargs.update({'name': name})
return cls.objects.get_or_create(
name__iexact=name,
defaults=kwargs)[0]
def import_artist(v): def import_artist(v):
a = Artist.get_or_create_from_api(mbid=v[0]['artist']['id'])[0] a = Artist.get_or_create_from_api(mbid=v[0]['artist']['id'])[0]
return a return a
def parse_date(v): def parse_date(v):
if len(v) == 4: if len(v) == 4:
return datetime.date(int(v), 1, 1) return datetime.date(int(v), 1, 1)
@ -108,6 +119,7 @@ def import_tracks(instance, cleaned_data, raw_data):
track_cleaned_data['position'] = int(track_data['position']) track_cleaned_data['position'] = int(track_data['position'])
track = importers.load(Track, track_cleaned_data, track_data, Track.import_hooks) track = importers.load(Track, track_cleaned_data, track_data, Track.import_hooks)
class Album(APIModelMixin): class Album(APIModelMixin):
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
artist = models.ForeignKey( artist = models.ForeignKey(
@ -170,6 +182,14 @@ class Album(APIModelMixin):
t.append(tag) t.append(tag)
return set(t) return set(t)
@classmethod
def get_or_create_from_title(cls, title, **kwargs):
kwargs.update({'title': title})
return cls.objects.get_or_create(
title__iexact=title,
defaults=kwargs)[0]
def import_tags(instance, cleaned_data, raw_data): def import_tags(instance, cleaned_data, raw_data):
MINIMUM_COUNT = 2 MINIMUM_COUNT = 2
tags_to_add = [] tags_to_add = []
@ -182,6 +202,7 @@ def import_tags(instance, cleaned_data, raw_data):
tags_to_add.append(tag_data['name']) tags_to_add.append(tag_data['name'])
instance.tags.add(*tags_to_add) instance.tags.add(*tags_to_add)
def import_album(v): def import_album(v):
a = Album.get_or_create_from_api(mbid=v[0]['id'])[0] a = Album.get_or_create_from_api(mbid=v[0]['id'])[0]
return a return a
@ -366,6 +387,13 @@ class Track(APIModelMixin):
self.mbid) self.mbid)
return settings.FUNKWHALE_URL + '/tracks/{}'.format(self.pk) return settings.FUNKWHALE_URL + '/tracks/{}'.format(self.pk)
@classmethod
def get_or_create_from_title(cls, title, **kwargs):
kwargs.update({'title': title})
return cls.objects.get_or_create(
title__iexact=title,
defaults=kwargs)[0]
class TrackFile(models.Model): class TrackFile(models.Model):
track = models.ForeignKey( track = models.ForeignKey(
@ -420,7 +448,8 @@ IMPORT_STATUS_CHOICES = (
class ImportBatch(models.Model): class ImportBatch(models.Model):
IMPORT_BATCH_SOURCES = [ IMPORT_BATCH_SOURCES = [
('api', 'api'), ('api', 'api'),
('shell', 'shell') ('shell', 'shell'),
('federation', 'federation'),
] ]
source = models.CharField( source = models.CharField(
max_length=30, default='api', choices=IMPORT_BATCH_SOURCES) max_length=30, default='api', choices=IMPORT_BATCH_SOURCES)
@ -428,6 +457,8 @@ class ImportBatch(models.Model):
submitted_by = models.ForeignKey( submitted_by = models.ForeignKey(
'users.User', 'users.User',
related_name='imports', related_name='imports',
null=True,
blank=True,
on_delete=models.CASCADE) on_delete=models.CASCADE)
status = models.CharField( status = models.CharField(
choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30) choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30)
@ -437,6 +468,16 @@ class ImportBatch(models.Model):
null=True, null=True,
blank=True, blank=True,
on_delete=models.CASCADE) on_delete=models.CASCADE)
federation_source = models.URLField(null=True, blank=True)
federation_actor = models.ForeignKey(
'federation.Actor',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='import_batches',
)
class Meta: class Meta:
ordering = ['-creation_date'] ordering = ['-creation_date']
@ -464,6 +505,8 @@ class ImportJob(models.Model):
choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30) choices=IMPORT_STATUS_CHOICES, default='pending', max_length=30)
audio_file = models.FileField( audio_file = models.FileField(
upload_to='imports/%Y/%m/%d', max_length=255, null=True, blank=True) upload_to='imports/%Y/%m/%d', max_length=255, null=True, blank=True)
federation_source = models.URLField(null=True, blank=True)
metadata = JSONField(default={})
class Meta: class Meta:
ordering = ('id', ) ordering = ('id', )

Wyświetl plik

@ -61,6 +61,7 @@ def test_import_job_from_federation_no_musicbrainz(factories):
job.refresh_from_db() job.refresh_from_db()
tf = job.track_file tf = job.track_file
assert tf.source == job.source
assert tf.track.title == 'Ping' assert tf.track.title == 'Ping'
assert tf.track.artist.name == 'Hello' assert tf.track.artist.name == 'Hello'
assert tf.track.album.title == 'World' assert tf.track.album.title == 'World'
@ -82,6 +83,7 @@ def test_import_job_from_federation_musicbrainz_recording(factories, mocker):
job.refresh_from_db() job.refresh_from_db()
tf = job.track_file tf = job.track_file
assert tf.source == job.source
assert tf.track == t assert tf.track == t
track_from_api.assert_called_once_with( track_from_api.assert_called_once_with(
mbid=tasks.get_mbid(job.metadata['recording'], 'recording')) mbid=tasks.get_mbid(job.metadata['recording'], 'recording'))
@ -103,6 +105,7 @@ def test_import_job_from_federation_musicbrainz_release(factories, mocker):
job.refresh_from_db() job.refresh_from_db()
tf = job.track_file tf = job.track_file
assert tf.source == job.source
assert tf.track.title == 'Ping' assert tf.track.title == 'Ping'
assert tf.track.artist == a.artist assert tf.track.artist == a.artist
assert tf.track.album == a assert tf.track.album == a
@ -127,6 +130,7 @@ def test_import_job_from_federation_musicbrainz_artist(factories, mocker):
job.refresh_from_db() job.refresh_from_db()
tf = job.track_file tf = job.track_file
assert tf.source == job.source
assert tf.track.title == 'Ping' assert tf.track.title == 'Ping'
assert tf.track.artist == a assert tf.track.artist == a
assert tf.track.album.artist == a assert tf.track.album.artist == a