talc/pkg/tal/repo.go
2020-03-18 05:16:25 +01:00

120 lines
2.0 KiB
Go

package tal
import (
"bufio"
"errors"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"regexp"
"strings"
)
var metaRegex = regexp.MustCompile(`^#([a-zA-Z]+) (.*)$`)
type Repo struct {
URL string
Path string
Update bool
Books []Book
}
func (lr *Repo) GetMeta() map[string]map[string][]Book {
meta := map[string]map[string][]Book{}
for _, book := range lr.Books {
if book.Meta["DELETED"] != "" {
continue
}
for key, value := range book.Meta {
if meta[key] == nil {
meta[key] = map[string][]Book{}
}
meta[key][value] = append(meta[key][value], book)
}
}
return meta
}
func (lr *Repo) Scan() error {
books := lr.scanTree(lr.Path, 1, 3, ".muse")
if len(books) == 0 {
return errors.New(fmt.Sprintf("No library found at %s", lr.Path))
}
for _, p := range books {
meta, err := readMeta(p)
if err != nil {
continue
}
lr.Books = append(lr.Books, Book{
Path: p,
Base: strings.TrimSuffix(path.Base(p), ".muse"),
Meta: meta,
})
}
return nil
}
func (lr *Repo) scanTree(p string, dirlen uint8, max uint8, suffix string) []string {
var paths []string
files, err := ioutil.ReadDir(p)
if err != nil {
return paths
}
for _, entry := range files {
name := entry.Name()
subdir := filepath.Join(p, name)
if dirlen == max {
if strings.HasSuffix(name, suffix) {
paths = append(paths, subdir)
}
} else {
if !entry.IsDir() || len(name) != int(dirlen) {
continue
}
paths = append(paths, lr.scanTree(subdir, dirlen+1, max, suffix)...)
}
}
return paths
}
func readMeta(p string) (map[string]string, error) {
meta := map[string]string{}
f, err := os.Open(p)
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
if len(line) > 0 && line[0] == '#' {
result := metaRegex.FindStringSubmatch(line)
if len(result) > 0 {
tag := strings.TrimSpace(result[1])
value := strings.TrimSpace(result[2])
meta[tag] = value
}
} else {
break
}
}
f.Close()
return meta, nil
}