refactor podcast schema and generate unique episode paths (#373)

closes #350
This commit is contained in:
Senan Kelly
2023-09-21 00:01:16 +01:00
committed by GitHub
parent c13d17262f
commit 33f1f2e0cf
15 changed files with 401 additions and 193 deletions

56
fileutil/fileutil.go Normal file
View File

@@ -0,0 +1,56 @@
// TODO: this package shouldn't really exist. we can usually just attempt our normal filesystem operations
// and handle errors atomically. eg.
// - Safe could instead be try create file, handle error
// - Unique could be try create file, on err create file (1), etc
package fileutil
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)
var nonAlphaNumExpr = regexp.MustCompile("[^a-zA-Z0-9_.]+")
func Safe(filename string) string {
filename = nonAlphaNumExpr.ReplaceAllString(filename, "")
return filename
}
// try to find a unqiue file (or dir) name. incrementing like "example (1)"
func Unique(base, filename string) (string, error) {
return unique(base, filename, 0)
}
func unique(base, filename string, count uint) (string, error) {
var suffix string
if count > 0 {
suffix = fmt.Sprintf(" (%d)", count)
}
path := base + suffix
if filename != "" {
noExt := strings.TrimSuffix(filename, filepath.Ext(filename))
path = filepath.Join(base, noExt+suffix+filepath.Ext(filename))
}
_, err := os.Stat(path)
if os.IsNotExist(err) {
return path, nil
}
if err != nil {
return "", err
}
return unique(base, filename, count+1)
}
func First(path ...string) (string, error) {
var err error
for _, p := range path {
_, err = os.Stat(p)
if err == nil {
return p, nil
}
}
return "", err
}

56
fileutil/fileutil_test.go Normal file
View File

@@ -0,0 +1,56 @@
package fileutil
import (
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func TestUniquePath(t *testing.T) {
unq := func(base, filename string, count uint) string {
r, err := unique(base, filename, count)
require.NoError(t, err)
return r
}
require.Equal(t, "test/wow.mp3", unq("test", "wow.mp3", 0))
require.Equal(t, "test/wow (1).mp3", unq("test", "wow.mp3", 1))
require.Equal(t, "test/wow (2).mp3", unq("test", "wow.mp3", 2))
require.Equal(t, "test", unq("test", "", 0))
require.Equal(t, "test (1)", unq("test", "", 1))
base := filepath.Join(t.TempDir(), "a")
require.NoError(t, os.MkdirAll(base, os.ModePerm))
next := base + " (1)"
require.Equal(t, next, unq(base, "", 0))
require.NoError(t, os.MkdirAll(next, os.ModePerm))
next = base + " (2)"
require.Equal(t, next, unq(base, "", 0))
_, err := os.Create(filepath.Join(base, "test.mp3"))
require.NoError(t, err)
require.Equal(t, filepath.Join(base, "test (1).mp3"), unq(base, "test.mp3", 0))
}
func TestFirst(t *testing.T) {
base := t.TempDir()
name := filepath.Join(base, "test")
_, err := os.Create(name)
require.NoError(t, err)
p := func(name string) string {
return filepath.Join(base, name)
}
r, err := First(p("one"), p("two"), p("test"), p("four"))
require.NoError(t, err)
require.Equal(t, p("test"), r)
}