diff --git a/api/v1_track_stems_download.go b/api/v1_track_stems_download.go index 58e6bd58..54eaf617 100644 --- a/api/v1_track_stems_download.go +++ b/api/v1_track_stems_download.go @@ -240,14 +240,20 @@ var audioExtensions = map[string]string{ "audio/ogg": ".ogg", } -// stemsZipFilename is the download filename, except that an original with no -// recorded filename gets its extension from the blob's content type rather -// than createFilename's .mp3, since the bytes are the original upload. +// stemsZipFilename is the download filename, except for an original with no +// recorded filename. createFilename gives that title + ".mp3", but the bytes +// are the original upload, so the extension comes from the blob's content +// type. Such titles often already end in the upload's extension ("DRUMS.wav"). func stemsZipFilename(t *dbv1.Track, contentType string) string { name := sanitizeZipName(createFilename(t)) if t.OrigFileCid.String != "" && t.OrigFilename.String == "" { if ext, ok := audioExtensions[strings.ToLower(contentType)]; ok { - name = strings.TrimSuffix(name, path.Ext(name)) + ext + title := sanitizeZipName(t.Title.String) + titleExt := strings.ToLower(path.Ext(title)) + if isAudioExtension(titleExt) { + title = strings.TrimSuffix(title, path.Ext(title)) + } + name = title + ext } } if name == "" || strings.HasPrefix(name, ".") { @@ -256,6 +262,15 @@ func stemsZipFilename(t *dbv1.Track, contentType string) string { return name } +func isAudioExtension(ext string) bool { + for _, e := range audioExtensions { + if e == ext { + return true + } + } + return false +} + func sanitizeZipName(name string) string { name = strings.Map(func(r rune) rune { switch { diff --git a/api/v1_track_stems_download_test.go b/api/v1_track_stems_download_test.go index 3bf3a4a5..2726b16c 100644 --- a/api/v1_track_stems_download_test.go +++ b/api/v1_track_stems_download_test.go @@ -174,6 +174,10 @@ func TestStemsZipFilename(t *testing.T) { } assert.Equal(t, "🍕DRUMS.wav", stemsZipFilename(track(map[string]string{"orig_cid": "Qm", "orig_filename": " 🍕DRUMS.wav"}), "audio/wav")) assert.Equal(t, "Bass.wav", stemsZipFilename(track(map[string]string{"title": "Bass", "orig_cid": "Qm"}), "audio/x-wav")) + assert.Equal(t, "🍕DRUMS.wav", stemsZipFilename(track(map[string]string{"title": " 🍕DRUMS.wav", "orig_cid": "Qm"}), "audio/wav")) + assert.Equal(t, "Bass.wav", stemsZipFilename(track(map[string]string{"title": "Bass.WAV", "orig_cid": "Qm"}), "audio/wav")) + assert.Equal(t, "Bass.flac", stemsZipFilename(track(map[string]string{"title": "Bass.wav", "orig_cid": "Qm"}), "audio/flac")) + assert.Equal(t, "Mix v1.2.wav", stemsZipFilename(track(map[string]string{"title": "Mix v1.2", "orig_cid": "Qm"}), "audio/wav")) assert.Equal(t, "Bass.mp3", stemsZipFilename(track(map[string]string{"title": "Bass"}), "audio/wav")) assert.Equal(t, "a_b.mp3", stemsZipFilename(track(map[string]string{"title": "a/b"}), "")) }