You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.3 KiB
Go

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 into:", 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 (
target string
)
flag.StringVar(&target, "target", "/tmp/blog/content/posts/", "target 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, target)
if err != nil {
log.Fatalf("error moving attachment: %s\n", err)
}
}
}()
// }
err := filepath.Walk(target, walkFunc(attachments))
if err != nil {
log.Fatalf("error walking %s", err)
}
}