diff --git a/funkwhale_api/common/utils.py b/funkwhale_api/common/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..ea531d614a7d927416b7a55604a1eaae7cd0d756 --- /dev/null +++ b/funkwhale_api/common/utils.py @@ -0,0 +1,18 @@ +import os + + +def rename_file(instance, field_name, new_name, allow_missing_file=False): + field = getattr(instance, field_name) + current_name, extension = os.path.splitext(field.name) + + new_name_with_extension = '{}{}'.format(new_name, extension) + try: + os.rename(field.path, new_name_with_extension) + except FileNotFoundError: + if not allow_missing_file: + raise + + initial_path = os.path.dirname(field.name) + field.name = os.path.join(initial_path, new_name_with_extension) + instance.save() + return new_name_with_extension diff --git a/funkwhale_api/downloader/downloader.py b/funkwhale_api/downloader/downloader.py index 0aac2370ac9652a138516f980e8569c903aaab5c..840185c89c5e7e1e6851eaa6be46ed27c6176724 100644 --- a/funkwhale_api/downloader/downloader.py +++ b/funkwhale_api/downloader/downloader.py @@ -5,9 +5,13 @@ from urllib.parse import quote_plus import youtube_dl - -def download(url, target_directory, extension='vorbis', bitrate=192): - target_path = os.path.join(target_directory, '%(id)s.ogg') +def download( + url, + target_directory, + name="%(id)s", + extension='vorbis', + bitrate=192): + target_path = os.path.join(target_directory, '{}.ogg'.format(name)) ydl_opts = { 'format': 'bestaudio/best', 'quiet': True, diff --git a/funkwhale_api/music/migrations/0011_rename_files.py b/funkwhale_api/music/migrations/0011_rename_files.py new file mode 100644 index 0000000000000000000000000000000000000000..869575b889a284ec6f373b6d190214d715c914b4 --- /dev/null +++ b/funkwhale_api/music/migrations/0011_rename_files.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals +import os + +from django.db import migrations, models +from funkwhale_api.common.utils import rename_file + +def rename_files(apps, schema_editor): + TrackFile = apps.get_model("music", "TrackFile") + qs = TrackFile.objects.select_related( + 'track__album__artist', 'track__artist') + for tf in qs: + try: + new_name = '{} - {} - {}'.format( + tf.track.artist.name, + tf.track.album.title, + tf.track.title, + ) + except AttributeError: + new_name = '{} - {}'.format( + tf.track.artist.name, + tf.track.title, + ) + rename_file( + instance=tf, + field_name='audio_file', + allow_missing_file=True, + new_name=new_name) + + +def rewind(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('music', '0010_auto_20160920_1742'), + ] + + operations = [ + migrations.AlterField( + model_name='trackfile', + name='audio_file', + field=models.FileField(upload_to='tracks/%Y/%m/%d', max_length=255), + ), + migrations.RunPython(rename_files, rewind), + ] diff --git a/funkwhale_api/music/models.py b/funkwhale_api/music/models.py index 092516decda3218952560693953dc2d6f13d18d4..4fa7717e2a6a58cc1b807dd54a0815a65f255cf8 100644 --- a/funkwhale_api/music/models.py +++ b/funkwhale_api/music/models.py @@ -316,9 +316,24 @@ class Track(APIModelMixin): def get_lyrics_url(self): return reverse('api:tracks-lyrics', kwargs={'pk': self.pk}) + @property + def full_name(self): + try: + return '{} - {} - {}'.format( + self.artist.name, + self.album.title, + self.title, + ) + except AttributeError: + return '{} - {}'.format( + self.artist.name, + self.title, + ) + + class TrackFile(models.Model): track = models.ForeignKey(Track, related_name='files') - audio_file = models.FileField(upload_to='tracks/%Y/%m/%d') + audio_file = models.FileField(upload_to='tracks/%Y/%m/%d', max_length=255) source = models.URLField(null=True, blank=True) duration = models.IntegerField(null=True, blank=True) @@ -326,7 +341,10 @@ class TrackFile(models.Model): # import the track file, since there is not any # we create a tmp dir for the download tmp_dir = tempfile.mkdtemp() - data = downloader.download(self.source, target_directory=tmp_dir) + data = downloader.download( + self.source, + name=self.track.full_name, + target_directory=tmp_dir) self.duration = data.get('duration', None) self.audio_file.save( os.path.basename(data['audio_file_path']),