Now store track file mimetype in database
This commit is contained in:
parent
937c55fdd5
commit
ddea5f1825
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 2.0.2 on 2018-02-18 15:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('music', '0017_auto_20171227_1728'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='trackfile',
|
||||||
|
name='mimetype',
|
||||||
|
field=models.CharField(blank=True, max_length=200, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='importjob',
|
||||||
|
name='source',
|
||||||
|
field=models.CharField(max_length=500),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='importjob',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(choices=[('pending', 'Pending'), ('finished', 'Finished'), ('errored', 'Errored'), ('skipped', 'Skipped')], default='pending', max_length=30),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,34 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
from funkwhale_api.music.utils import guess_mimetype
|
||||||
|
|
||||||
|
|
||||||
|
def populate_mimetype(apps, schema_editor):
|
||||||
|
TrackFile = apps.get_model("music", "TrackFile")
|
||||||
|
|
||||||
|
for tf in TrackFile.objects.filter(audio_file__isnull=False, mimetype__isnull=True).only('audio_file'):
|
||||||
|
try:
|
||||||
|
tf.mimetype = guess_mimetype(tf.audio_file)
|
||||||
|
except Exception as e:
|
||||||
|
print('Error on track file {}: {}'.format(tf.pk, e))
|
||||||
|
continue
|
||||||
|
print('Track file {}: {}'.format(tf.pk, tf.mimetype))
|
||||||
|
tf.save(update_fields=['mimetype'])
|
||||||
|
|
||||||
|
|
||||||
|
def rewind(apps, schema_editor):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('music', '0018_auto_20180218_1554'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(populate_mimetype, rewind),
|
||||||
|
]
|
|
@ -18,6 +18,7 @@ from versatileimagefield.fields import VersatileImageField
|
||||||
from funkwhale_api import downloader
|
from funkwhale_api import downloader
|
||||||
from funkwhale_api import musicbrainz
|
from funkwhale_api import musicbrainz
|
||||||
from . import importers
|
from . import importers
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
class APIModelMixin(models.Model):
|
class APIModelMixin(models.Model):
|
||||||
|
@ -364,6 +365,7 @@ class TrackFile(models.Model):
|
||||||
source = models.URLField(null=True, blank=True)
|
source = models.URLField(null=True, blank=True)
|
||||||
duration = models.IntegerField(null=True, blank=True)
|
duration = models.IntegerField(null=True, blank=True)
|
||||||
acoustid_track_id = models.UUIDField(null=True, blank=True)
|
acoustid_track_id = models.UUIDField(null=True, blank=True)
|
||||||
|
mimetype = models.CharField(null=True, blank=True, max_length=200)
|
||||||
|
|
||||||
def download_file(self):
|
def download_file(self):
|
||||||
# import the track file, since there is not any
|
# import the track file, since there is not any
|
||||||
|
@ -393,6 +395,10 @@ class TrackFile(models.Model):
|
||||||
self.track.full_name,
|
self.track.full_name,
|
||||||
os.path.splitext(self.audio_file.name)[-1])
|
os.path.splitext(self.audio_file.name)[-1])
|
||||||
|
|
||||||
|
def save(self, **kwargs):
|
||||||
|
if not self.mimetype and self.audio_file:
|
||||||
|
self.mimetype = utils.guess_mimetype(self.audio_file)
|
||||||
|
return super().save(**kwargs)
|
||||||
|
|
||||||
class ImportBatch(models.Model):
|
class ImportBatch(models.Model):
|
||||||
IMPORT_BATCH_SOURCES = [
|
IMPORT_BATCH_SOURCES = [
|
||||||
|
|
|
@ -28,7 +28,14 @@ class TrackFileSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.TrackFile
|
model = models.TrackFile
|
||||||
fields = ('id', 'path', 'duration', 'source', 'filename', 'track')
|
fields = (
|
||||||
|
'id',
|
||||||
|
'path',
|
||||||
|
'duration',
|
||||||
|
'source',
|
||||||
|
'filename',
|
||||||
|
'mimetype',
|
||||||
|
'track')
|
||||||
|
|
||||||
def get_path(self, o):
|
def get_path(self, o):
|
||||||
url = o.path
|
url = o.path
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
|
import magic
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
|
|
||||||
def normalize_query(query_string,
|
def normalize_query(query_string,
|
||||||
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
|
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
|
||||||
normspace=re.compile(r'\s{2,}').sub):
|
normspace=re.compile(r'\s{2,}').sub):
|
||||||
|
@ -15,6 +17,7 @@ def normalize_query(query_string,
|
||||||
'''
|
'''
|
||||||
return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
|
return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
|
||||||
|
|
||||||
|
|
||||||
def get_query(query_string, search_fields):
|
def get_query(query_string, search_fields):
|
||||||
''' Returns a query, that is a combination of Q objects. That combination
|
''' Returns a query, that is a combination of Q objects. That combination
|
||||||
aims to search keywords within a model by testing the given search fields.
|
aims to search keywords within a model by testing the given search fields.
|
||||||
|
@ -35,3 +38,8 @@ def get_query(query_string, search_fields):
|
||||||
else:
|
else:
|
||||||
query = query & or_query
|
query = query & or_query
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
|
def guess_mimetype(f):
|
||||||
|
b = min(100000, f.size)
|
||||||
|
return magic.from_buffer(f.read(b), mime=True)
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from funkwhale_api.music import models
|
from funkwhale_api.music import models
|
||||||
from funkwhale_api.music import importers
|
from funkwhale_api.music import importers
|
||||||
from funkwhale_api.music import tasks
|
from funkwhale_api.music import tasks
|
||||||
|
|
||||||
|
DATA_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
|
||||||
def test_can_store_release_group_id_on_album(factories):
|
def test_can_store_release_group_id_on_album(factories):
|
||||||
album = factories['music.Album']()
|
album = factories['music.Album']()
|
||||||
|
@ -48,3 +51,15 @@ def test_import_job_is_bound_to_track_file(factories, mocker):
|
||||||
tasks.import_job_run(import_job_id=job.pk)
|
tasks.import_job_run(import_job_id=job.pk)
|
||||||
job.refresh_from_db()
|
job.refresh_from_db()
|
||||||
assert job.track_file.track == track
|
assert job.track_file.track == track
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('extention,mimetype', [
|
||||||
|
('ogg', 'audio/ogg'),
|
||||||
|
('mp3', 'audio/mpeg'),
|
||||||
|
])
|
||||||
|
def test_audio_track_mime_type(extention, mimetype, factories):
|
||||||
|
|
||||||
|
name = '.'.join(['test', extention])
|
||||||
|
path = os.path.join(DATA_DIR, name)
|
||||||
|
tf = factories['music.TrackFile'](audio_file__from_path=path)
|
||||||
|
|
||||||
|
assert tf.mimetype == mimetype
|
||||||
|
|
Loading…
Reference in New Issue