Skip to content

Commit

Permalink
fix(export): add error handling for duplicated slugs
Browse files Browse the repository at this point in the history
Close #4
  • Loading branch information
waynezhang committed Jan 1, 2024
1 parent 7a84081 commit f378beb
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 13 deletions.
5 changes: 3 additions & 2 deletions internal/cmd/preview.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ func preview(cmd *cobra.Command, args []string) {
log.Debug("Creating Preview...")

config := config.Shared()
index := indexer.Build(config.GetSectionMetadata(), config.GetExtractOption())
index, err := indexer.Build(config.GetSectionMetadata(), config.GetExtractOption())
utils.CheckFatalError(err, "Failed to build index")

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
handleRoot(
Expand Down Expand Up @@ -62,7 +63,7 @@ func preview(cmd *cobra.Command, args []string) {
}

log.Info("Server started -> http://localhost:%d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
err = http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
utils.CheckFatalError(err, "Failed to listen the port")
}

Expand Down
11 changes: 8 additions & 3 deletions internal/export/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ProgressFunc func(path string)

type Context interface {
cleanDirectory(outputPath string) error
buildIndex(cfg config.Config) []indexer.Section
buildIndex(cfg config.Config) ([]indexer.Section, error)
exportPhotos(sections []indexer.Section, outputPath string, cache cache.Cache, progressFunc ProgressFunc)
generateIndexHtml(cfg config.Config, sections []indexer.Section, path string, minimize bool)
processOtherFolders(folders []string, outputPath string, minimize bool, messageFunc func(src string, dst string))
Expand Down Expand Up @@ -59,7 +59,12 @@ func export(cfg config.Config, outputPath string, minimize bool, cache cache.Cac

spinnerMsg("Building index %s", outputPath)
photosDirectory := files.OutputPhotosFilePath(outputPath)
section := ctx.buildIndex(cfg)
section, err := ctx.buildIndex(cfg)
if err != nil {
ctx.cleanDirectory(outputPath)
utils.CheckFatalError(err, "Failed t build index.")
}

ctx.exportPhotos(section, photosDirectory, cache, func(path string) {
spinnerMsg("%s", path)
})
Expand All @@ -84,7 +89,7 @@ func (ctx DefaultExportContext) cleanDirectory(outputPath string) error {
return files.PruneDirectory(outputPath)
}

func (ctx DefaultExportContext) buildIndex(cfg config.Config) []indexer.Section {
func (ctx DefaultExportContext) buildIndex(cfg config.Config) ([]indexer.Section, error) {
return indexer.Build(cfg.GetSectionMetadata(), cfg.GetExtractOption())
}

Expand Down
15 changes: 12 additions & 3 deletions internal/export/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,17 @@ func (m *MockContext) cleanDirectory(outputPath string) error {
return m.Called(outputPath).Error(0)
}

func (m *MockContext) buildIndex(cfg config.Config) []indexer.Section {
return m.Called(cfg).Get(0).([]indexer.Section)
func (m *MockContext) buildIndex(cfg config.Config) ([]indexer.Section, error) {
args := m.Called(cfg)
var sections []indexer.Section
var err error
if args.Get(0) != nil {
sections = args.Get(0).([]indexer.Section)
}
if args.Get(1) != nil {
err = args.Get(1).(error)
}
return sections, err
}

func (m *MockContext) exportPhotos(sections []indexer.Section, outputPath string, cache cache.Cache, progressFunc ProgressFunc) {
Expand Down Expand Up @@ -104,7 +113,7 @@ func TestExportPhotos(t *testing.T) {

mockCtx := new(MockContext)
mockCtx.On("cleanDirectory", mock.Anything).Return(nil)
mockCtx.On("buildIndex", mock.Anything).Return(sections)
mockCtx.On("buildIndex", mock.Anything).Return(sections, nil)
mockCtx.On("exportPhotos", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return()
mockCtx.On("generateIndexHtml", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return()
mockCtx.On("processOtherFolders", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return()
Expand Down
17 changes: 13 additions & 4 deletions internal/indexer/indexer.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package indexer

import (
"fmt"
"html/template"
"os"
"path/filepath"
Expand Down Expand Up @@ -28,23 +29,31 @@ type ImageSet struct {
OriginalSize ImageSize
}

func Build(metadata []config.SectionMetadata, option config.ExtractOption) []Section {
func Build(metadata []config.SectionMetadata, option config.ExtractOption) ([]Section, error) {
sections := []Section{}
slugs := map[string]bool{}

for _, val := range metadata {
slug := val.Slug
if slugs[slug] {
return nil, fmt.Errorf("Slug \"%s\" already exists. Slug needs to be unique.", slug)
}

log.Debug("Extacting section [%s][/%s] %s", val.Title, val.Slug, val.Folder)
s := Section{
Title: val.Title,
Text: val.Text,
Slug: val.Slug,
Slug: slug,
Folder: val.Folder,
Ascending: val.Ascending,
ImageSets: buildImageSets(val.Folder, val.Ascending, option),
}
log.Debug("Extacting section [%s][/%s] %s", val.Title, val.Slug, val.Folder)
slugs[slug] = true

sections = append(sections, s)
}

return sections
return sections, nil
}

func buildImageSets(folder string, ascending bool, option config.ExtractOption) []ImageSet {
Expand Down
15 changes: 14 additions & 1 deletion internal/indexer/indexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestBuild(t *testing.T) {

data := []config.SectionMetadata{meta1, meta2}

sections := Build(data, defaultOption)
sections, _ := Build(data, defaultOption)
assert.Equal(t, 2, len(sections))
assert.Equal(t, testdata.Collection1["title"], sections[0].Title)

Expand All @@ -38,6 +38,19 @@ func TestBuild(t *testing.T) {
assert.Equal(t, testdata.Collection2FileName3, sections[1].ImageSets[0].FileName)
}

func TestBuildDuplicatedSlugs(t *testing.T) {
var meta1 config.SectionMetadata
var meta2 config.SectionMetadata
mapstructure.Decode(testdata.Collection1, &meta1)
mapstructure.Decode(testdata.Collection2, &meta2)
meta2.Slug = meta1.Slug

data := []config.SectionMetadata{meta1, meta2}

_, err := Build(data, defaultOption)
assert.NotNil(t, err)
}

func TestBuildImageSets(t *testing.T) {
expectedAscendingFileNames := []string{
testdata.Collection1FileName1,
Expand Down

0 comments on commit f378beb

Please sign in to comment.