kopia lustrzana https://dev.funkwhale.audio/funkwhale/funkwhale
See #272: linting and changelog
rodzic
ac4bba816d
commit
bcd22eb38c
|
@ -3,7 +3,7 @@ import re
|
|||
from django.db.models import Q
|
||||
|
||||
|
||||
QUERY_REGEX = re.compile('(((?P<key>\w+):)?(?P<value>"[^"]+"|[\S]+))')
|
||||
QUERY_REGEX = re.compile(r'(((?P<key>\w+):)?(?P<value>"[^"]+"|[\S]+))')
|
||||
|
||||
|
||||
def parse_query(query):
|
||||
|
|
|
@ -209,12 +209,7 @@ class AlbumQuerySet(models.QuerySet):
|
|||
|
||||
def with_prefetched_tracks_and_playable_uploads(self, actor):
|
||||
tracks = Track.objects.with_playable_uploads(actor)
|
||||
return self.prefetch_related(
|
||||
models.Prefetch(
|
||||
'tracks',
|
||||
queryset=tracks,
|
||||
)
|
||||
)
|
||||
return self.prefetch_related(models.Prefetch("tracks", queryset=tracks))
|
||||
|
||||
|
||||
class Album(APIModelMixin):
|
||||
|
@ -413,13 +408,9 @@ class TrackQuerySet(models.QuerySet):
|
|||
return self.exclude(uploads__in=files).distinct()
|
||||
|
||||
def with_playable_uploads(self, actor):
|
||||
uploads = Upload.objects.playable_by(actor).select_related('track')
|
||||
uploads = Upload.objects.playable_by(actor).select_related("track")
|
||||
return self.prefetch_related(
|
||||
models.Prefetch(
|
||||
'uploads',
|
||||
queryset=uploads,
|
||||
to_attr='playable_uploads'
|
||||
)
|
||||
models.Prefetch("uploads", queryset=uploads, to_attr="playable_uploads")
|
||||
)
|
||||
|
||||
|
||||
|
@ -763,11 +754,13 @@ class Upload(models.Model):
|
|||
# we create the version with an empty file, then
|
||||
# we'll write to it
|
||||
f = ContentFile(b"")
|
||||
version = self.versions.create(mimetype=mimetype, bitrate=self.bitrate or 128000, size=0)
|
||||
version = self.versions.create(
|
||||
mimetype=mimetype, bitrate=self.bitrate or 128000, size=0
|
||||
)
|
||||
# we keep the same name, but we update the extension
|
||||
new_name = os.path.splitext(
|
||||
os.path.basename(self.audio_file.name)
|
||||
)[0] + '.{}'.format(format)
|
||||
new_name = os.path.splitext(os.path.basename(self.audio_file.name))[
|
||||
0
|
||||
] + ".{}".format(format)
|
||||
version.audio_file.save(new_name, f)
|
||||
utils.transcode_file(
|
||||
input=self.audio_file,
|
||||
|
@ -776,18 +769,18 @@ class Upload(models.Model):
|
|||
output_format=utils.MIMETYPE_TO_EXTENSION[mimetype],
|
||||
)
|
||||
version.size = version.audio_file.size
|
||||
version.save(update_fields=['size'])
|
||||
version.save(update_fields=["size"])
|
||||
|
||||
return version
|
||||
|
||||
|
||||
MIMETYPE_CHOICES = [
|
||||
(mt, ext) for ext, mt in utils.AUDIO_EXTENSIONS_AND_MIMETYPE
|
||||
]
|
||||
MIMETYPE_CHOICES = [(mt, ext) for ext, mt in utils.AUDIO_EXTENSIONS_AND_MIMETYPE]
|
||||
|
||||
|
||||
class UploadVersion(models.Model):
|
||||
upload = models.ForeignKey(Upload, related_name='versions', on_delete=models.CASCADE)
|
||||
upload = models.ForeignKey(
|
||||
Upload, related_name="versions", on_delete=models.CASCADE
|
||||
)
|
||||
mimetype = models.CharField(max_length=50, choices=MIMETYPE_CHOICES)
|
||||
creation_date = models.DateTimeField(default=timezone.now)
|
||||
accessed_date = models.DateTimeField(null=True, blank=True)
|
||||
|
@ -796,7 +789,7 @@ class UploadVersion(models.Model):
|
|||
size = models.IntegerField()
|
||||
|
||||
class Meta:
|
||||
unique_together = ('upload', 'mimetype', 'bitrate')
|
||||
unique_together = ("upload", "mimetype", "bitrate")
|
||||
|
||||
@property
|
||||
def filename(self):
|
||||
|
|
|
@ -200,8 +200,8 @@ class SubsonicViewSet(viewsets.GenericViewSet):
|
|||
if not upload:
|
||||
return response.Response(status=404)
|
||||
|
||||
format = data.get('format', 'raw')
|
||||
if format == 'raw':
|
||||
format = data.get("format", "raw")
|
||||
if format == "raw":
|
||||
format = None
|
||||
return music_views.handle_serve(upload=upload, user=request.user, format=format)
|
||||
|
||||
|
|
|
@ -206,14 +206,18 @@ def test_stream(f, db, logged_in_api_client, factories, mocker, queryset_equal_q
|
|||
playable_by.assert_called_once_with(music_models.Track.objects.all(), None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("format,expected", [("mp3", 'mp3'), ("raw", None)])
|
||||
@pytest.mark.parametrize("format,expected", [("mp3", "mp3"), ("raw", None)])
|
||||
def test_stream_format(format, expected, logged_in_api_client, factories, mocker):
|
||||
url = reverse("api:subsonic-stream")
|
||||
mocked_serve = mocker.patch.object(music_views, "handle_serve", return_value=Response())
|
||||
mocked_serve = mocker.patch.object(
|
||||
music_views, "handle_serve", return_value=Response()
|
||||
)
|
||||
upload = factories["music.Upload"](playable=True)
|
||||
response = logged_in_api_client.get(url, {"id": upload.track.pk, "format": format})
|
||||
|
||||
mocked_serve.assert_called_once_with(upload=upload, user=logged_in_api_client.user, format=expected)
|
||||
mocked_serve.assert_called_once_with(
|
||||
upload=upload, user=logged_in_api_client.user, format=expected
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ def test_import_files_skip_if_path_already_imported(factories, mocker):
|
|||
)
|
||||
|
||||
call_command(
|
||||
"import_files", str(library.uuid), path, async=False, interactive=False
|
||||
"import_files", str(library.uuid), path, async_=False, interactive=False
|
||||
)
|
||||
assert library.uploads.count() == 1
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
Audio transcoding is back! (#272)
|
||||
|
||||
|
||||
Audio transcoding is back!
|
||||
--------------------------
|
||||
|
||||
After removal of our first, buggy transcoding implementation, we're proud to announce
|
||||
that this feature is back. It is enabled by default, and can be configured/disabled
|
||||
in your instance settings!
|
||||
|
||||
This feature works in the browser, with federated/non-federated tracks and using Subsonic clients.
|
||||
Transcoded tracks are generated on the fly, and cached for a configurable amount of time,
|
||||
to reduce the load on the server.
|
Ładowanie…
Reference in New Issue