mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Import: Allow configuration of the destination file path #4666
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -1,7 +1,67 @@
|
|||||||
package customize
|
package customize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/photoprism/photoprism/pkg/clean"
|
||||||
|
)
|
||||||
|
|
||||||
// ImportSettings represents import settings.
|
// ImportSettings represents import settings.
|
||||||
type ImportSettings struct {
|
type ImportSettings struct {
|
||||||
Path string `json:"path" yaml:"Path"`
|
Path string `json:"path" yaml:"Path"`
|
||||||
Move bool `json:"move" yaml:"Move"`
|
Move bool `json:"move" yaml:"Move"`
|
||||||
|
Dest string `json:"dest" yaml:"Dest,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultImportDest specifies the default import destination file path in the Originals folder.
|
||||||
|
// The date and time placeholders are described at https://pkg.go.dev/time#Layout.
|
||||||
|
var DefaultImportDest = "2006/01/20060102_150405_82F63B78.jpg"
|
||||||
|
var ImportDestRegexp = regexp.MustCompile("^(?P<name>\\D*\\d{2,14}[\\-/_].*\\d{2,14}.*)(?P<checksum>[0-9a-fA-F]{8})(?P<count>\\.\\d{1,6}|\\.COUNT)?(?P<ext>\\.[0-9a-zA-Z]{2,8})$")
|
||||||
|
|
||||||
|
// GetPath returns the default import source path, or a custom path if set.
|
||||||
|
func (s *ImportSettings) GetPath() string {
|
||||||
|
if s.Path != "" {
|
||||||
|
return s.Path
|
||||||
|
}
|
||||||
|
|
||||||
|
return RootPath
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDest returns the default file import destination, or a custom pattern if set and valid.
|
||||||
|
func (s *ImportSettings) GetDest() string {
|
||||||
|
if dest := strings.Trim(clean.Path(s.Dest), "/."); dest == "" || dest != s.Dest {
|
||||||
|
s.Dest = ""
|
||||||
|
} else if ImportDestRegexp.MatchString(dest) {
|
||||||
|
s.Dest = dest
|
||||||
|
return dest
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultImportDest
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDestName returns the parsed import destination path and file name patterns.
|
||||||
|
func (s *ImportSettings) GetDestName() (pathName, fileName string) {
|
||||||
|
// Parse import destination pattern.
|
||||||
|
m := ImportDestRegexp.FindStringSubmatch(s.GetDest())
|
||||||
|
|
||||||
|
if len(m) < 4 {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split file path into file and path name.
|
||||||
|
pathName, fileName = filepath.Split(m[ImportDestRegexp.SubexpIndex("name")])
|
||||||
|
|
||||||
|
// Make sure path and file name are not empty.
|
||||||
|
if pathName == "" || fileName == "" {
|
||||||
|
pathName, fileName = filepath.Split(ImportDestRegexp.FindStringSubmatch(DefaultImportDest)[ImportDestRegexp.SubexpIndex("name")])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the file name pattern ends with "_" or "-".
|
||||||
|
if end := fileName[len(fileName)-1:]; end != "_" && end != "-" {
|
||||||
|
fileName += "_"
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Trim(pathName, "/. "), fileName
|
||||||
}
|
}
|
||||||
|
|||||||
149
internal/config/customize/import_test.go
Normal file
149
internal/config/customize/import_test.go
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
package customize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestImportSettings(t *testing.T) {
|
||||||
|
t.Run("Default", func(t *testing.T) {
|
||||||
|
s := ImportSettings{}
|
||||||
|
|
||||||
|
assert.IsType(t, ImportSettings{}, s)
|
||||||
|
assert.Equal(t, "", s.Path)
|
||||||
|
assert.Equal(t, RootPath, s.GetPath())
|
||||||
|
assert.Equal(t, false, s.Move)
|
||||||
|
assert.Equal(t, "", s.Dest)
|
||||||
|
assert.Equal(t, DefaultImportDest, s.GetDest())
|
||||||
|
|
||||||
|
pathName, fileName := s.GetDestName()
|
||||||
|
|
||||||
|
assert.Equal(t, "2006/01", pathName)
|
||||||
|
assert.Equal(t, "20060102_150405_", fileName)
|
||||||
|
})
|
||||||
|
t.Run("Customized", func(t *testing.T) {
|
||||||
|
customPath := "/foo/bar"
|
||||||
|
customDest := "2006/01/02/20060102_150405_82F63B78.jpg"
|
||||||
|
|
||||||
|
s := ImportSettings{
|
||||||
|
Path: customPath,
|
||||||
|
Move: true,
|
||||||
|
Dest: customDest,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.IsType(t, ImportSettings{}, s)
|
||||||
|
assert.Equal(t, customPath, s.Path)
|
||||||
|
assert.Equal(t, customPath, s.GetPath())
|
||||||
|
assert.Equal(t, true, s.Move)
|
||||||
|
assert.Equal(t, customDest, s.Dest)
|
||||||
|
assert.Equal(t, customDest, s.GetDest())
|
||||||
|
|
||||||
|
pathName, fileName := s.GetDestName()
|
||||||
|
|
||||||
|
assert.Equal(t, "2006/01/02", pathName)
|
||||||
|
assert.Equal(t, "20060102_150405_", fileName)
|
||||||
|
})
|
||||||
|
t.Run("InvalidDest", func(t *testing.T) {
|
||||||
|
customPath := "/foo/bar"
|
||||||
|
customDest := "/1/2/20060102_150405_82F63B78.jpg"
|
||||||
|
|
||||||
|
s := ImportSettings{
|
||||||
|
Path: customPath,
|
||||||
|
Move: true,
|
||||||
|
Dest: customDest,
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.IsType(t, ImportSettings{}, s)
|
||||||
|
assert.Equal(t, customPath, s.Path)
|
||||||
|
assert.Equal(t, customPath, s.GetPath())
|
||||||
|
assert.Equal(t, true, s.Move)
|
||||||
|
assert.Equal(t, DefaultImportDest, s.GetDest())
|
||||||
|
assert.Equal(t, "", s.Dest)
|
||||||
|
assert.Equal(t, DefaultImportDest, s.GetDest())
|
||||||
|
|
||||||
|
pathName, fileName := s.GetDestName()
|
||||||
|
|
||||||
|
assert.Equal(t, "2006/01", pathName)
|
||||||
|
assert.Equal(t, "20060102_150405_", fileName)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImportDestRegexp(t *testing.T) {
|
||||||
|
// Must match "^\\D*\\d{2,14}[\\-/_].*\\d{2,14}.*(\\.ext|\\.EXT)$"
|
||||||
|
t.Run("Valid", func(t *testing.T) {
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01/20060102_150405_82f63b78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString(DefaultImportDest))
|
||||||
|
t.Logf("%s -> %s", DefaultImportDest, time.Now().Format("2006/01_02_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString(time.Now().Format(DefaultImportDest)))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("foo/"+DefaultImportDest))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("/foo/"+DefaultImportDest))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01/20060102_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01/02/150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("foo/2006/01_02_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("/foo/2006/01_02_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/2/20060102_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/2/20060102_150405_82f63b78.COUNT.ext"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/2_150405_82F63B78.jpg"))
|
||||||
|
|
||||||
|
if m := ImportDestRegexp.FindStringSubmatch("2006/01/20060102_150405_82f63b78.00000.EXT"); m != nil {
|
||||||
|
t.Logf("Matches: %#v", m)
|
||||||
|
assert.Equal(t, "2006/01/20060102_150405_82f63b78.00000.EXT", m[0])
|
||||||
|
assert.Equal(t, "2006/01/20060102_150405_", m[1])
|
||||||
|
assert.Equal(t, "82f63b78", m[2])
|
||||||
|
assert.Equal(t, ".00000", m[3])
|
||||||
|
assert.Equal(t, ".EXT", m[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := ImportDestRegexp.FindStringSubmatch("2006/2/20060102_150405_82F63B78.jpg"); m != nil {
|
||||||
|
t.Logf("Matches: %#v", m)
|
||||||
|
assert.Equal(t, "2006/2/20060102_150405_82F63B78.jpg", m[0])
|
||||||
|
assert.Equal(t, "2006/2/20060102_150405_", m[1])
|
||||||
|
assert.Equal(t, "82F63B78", m[2])
|
||||||
|
assert.Equal(t, "", m[3])
|
||||||
|
assert.Equal(t, ".jpg", m[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
if m := ImportDestRegexp.FindStringSubmatch("foo/2006/01_02_150405_82f63b78.COUNT.ext"); m != nil {
|
||||||
|
t.Logf("Matches: %#v", m)
|
||||||
|
assert.Equal(t, "foo/2006/01_02_150405_82f63b78.COUNT.ext", m[0])
|
||||||
|
assert.Equal(t, "foo/2006/01_02_150405_", m[1])
|
||||||
|
assert.Equal(t, "82f63b78", m[2])
|
||||||
|
assert.Equal(t, ".COUNT", m[3])
|
||||||
|
assert.Equal(t, ".ext", m[4])
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01/20060102_150405_82f63b78.00000.EXT"))
|
||||||
|
t.Logf("2006/01/20060102_150405_82f63b78.00000.EXT -> %s", time.Now().Format("2006/01/20060102_150405_82f63b78.00000.EXT"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString(time.Now().Format("2006/01/20060102_150405_82f63b78.00000.EXT")))
|
||||||
|
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01/02/20060102_150405_82F63B78.jpg"))
|
||||||
|
t.Logf("2006/01/02/20060102_150405_82F63B78.jpg -> %s", time.Now().Format("2006/01/02/20060102_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString(time.Now().Format("2006/01/02/20060102_150405_82F63B78.jpg")))
|
||||||
|
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString("2006/01_02_150405_82F63B78.jpg"))
|
||||||
|
t.Logf("2006/01_02_150405_82F63B78.jpg -> %s", time.Now().Format("2006/01_02_150405_82F63B78.jpg"))
|
||||||
|
assert.True(t, ImportDestRegexp.MatchString(time.Now().Format("2006/01_02_150405_82F63B78.jpg")))
|
||||||
|
})
|
||||||
|
t.Run("Invalid", func(t *testing.T) {
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString(""))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString(DefaultImportDest+"foobar"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString(DefaultImportDest+".foobar"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("1/2/20060102_150405_82F63B78.jpg"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/2/CHECKSUM.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/2/bar.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/20060102_150405.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/20060102_150405_CRC32.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/20060102_150405.EXT"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/02/150405.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/02/150405.EXT"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01_02_150405.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("foo/2006/01_02_150405.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/02/150405-CRC32.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01_02_150405_CRC32.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("foo/2006/01_02_150405_CRC32.ext"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01/02/150405-CHECKSUM.EXT"))
|
||||||
|
assert.False(t, ImportDestRegexp.MatchString("2006/01_02_150405 CHECKSUM.ext"))
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -83,6 +83,7 @@ func NewSettings(theme, lang string) *Settings {
|
|||||||
Import: ImportSettings{
|
Import: ImportSettings{
|
||||||
Path: RootPath,
|
Path: RootPath,
|
||||||
Move: false,
|
Move: false,
|
||||||
|
Dest: "",
|
||||||
},
|
},
|
||||||
Index: IndexSettings{
|
Index: IndexSettings{
|
||||||
Path: RootPath,
|
Path: RootPath,
|
||||||
|
|||||||
@@ -3,8 +3,9 @@ package entity
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/photoprism/photoprism/internal/config/customize"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/photoprism/photoprism/internal/config/customize"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCreateUserSettings(t *testing.T) {
|
func TestCreateUserSettings(t *testing.T) {
|
||||||
@@ -75,6 +76,7 @@ func TestUserSettings_Apply(t *testing.T) {
|
|||||||
Import: customize.ImportSettings{
|
Import: customize.ImportSettings{
|
||||||
Path: "imports/2023",
|
Path: "imports/2023",
|
||||||
Move: false,
|
Move: false,
|
||||||
|
Dest: customize.DefaultImportDest,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
r := m.Apply(s)
|
r := m.Apply(s)
|
||||||
|
|||||||
@@ -289,8 +289,12 @@ func (imp *Import) Cancel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DestinationFilename returns the destination filename of a MediaFile to be imported.
|
// DestinationFilename returns the destination filename of a MediaFile to be imported.
|
||||||
|
// Format: 2006/01/20060102_150405_CHECKSUM.ext
|
||||||
func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile, folder string) (string, error) {
|
func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile, folder string) (string, error) {
|
||||||
fileName := mainFile.CanonicalName()
|
// Get the import destination path and file name patterns.
|
||||||
|
pathPattern, namePattern := imp.conf.Settings().Import.GetDestName()
|
||||||
|
|
||||||
|
fileName := mainFile.CanonicalName(namePattern)
|
||||||
fileExtension := mediaFile.Extension()
|
fileExtension := mediaFile.Extension()
|
||||||
dateCreated := mainFile.DateCreated()
|
dateCreated := mainFile.DateCreated()
|
||||||
|
|
||||||
@@ -305,20 +309,20 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find and return available filename.
|
// Find and return the next available file name if the default name is already being used by another file.
|
||||||
iteration := 0
|
i := 0
|
||||||
dir := filepath.Join(imp.originalsPath(), folder, dateCreated.Format("2006/01"))
|
pathName := filepath.Join(imp.originalsPath(), folder, dateCreated.Format(pathPattern))
|
||||||
result := filepath.Join(dir, fileName+fileExtension)
|
filePath := filepath.Join(pathName, fileName+fileExtension)
|
||||||
|
|
||||||
for fs.FileExists(result) {
|
for fs.FileExists(filePath) {
|
||||||
if mediaFile.Hash() == fs.Hash(result) {
|
if mediaFile.Hash() == fs.Hash(filePath) {
|
||||||
return result, fmt.Errorf("%s already exists", clean.Log(fs.RelName(result, imp.originalsPath())))
|
return filePath, fmt.Errorf("%s already exists", clean.Log(fs.RelName(filePath, imp.originalsPath())))
|
||||||
}
|
}
|
||||||
|
|
||||||
iteration++
|
i++
|
||||||
|
|
||||||
result = filepath.Join(dir, fileName+"."+fmt.Sprintf("%05d", iteration)+fileExtension)
|
filePath = filepath.Join(pathName, fileName+"."+fmt.Sprintf("%05d", i)+fileExtension)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return filePath, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,8 +280,13 @@ func (m *MediaFile) Exposure() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalName returns the canonical name of a media file.
|
// CanonicalName returns the canonical name of a media file.
|
||||||
func (m *MediaFile) CanonicalName() string {
|
func (m *MediaFile) CanonicalName(pattern string) string {
|
||||||
return fs.CanonicalName(m.DateCreated(), m.Checksum())
|
return fs.CanonicalName(m.DateCreated(), m.Checksum(), pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanonicalNameDefault returns the default canonical name of a media file.
|
||||||
|
func (m *MediaFile) CanonicalNameDefault() string {
|
||||||
|
return fs.CanonicalName(m.DateCreated(), m.Checksum(), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalNameFromFile returns the canonical name of a file derived from the image name.
|
// CanonicalNameFromFile returns the canonical name of a file derived from the image name.
|
||||||
|
|||||||
@@ -364,18 +364,21 @@ func TestMediaFile_Exposure(t *testing.T) {
|
|||||||
c := config.TestConfig()
|
c := config.TestConfig()
|
||||||
|
|
||||||
t.Run("/cat_brown.jpg", func(t *testing.T) {
|
t.Run("/cat_brown.jpg", func(t *testing.T) {
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/cat_brown.jpg")
|
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/cat_brown.jpg")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, "1/50", mediaFile.Exposure())
|
assert.Equal(t, "1/50", mediaFile.Exposure())
|
||||||
})
|
})
|
||||||
t.Run("/elephants.jpg", func(t *testing.T) {
|
t.Run("/elephants.jpg", func(t *testing.T) {
|
||||||
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/elephants.jpg")
|
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/elephants.jpg")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, "1/640", mediaFile.Exposure())
|
assert.Equal(t, "1/640", mediaFile.Exposure())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -384,29 +387,36 @@ func TestMediaFileCanonicalName(t *testing.T) {
|
|||||||
c := config.TestConfig()
|
c := config.TestConfig()
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/beach_wood.jpg")
|
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/beach_wood.jpg")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
assert.Equal(t, "20180111_110938_7D8F8A23", mediaFile.CanonicalName())
|
|
||||||
|
assert.Equal(t, "2018_01_11-11_09_38_7D8F8A23", mediaFile.CanonicalName("2006_01_02-15_04_05_"))
|
||||||
|
assert.Equal(t, "180111-110938_7D8F8A23", mediaFile.CanonicalName("060102-150405_"))
|
||||||
|
assert.Equal(t, "20180111_110938_7D8F8A23", mediaFile.CanonicalName(""))
|
||||||
|
assert.Equal(t, "20180111_110938_7D8F8A23", mediaFile.CanonicalNameDefault())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMediaFileCanonicalNameFromFile(t *testing.T) {
|
func TestMediaFileCanonicalNameFromFile(t *testing.T) {
|
||||||
t.Run("/beach_wood.jpg", func(t *testing.T) {
|
c := config.TestConfig()
|
||||||
conf := config.TestConfig()
|
|
||||||
|
t.Run("/beach_wood.jpg", func(t *testing.T) {
|
||||||
|
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/beach_wood.jpg")
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/beach_wood.jpg")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, "beach_wood", mediaFile.CanonicalNameFromFile())
|
assert.Equal(t, "beach_wood", mediaFile.CanonicalNameFromFile())
|
||||||
})
|
})
|
||||||
t.Run("/airport_grey", func(t *testing.T) {
|
t.Run("/airport_grey", func(t *testing.T) {
|
||||||
conf := config.TestConfig()
|
mediaFile, err := NewMediaFile(c.ExamplesPath() + "/airport_grey")
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/airport_grey")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, "airport_grey", mediaFile.CanonicalNameFromFile())
|
assert.Equal(t, "airport_grey", mediaFile.CanonicalNameFromFile())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
// NonCanonical returns true if the file basename is NOT canonical.
|
// NonCanonical returns true if the file basename is NOT canonical.
|
||||||
func NonCanonical(basename string) bool {
|
func NonCanonical(basename string) bool {
|
||||||
if len(basename) != 24 {
|
if l := len(basename); l != 22 && l != 24 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,12 +28,16 @@ func IsCanonical(basename string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CanonicalName returns a canonical name based on time and CRC32 checksum.
|
// CanonicalName returns a canonical name based on time and CRC32 checksum.
|
||||||
func CanonicalName(date time.Time, checksum string) string {
|
func CanonicalName(date time.Time, checksum, pattern string) string {
|
||||||
if len(checksum) != 8 {
|
if len(checksum) != 8 {
|
||||||
checksum = "EEEEEEEE"
|
checksum = "EEEEEEEE"
|
||||||
} else {
|
} else {
|
||||||
checksum = strings.ToUpper(checksum)
|
checksum = strings.ToUpper(checksum)
|
||||||
}
|
}
|
||||||
|
|
||||||
return date.Format("20060102_150405_") + checksum
|
if pattern == "" {
|
||||||
|
pattern = "20060102_150405_"
|
||||||
|
}
|
||||||
|
|
||||||
|
return date.Format(pattern) + checksum
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ func TestCanonicalName(t *testing.T) {
|
|||||||
date := time.Date(
|
date := time.Date(
|
||||||
2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
|
2009, 11, 17, 20, 34, 58, 651387237, time.UTC)
|
||||||
|
|
||||||
assert.Equal(t, "20091117_203458_EEEEEEEE", CanonicalName(date, "123"))
|
assert.Equal(t, "20091117_203458_EEEEEEEE", CanonicalName(date, "123", ""))
|
||||||
assert.Equal(t, "20091117_203458_12345678", CanonicalName(date, "12345678"))
|
assert.Equal(t, "20091117_203458_12345678", CanonicalName(date, "12345678", ""))
|
||||||
|
assert.Equal(t, "091117-203458_12345678", CanonicalName(date, "12345678", "060102-150405_"))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user