/
generator.go
96 lines (82 loc) · 2.56 KB
/
generator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package generator
import (
"bytes"
"context"
"fmt"
"time"
"github.com/wzshiming/profile_stats"
"github.com/wzshiming/profile_stats/generator/activities"
"github.com/wzshiming/profile_stats/generator/charts"
"github.com/wzshiming/profile_stats/generator/now"
"github.com/wzshiming/profile_stats/generator/placeholder"
"github.com/wzshiming/profile_stats/generator/stats"
"github.com/wzshiming/profile_stats/source"
"github.com/wzshiming/xmlinjector"
)
const (
key = "PROFILE_STATS"
blankChar = "\n"
)
type Handler struct {
registry map[string]profile_stats.Generator
}
func NewHandler(src *source.Source) *Handler {
r := &Handler{
registry: map[string]profile_stats.Generator{},
}
r.register("now", now.NewNow())
r.register("updatedat", now.NewNow())
r.register("placeholder", placeholder.NewPlaceHolder())
r.register("activities", activities.NewActivities(src))
r.register("stats", stats.NewStats(src))
r.register("charts", charts.NewCharts(src))
return r
}
func (r *Handler) register(name string, generator profile_stats.Generator) {
r.registry[name] = generator
}
func (r *Handler) Handle(ctx context.Context, origin []byte) ([]byte, []string, error) {
buf := bytes.NewBuffer(nil)
var warnings []string
date, err := xmlinjector.Inject([]byte(key), origin, func(args, origin []byte) []byte {
tag := NewArgs(string(args), true)
template, ok := tag.String("template")
if !ok || template == "" {
warnings = append(warnings, fmt.Sprintf("%q: no template", args))
return errInfo("no template", origin)
}
blank, ok := tag.Int("blank")
if !ok {
blank = 2
}
generator, ok := r.registry[template]
if !ok {
warnings = append(warnings, fmt.Sprintf("%q: not support template %q", args, template))
return errInfo(fmt.Sprintf("not support template %q", template), origin)
}
buf.Reset()
err := generator.Generate(ctx, buf, tag)
if err != nil {
warnings = append(warnings, fmt.Sprintf("%q: %s", args, err.Error()))
return errInfo(err.Error(), origin)
}
raw := buf.Bytes()
raw = bytes.Trim(raw, blankChar)
var tmp []byte
if blank > 0 {
tmp = make([]byte, 0, len(raw)+blank*2)
blanks := bytes.Repeat([]byte(blankChar), blank)
tmp = append(tmp, blanks...)
tmp = append(tmp, raw...)
tmp = append(tmp, blanks...)
} else {
tmp = make([]byte, len(raw))
copy(tmp, raw)
}
return tmp
})
return date, warnings, err
}
func errInfo(msg string, origin []byte) []byte {
return append([]byte(fmt.Sprintf("\n<!-- profile_stats_error error:%q date:%q /-->\n", msg, time.Now().Format(time.RFC3339))), origin...)
}