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
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)
|
|
}
|
|
|
|
}
|