feat: datasource with yaml

This commit is contained in:
Young Xu 2024-09-08 01:14:29 +08:00
parent 2e55397574
commit eae87c0365
8 changed files with 137 additions and 76 deletions

View File

@ -1,8 +1,9 @@
package main
import (
"github.com/spf13/cobra"
"strings"
"github.com/spf13/cobra"
)
func deployCmd() *cobra.Command {

View File

@ -2,7 +2,6 @@ package main
import (
"bytes"
"encoding/json"
"fmt"
"math"
"os"
@ -17,6 +16,8 @@ import (
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
"go.abhg.dev/goldmark/toc"
"gitter.top/mder/mder/internal"
)
func generateCmd() *cobra.Command {
@ -39,10 +40,12 @@ func generateCmd() *cobra.Command {
},
Run: func(cmd *cobra.Command, args []string) {
// 读取资源文件
if err := outter.readDataSource(); err != nil {
logger.Errorf("read data source failed: %v", err)
dataSource, err := internal.GetDataSource(BaseDir)
if err != nil {
logger.Fatalf("get data source failed: %v", err)
return
}
outter.DataSource = dataSource
// 读取主题模板文件
if err := outter.readTheme(outter.Config.Site.Theme); err != nil {
logger.Errorf("read theme source failed: %v", err)
@ -63,7 +66,7 @@ func generateCmd() *cobra.Command {
},
PostRun: func(cmd *cobra.Command, args []string) {
endAt := time.Since(startAt)
logger.Infof("generate used: %s", endAt.String())
logger.Infof("generate cost: %s", endAt.String())
},
}
cmd.Flags().StringVar(&path, "path", ".", "mder project path")
@ -293,14 +296,14 @@ func (o *Outter) readTheme(themeName string) (err error) {
}
type Outter struct {
SourceVersion string // 资源号 防缓存
Config *Config // 全局配置
SourceData map[string]interface{} // 记录source/data下的所有文件
Posts []*Post // 记录文章
DraftPosts []*Post // 不宜发布的草稿文章
Pages []*Page // 记录页面
Theme *Theme // 记录主题模板文件
Now time.Time // 当前时间
SourceVersion string // 资源号 防缓存
Config *Config // 全局配置
DataSource internal.DataSource // 记录source/data下的所有文件
Posts []*Post // 记录文章
DraftPosts []*Post // 不宜发布的草稿文章
Pages []*Page // 记录页面
Theme *Theme // 记录主题模板文件
Now time.Time // 当前时间
}
type Theme struct {
@ -352,38 +355,6 @@ func (o *Outter) loadConfig() error {
return o.Config.load()
}
// readDataSource 读取资源文件
func (o *Outter) readDataSource() error {
o.SourceData = make(map[string]interface{})
var dataDir = BaseDir + "/data"
dirs, err := os.ReadDir(dataDir)
if err != nil {
return nil
}
for _, dir := range dirs {
if dir.IsDir() {
continue
}
// 不是json文件
if !strings.HasSuffix(dir.Name(), ".json") {
continue
}
var body []byte
body, err = os.ReadFile(fmt.Sprintf("%s/%s", dataDir, dir.Name()))
if err != nil {
logger.Errorf("read data source file failed: %v", err)
return err
}
var obj interface{}
if err := json.Unmarshal(body, &obj); err != nil {
logger.Errorf("unmarshal data source file failed: %v", err)
return err
}
o.SourceData[strings.ReplaceAll(dir.Name(), ".json", "")] = obj
}
return nil
}
// generate 文件生成
func (o *Outter) generate() {
// 清理dist目录
@ -916,12 +887,8 @@ var funcMap = template.FuncMap{
"sum": sum,
}
func getSource(data interface{}, key string) interface{} {
source, ok := data.(map[string]interface{})
if !ok {
return nil
}
return source[key]
func getSource(data internal.DataSource, key string) []*internal.DataItem {
return data[key]
}
func add(a, b int) int {

44
go.mod
View File

@ -3,47 +3,49 @@ module gitter.top/mder/mder
go 1.20
require (
github.com/gin-gonic/gin v1.9.1
github.com/guonaihong/gout v0.3.9
github.com/gin-gonic/gin v1.10.0
github.com/guonaihong/gout v0.3.10
github.com/radovskyb/watcher v1.0.7
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
github.com/yuin/goldmark v1.6.0
github.com/yuin/goldmark-emoji v1.0.2
github.com/spf13/cobra v1.8.1
github.com/yuin/goldmark v1.7.4
github.com/yuin/goldmark-emoji v1.0.3
github.com/yuin/goldmark-meta v1.1.0
go.abhg.dev/goldmark/mermaid v0.5.0
go.abhg.dev/goldmark/toc v0.9.0
go.abhg.dev/goldmark/toc v0.10.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/bytedance/sonic v1.10.2 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/bytedance/sonic v1.12.2 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.5 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.17.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/go-playground/validator/v10 v10.22.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/leodido/go-urn v1.3.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/samber/lo v1.47.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/protobuf v1.32.0 // indirect
golang.org/x/arch v0.10.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

47
internal/read_data.go Normal file
View File

@ -0,0 +1,47 @@
package internal
import (
"os"
"path/filepath"
"github.com/samber/lo"
)
type DataItem struct {
Name string `yaml:"name"`
Link string `yaml:"link"`
Desc string `yaml:"desc"`
}
type DataSource map[string][]*DataItem
// GetDataSource 读取数据目录 数据目录不支持嵌套读入
func GetDataSource(dir string) (DataSource, error) {
dir = filepath.Join(dir, "data")
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var datasource = make(DataSource)
for _, entry := range entries {
if entry.IsDir() {
continue
}
// 不是json文件
ext := filepath.Ext(entry.Name())
// 没有指定扩展名
if ext == "" {
continue
}
if !lo.Contains([]string{".yaml", ".yml"}, ext) {
continue
}
filename := entry.Name()[:len(entry.Name())-len(filepath.Ext(entry.Name()))]
dataItems, err := ReadYamlToDataItems(filepath.Join(dir, entry.Name()))
if err != nil {
panic("read data source file failed: " + err.Error())
}
datasource[filename] = dataItems
}
return datasource, nil
}

25
internal/read_page.go Normal file
View File

@ -0,0 +1,25 @@
package internal
import "time"
// Post 文章属性
type Post struct {
Title string // 文章标题
FileBasename string // 文件名
Link string // 链接
Category string // 分类
CategoryAlias string // 分类别名
Tags []string // 标签
CreatedAt time.Time // 创建时间
CreatedAtFormat string // 创建时间格式化
UpdatedAtFormat string // 更新时间
MD string // 文章内容
TOC string // 文章toc
}
// Page 页面属性
type Page struct {
Title string // 展示名
Link string // 链接名
MD string // 页面内容
}

17
internal/utils.go Normal file
View File

@ -0,0 +1,17 @@
package internal
import (
"os"
"gopkg.in/yaml.v3"
)
func ReadYamlToDataItems(filename string) ([]*DataItem, error) {
readFile, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
var dataItems []*DataItem
err = yaml.Unmarshal(readFile, &dataItems)
return dataItems, err
}

View File

@ -11,8 +11,9 @@ import (
func serveCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "serve",
Short: "run a serve locally",
Use: "serve",
Short: "run a serve locally",
Aliases: []string{"s"},
Run: func(cmd *cobra.Command, args []string) {
w := watcher.New()
w.SetMaxEvents(1)
@ -73,9 +74,9 @@ func serveCmd() *cobra.Command {
logger.Errorf("generate website failed: %v", err)
return
}
// 秒一次
// 3秒一次
logger.Info("http://127.0.0.1:8666")
if err := w.Start(time.Second * 5); err != nil {
if err := w.Start(time.Second * 3); err != nil {
logger.Errorf("watch file failed: %v", err)
return
}

View File

@ -14,6 +14,7 @@ func updateCmd() *cobra.Command {
Use: "update",
Short: "mder auto update",
Example: "mder update",
Aliases: []string{"u"},
Run: func(cmd *cobra.Command, args []string) {
commit, err := GetRepoLatestCommit()
if err != nil {