From 40b1b1a767db9d8151d150b8bf75e112c3312546 Mon Sep 17 00:00:00 2001 From: dkaslovsky Date: Sun, 29 Jan 2023 12:16:07 -0700 Subject: [PATCH] use directory.SubDir for path join and existence check --- pkg/thread/directory.go | 22 +++++++++++++++------- pkg/thread/io.go | 21 +++++++++------------ pkg/thread/template.go | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/pkg/thread/directory.go b/pkg/thread/directory.go index 422fb58..fab6449 100644 --- a/pkg/thread/directory.go +++ b/pkg/thread/directory.go @@ -14,25 +14,33 @@ type Directory struct { // NewDirectory constructs a new Directory by formatting the name and joining with topLevelDir func NewDirectory(topLevelDir string, name string) *Directory { return &Directory{ - path: filepath.Join(topLevelDir, strings.Replace(name, " ", "_", -1)), + path: filepath.Clean(filepath.Join(topLevelDir, strings.Replace(name, " ", "_", -1))), } } +// Create creates a Directory +func (d *Directory) Create() error { + return os.MkdirAll(d.path, 0o750) +} + // Exists evaluates if a Directory exists -func (d *Directory) Exists(subpaths ...string) bool { - _, err := os.Stat(d.Join(subpaths...)) +func (d *Directory) Exists() bool { + _, err := os.Stat(d.path) return !os.IsNotExist(err) } -// Create creates a Directory -func (d *Directory) Create() error { - return os.MkdirAll(filepath.Clean(d.path), 0o750) +// SubDir constructs a file path by joining any provided subpath strings to the Directory path and +// returns the path and a bool indicating if the constructed path exists +func (d *Directory) SubDir(subpaths ...string) (string, bool) { + path := d.Join(subpaths...) + _, err := os.Stat(path) + return path, !os.IsNotExist(err) } // Join constructs a string representing a path to a subdirectory or file of a Directory func (d *Directory) Join(subpaths ...string) string { parts := append([]string{d.path}, subpaths...) - return filepath.Join(parts...) + return filepath.Clean(filepath.Join(parts...)) } func (d *Directory) String() string { diff --git a/pkg/thread/io.go b/pkg/thread/io.go index 9c38dac..4744dbf 100644 --- a/pkg/thread/io.go +++ b/pkg/thread/io.go @@ -30,8 +30,7 @@ func FromJSON(appDir string, threadName string) (*Thread, error) { return nil, fmt.Errorf("%s not found", dir) } - jsonFile := filepath.Clean(dir.Join(fileNameJSON)) - b, err := os.ReadFile(jsonFile) + b, err := os.ReadFile(dir.Join(fileNameJSON)) if err != nil { return nil, err } @@ -53,8 +52,7 @@ func (th *Thread) ToJSON() error { return err } - jsonFile := filepath.Clean(th.Dir.Join(fileNameJSON)) - return os.WriteFile(jsonFile, b, 0o600) + return os.WriteFile(th.Dir.Join(fileNameJSON), b, 0o600) } // ToHTML generates and saves an HTML file from a thread using default or provided template and CSS files @@ -69,10 +67,9 @@ func (th *Thread) ToHTML(templateFile string, cssFile string) error { return fmt.Errorf("failed to parse template: %w", tErr) } - htmlFile := filepath.Clean(th.Dir.Join(fileNameHTML)) - f, fErr := os.Create(htmlFile) + f, fErr := os.Create(th.Dir.Join(fileNameHTML)) if fErr != nil { - return fmt.Errorf("failed to open file %s: %w", htmlFile, fErr) + return fmt.Errorf("failed to open HTML file: %w", fErr) } defer func() { _ = f.Close() @@ -95,7 +92,7 @@ func (th *Thread) DownloadAttachments() error { for _, tweet := range th.Tweets { for _, attachment := range tweet.Attachments { - err := attachment.Download(filepath.Clean(attachmentDir.Join(attachment.Name(tweet.ID)))) + err := attachment.Download(attachmentDir.Join(attachment.Name(tweet.ID))) if err != nil { return err } @@ -111,8 +108,8 @@ func loadHTMLTemplateFile(threadDir *Directory, templateFile string) (string, er } // Try to load default template from file - if threadDir.Exists("..", fileNameTemplateDefault) { - return readFile(threadDir.Join("..", fileNameTemplateDefault)) + if defaultFile, exists := threadDir.SubDir("..", fileNameTemplateDefault); exists { + return readFile(defaultFile) } return "", nil @@ -124,8 +121,8 @@ func getCSSFile(threadDir *Directory, cssFile string) string { } // Try to load default CSS file - if threadDir.Exists("..", fileNameCSSDefault) { - return threadDir.Join("..", fileNameCSSDefault) + if defaultFile, exists := threadDir.SubDir("..", fileNameCSSDefault); exists { + return defaultFile } return "" diff --git a/pkg/thread/template.go b/pkg/thread/template.go index 794a7f4..9ed6ace 100644 --- a/pkg/thread/template.go +++ b/pkg/thread/template.go @@ -37,7 +37,7 @@ func NewTemplateThread(th *Thread) TemplateThread { attachmentFile := attachment.Name(tweet.ID) // Skip attachment if not downloaded - if !attachmentDir.Exists(attachmentFile) { + if _, exists := attachmentDir.SubDir(attachmentFile); !exists { continue }