commit f8f69a7187e6a4688e9f61997bec62f20818cf00 Author: Nick Dumas Date: Tue Feb 28 11:22:31 2023 -0500 committing diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8039891 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:latest as BUILD + +WORKDIR /gather-media + +COPY go.mod ./ +# COPY go.sum ./ + +RUN go mod download + +COPY *.go ./ + +RUN go build -o /bin/gather-media diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..22192ea --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module gathermedia + +go 1.19 diff --git a/main.go b/main.go new file mode 100644 index 0000000..ea5c090 --- /dev/null +++ b/main.go @@ -0,0 +1,123 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "io/fs" + "log" + "os" + "path/filepath" + "regexp" + "strings" +) + +type Attachment struct { + Filename string + Note string +} + +type matches chan Attachment + +func scanReader(r io.Reader, path string, matchChan matches) { + + log.Printf("scanning markdown file: %s", path) + pat := regexp.MustCompile(`\[\[(Resources\/attachments\/.*?)\]\]`) + + s := bufio.NewScanner(r) + for s.Scan() { + tok := s.Text() + matches := pat.FindAllStringSubmatch(tok, -1) + if len(matches) > 0 { + log.Printf("media found in %s: %#+v\n", path, matches) + for _, match := range matches { + dirs := strings.Split(path, "/") + noteFilename := dirs[len(dirs)-2] + matchChan <- Attachment{Filename: match[1], Note: noteFilename} + } + } + } +} + +func walkFunc(matchChan matches) filepath.WalkFunc { + return func(path string, info fs.FileInfo, err error) error { + if err != nil { + return nil + } + if info.IsDir() { + return nil + } + f, err := os.Open(path) + if err != nil { + return err + } + + if strings.HasSuffix(path, "index.md") { + scanReader(f, path, matchChan) + } + return nil + } +} + +func moveAttachment(att Attachment, dest string) error { + destPath := filepath.Join(dest, strings.Split(att.Note, ".")[0]) + log.Println("moving files:", destPath) + _, err := copy(att.Filename, filepath.Join(destPath, filepath.Base(att.Filename))) + return err +} + +func copy(src, dst string) (int64, error) { + sourceFileStat, err := os.Stat(src) + if err != nil { + return 0, err + } + + if !sourceFileStat.Mode().IsRegular() { + return 0, fmt.Errorf("%s is not a regular file", src) + } + + source, err := os.Open(src) + if err != nil { + return 0, err + } + defer source.Close() + + destination, err := os.Create(dst) + if err != nil { + return 0, err + } + defer destination.Close() + nBytes, err := io.Copy(destination, source) + return nBytes, err +} + +func main() { + var ( + origin string + destination string + ) + flag.StringVar(&origin, "origin", "./content/", "directory containing Obsidian Markdown posts") + flag.StringVar(&destination, "destination", "/tmp/blog/content/posts/", "destination for posts and their attachments") + + flag.Parse() + + attachments := make(matches) + + // for i := 0; i < 5; i++ { + go func() { + for match := range attachments { + err := moveAttachment(match, destination) + if err != nil { + log.Fatalf("error moving attachment: %s\n", err) + } + } + }() + // } + + err := filepath.Walk(origin, walkFunc(attachments)) + if err != nil { + log.Fatalf("error walking %s", err) + } + +}