Compare commits
No commits in common. "master" and "v0.6.0" have entirely different histories.
3 changed files with 10 additions and 114 deletions
17
README.md
17
README.md
|
@ -64,23 +64,8 @@ Hear goes content. It can be written in html, markdown or whatever what can be p
|
||||||
|
|
||||||
There are two main commands: `PopulateTree` to prepare source (format, add metadata and add Id) and separate images and other data files and `BuildTree` to get object of tree.
|
There are two main commands: `PopulateTree` to prepare source (format, add metadata and add Id) and separate images and other data files and `BuildTree` to get object of tree.
|
||||||
|
|
||||||
Also both commands use `Config` object that can be prepared by `NewConfig` command. With it can be configurable readable formats, attachment directory, custom meta, excludes (not movable files by regexp) and list of functions to apply before file formatting (read bellow).
|
Also both commands use `Config` object that can be prepared by `NewConfig` command. With it can be configurable readable formats, attachment directory, custom meta and excludes (not movable files by regexp).
|
||||||
|
|
||||||
`Tree` object has methods: `FileById` to get `File` by Id, `Slice` to get sub-tree of given path and `Filter` to filter tree by filter.
|
`Tree` object has methods: `FileById` to get `File` by Id, `Slice` to get sub-tree of given path and `Filter` to filter tree by filter.
|
||||||
Filter contains array of meta key and searching value. `tag` key is searched as equal and other meta values of keys can contain part. If `-` is before key - filter is filter out.
|
Filter contains array of meta key and searching value. `tag` key is searched as equal and other meta values of keys can contain part. If `-` is before key - filter is filter out.
|
||||||
|
|
||||||
By full file path and config meta there is possibility to get file params: `Id`, `Meta` and `Tags`:
|
|
||||||
|
|
||||||
```
|
|
||||||
GetFileParams(fullPath string, meta []string) (string, []string, map[string]string, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Functions to apply before file formatting
|
|
||||||
|
|
||||||
There is possibility to add custom functions to apply before file formatting. That is passed with custom function what returns string.
|
|
||||||
|
|
||||||
```
|
|
||||||
func(dir string, content string, info os.FileInfo) (string, error)
|
|
||||||
```
|
|
||||||
|
|
||||||
`dir` is path to directory of file, `content` is file content and `info` is file info.
|
|
||||||
|
|
105
tree.go
105
tree.go
|
@ -3,7 +3,6 @@ package zord_tree
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmp"
|
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -14,10 +13,10 @@ import (
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
abcex "g.arns.lt/zordsdavini/abcex/v4"
|
abcex "g.arns.lt/zordsdavini/abcex/v4"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -25,11 +24,8 @@ type Config struct {
|
||||||
AttachmentDirName string
|
AttachmentDirName string
|
||||||
CustomMeta map[string]func() string
|
CustomMeta map[string]func() string
|
||||||
Excludes []string
|
Excludes []string
|
||||||
Apps map[string]AppCallback
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppCallback func(dir string, content string, info os.FileInfo) (string, error)
|
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
Id string
|
Id string
|
||||||
Name string
|
Name string
|
||||||
|
@ -151,14 +147,12 @@ func NewConfig(
|
||||||
attachmentDirName string,
|
attachmentDirName string,
|
||||||
customMeta map[string]func() string,
|
customMeta map[string]func() string,
|
||||||
excludes []string,
|
excludes []string,
|
||||||
apps map[string]AppCallback,
|
|
||||||
) Config {
|
) Config {
|
||||||
return Config{
|
return Config{
|
||||||
ReadableFormats: readableFormats,
|
ReadableFormats: readableFormats,
|
||||||
AttachmentDirName: attachmentDirName,
|
AttachmentDirName: attachmentDirName,
|
||||||
CustomMeta: customMeta,
|
CustomMeta: customMeta,
|
||||||
Excludes: excludes,
|
Excludes: excludes,
|
||||||
Apps: apps,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,13 +164,6 @@ func PopulateTree(sourcePath string, meta []string, config Config) error {
|
||||||
var err error
|
var err error
|
||||||
var attachmentRegistry map[string]string
|
var attachmentRegistry map[string]string
|
||||||
|
|
||||||
for _, app := range config.Apps {
|
|
||||||
err = applyApp(app, sourcePath, config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attachmentRegistry, err = moveAttachments(sourcePath, config)
|
attachmentRegistry, err = moveAttachments(sourcePath, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -263,57 +250,6 @@ func moveAttachments(dir string, config Config) (map[string]string, error) {
|
||||||
return attachmentRegistry, err
|
return attachmentRegistry, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyApp(app AppCallback, dir string, config Config) error {
|
|
||||||
err := filepath.Walk(dir, func(fullPath string, info os.FileInfo, e error) error {
|
|
||||||
if e != nil {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.Mode().IsRegular() && slices.Contains(config.ReadableFormats, path.Ext(fullPath)) {
|
|
||||||
osf, err := os.Open(fullPath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove all empty lines and separate split line
|
|
||||||
content := ""
|
|
||||||
format := true
|
|
||||||
scanner := bufio.NewScanner(osf)
|
|
||||||
scanner.Split(bufio.ScanLines)
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
if line == "---" {
|
|
||||||
format = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if format {
|
|
||||||
line = strings.Trim(line, " ")
|
|
||||||
if line != "" {
|
|
||||||
content = content + "\n" + line
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
content = content + "\n" + line
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err = app(path.Dir(fullPath), content, info)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
data := []byte(content)
|
|
||||||
|
|
||||||
err = os.WriteFile(fullPath, data, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func fixFormat(dir string, attachmentRegistry map[string]string, config Config) error {
|
func fixFormat(dir string, attachmentRegistry map[string]string, config Config) error {
|
||||||
err := filepath.Walk(dir, func(fullPath string, info os.FileInfo, e error) error {
|
err := filepath.Walk(dir, func(fullPath string, info os.FileInfo, e error) error {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
|
@ -569,16 +505,7 @@ FILE_LOOP:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return tree, err
|
return tree, err
|
||||||
}
|
}
|
||||||
if nextFile.Id == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
tree.Files = append(tree.Files, nextFile)
|
tree.Files = append(tree.Files, nextFile)
|
||||||
slices.SortFunc(tree.Files, func(a, b File) int {
|
|
||||||
if len(a.Id) == len(b.Id) {
|
|
||||||
return strings.Compare(a.Id, b.Id)
|
|
||||||
}
|
|
||||||
return cmp.Compare(len(a.Id), len(b.Id))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree, nil
|
return tree, nil
|
||||||
|
@ -589,30 +516,13 @@ func readFile(file fs.DirEntry, fullPath string, category []string, meta []strin
|
||||||
Name: file.Name(),
|
Name: file.Name(),
|
||||||
FullPath: fullPath,
|
FullPath: fullPath,
|
||||||
Category: category,
|
Category: category,
|
||||||
|
Meta: map[string]string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
id, tags, fileMeta, err := GetFileParams(fullPath, meta)
|
|
||||||
if err != nil {
|
|
||||||
return f, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f.Id = id
|
|
||||||
f.Tags = tags
|
|
||||||
f.Meta = fileMeta
|
|
||||||
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetFileParams(fullPath string, meta []string) (string, []string, map[string]string, error) {
|
|
||||||
fileMeta := map[string]string{}
|
|
||||||
tags := []string{}
|
|
||||||
id := ""
|
|
||||||
|
|
||||||
osf, err := os.Open(fullPath)
|
osf, err := os.Open(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return id, tags, fileMeta, err
|
return File{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
scanner := bufio.NewScanner(osf)
|
scanner := bufio.NewScanner(osf)
|
||||||
scanner.Split(bufio.ScanLines)
|
scanner.Split(bufio.ScanLines)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
|
@ -624,24 +534,27 @@ func GetFileParams(fullPath string, meta []string) (string, []string, map[string
|
||||||
if strings.HasPrefix(line, "* tags:") {
|
if strings.HasPrefix(line, "* tags:") {
|
||||||
line = strings.TrimPrefix(line, "* tags:")
|
line = strings.TrimPrefix(line, "* tags:")
|
||||||
t := strings.Split(line, ",")
|
t := strings.Split(line, ",")
|
||||||
|
tags := []string{}
|
||||||
for _, tag := range t {
|
for _, tag := range t {
|
||||||
tags = append(tags, strings.Trim(tag, " "))
|
tags = append(tags, strings.Trim(tag, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.Tags = tags
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(line, "* id:") {
|
if strings.HasPrefix(line, "* id:") {
|
||||||
line = strings.TrimPrefix(line, "* id:")
|
line = strings.TrimPrefix(line, "* id:")
|
||||||
id = strings.Trim(line, " ")
|
f.Id = strings.Trim(line, " ")
|
||||||
}
|
}
|
||||||
for _, option := range meta {
|
for _, option := range meta {
|
||||||
if strings.HasPrefix(line, "* "+option) {
|
if strings.HasPrefix(line, "* "+option) {
|
||||||
line = strings.TrimPrefix(line, "* "+option+":")
|
line = strings.TrimPrefix(line, "* "+option+":")
|
||||||
fileMeta[option] = strings.Trim(line, " ")
|
f.Meta[option] = strings.Trim(line, " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ = osf.Close()
|
_ = osf.Close()
|
||||||
|
|
||||||
return id, tags, fileMeta, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadFileContent(file File) (string, error) {
|
func ReadFileContent(file File) (string, error) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ func prepare(t *testing.T) Config {
|
||||||
"__a",
|
"__a",
|
||||||
make(map[string]func() string),
|
make(map[string]func() string),
|
||||||
[]string{"exclude_[0-9]+.bin"},
|
[]string{"exclude_[0-9]+.bin"},
|
||||||
map[string]AppCallback{},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
err = PopulateTree("./testdata/sunny1", []string{}, config)
|
err = PopulateTree("./testdata/sunny1", []string{}, config)
|
||||||
|
@ -39,7 +38,6 @@ func TestFromNotExistingDirectory(t *testing.T) {
|
||||||
"__a",
|
"__a",
|
||||||
make(map[string]func() string),
|
make(map[string]func() string),
|
||||||
[]string{},
|
[]string{},
|
||||||
map[string]AppCallback{},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
_, err := BuildTree("./testing/i_dont_exist", []string{}, config)
|
_, err := BuildTree("./testing/i_dont_exist", []string{}, config)
|
||||||
|
|
Loading…
Add table
Reference in a new issue