mirror of
https://github.com/muhac/chinese-holidays-calendar.git
synced 2024-11-21 01:01:50 +08:00
reformat code
This commit is contained in:
parent
f5ac55b463
commit
78a33ffafd
@ -2,7 +2,7 @@
|
||||
|
||||
subscription link of public holidays in mainland China
|
||||
|
||||
> Calendar data updated at 1:34 on September 16, 2022
|
||||
> Calendar data updated at 2:41 on September 16, 2022
|
||||
|
||||
## Demo
|
||||
|
||||
|
7
go.mod
7
go.mod
@ -2,4 +2,9 @@ module main
|
||||
|
||||
go 1.19
|
||||
|
||||
require github.com/google/uuid v1.3.0
|
||||
require (
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/samber/lo v1.28.2
|
||||
)
|
||||
|
||||
require golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||
|
9
go.sum
9
go.sum
@ -1,2 +1,11 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/samber/lo v1.28.2 h1:f1gctelJ5YQk336wCN+Elr90FyhZ6ArhelD5kjhNTz4=
|
||||
github.com/samber/lo v1.28.2/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
14
main.go
14
main.go
@ -1,18 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"main/parse/base"
|
||||
"main/parse/app"
|
||||
"main/parse/core"
|
||||
)
|
||||
|
||||
func main() {
|
||||
holidays := core.Data().Read(`^20\d\d`).From("data").Parse().Sort().Get()
|
||||
holidays := app.Data().Read(`^20\d\d`).From("data").Parse().Sort().Get().Print("==== HOLIDAYS ====")
|
||||
|
||||
holidays.Print("==== HOLIDAYS ====")
|
||||
app.Data(holidays).Write("index.html").To("docs").Title("节假日").Set()
|
||||
app.Data(holidays).Write("holiday.ics").To("docs").Title("节假日").Set()
|
||||
|
||||
core.Data(holidays).Write("index.html").To("docs").Title("节假日").Set()
|
||||
core.Data(holidays).Write("holiday.ics").To("docs").Title("节假日").Set()
|
||||
|
||||
core.Data(holidays.Select(base.Rest)).Write("rest.ics").To("docs").Title("节假日(假期)").Set()
|
||||
core.Data(holidays.Select(base.Work)).Write("work.ics").To("docs").Title("节假日(补班)").Set()
|
||||
app.Data(holidays.Select(core.Rest)).Write("rest.ics").To("docs").Title("节假日(假期)").Set()
|
||||
app.Data(holidays.Select(core.Work)).Write("work.ics").To("docs").Title("节假日(补班)").Set()
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package core
|
||||
package app
|
||||
|
||||
import "main/parse/base"
|
||||
import "main/parse/core"
|
||||
|
||||
func Data(optional ...base.Holidays) Handler {
|
||||
func Data(optional ...core.Holidays) Handler {
|
||||
return newHandler(optional...)
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ type readData interface {
|
||||
|
||||
type getData interface {
|
||||
Sort() getData
|
||||
Get() base.Holidays
|
||||
Get() core.Holidays
|
||||
}
|
||||
|
||||
type setDirOut interface {
|
@ -1,9 +1,9 @@
|
||||
package core
|
||||
package app
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"main/parse/base"
|
||||
"main/parse/core"
|
||||
"main/parse/data"
|
||||
"main/parse/data/input"
|
||||
"main/parse/data/output"
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"main/parse/data/write"
|
||||
)
|
||||
|
||||
func newHandler(optional ...base.Holidays) Handler {
|
||||
func newHandler(optional ...core.Holidays) Handler {
|
||||
if len(optional) == 0 {
|
||||
return handler{}
|
||||
}
|
||||
@ -19,7 +19,7 @@ func newHandler(optional ...base.Holidays) Handler {
|
||||
}
|
||||
|
||||
type handler struct {
|
||||
data base.Holidays
|
||||
data core.Holidays
|
||||
|
||||
reader data.Reader
|
||||
writer data.Writer
|
||||
@ -65,7 +65,7 @@ func (h handler) Title(name string) writeData {
|
||||
return h
|
||||
}
|
||||
|
||||
func (h handler) Get() base.Holidays {
|
||||
func (h handler) Get() core.Holidays {
|
||||
return h.data
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
package base
|
||||
|
||||
const (
|
||||
Rest = iota // 假日
|
||||
Work // 补班
|
||||
)
|
@ -1,29 +0,0 @@
|
||||
package base
|
||||
|
||||
import "time"
|
||||
|
||||
// Holidays data
|
||||
type Holidays []Holiday
|
||||
|
||||
// Holiday data per day
|
||||
type Holiday struct {
|
||||
Group string
|
||||
Date time.Time
|
||||
Name string
|
||||
Type int
|
||||
Nth int
|
||||
Total int
|
||||
}
|
||||
|
||||
func (h Holidays) Where(filter func(Holiday) bool) (result Holidays) {
|
||||
for _, item := range h {
|
||||
if filter(item) {
|
||||
result = append(result, item)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (h Holidays) Len() int { return len(h) }
|
||||
func (h Holidays) Less(i, j int) bool { return h[i].Date.Before(h[j].Date) }
|
||||
func (h Holidays) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
@ -1,26 +0,0 @@
|
||||
package base
|
||||
|
||||
import "fmt"
|
||||
|
||||
func selectType(t int) func(Holiday) bool {
|
||||
return func(holidays Holiday) bool {
|
||||
return holidays.Type == t
|
||||
}
|
||||
}
|
||||
|
||||
func (h Holidays) Select(t int) Holidays {
|
||||
return h.Where(selectType(t))
|
||||
}
|
||||
|
||||
func (h Holidays) Print(titles ...string) (result string) {
|
||||
for _, title := range titles {
|
||||
fmt.Println(title)
|
||||
}
|
||||
|
||||
for _, day := range h {
|
||||
result += fmt.Sprintf("%+v\n", day)
|
||||
}
|
||||
|
||||
fmt.Println(result)
|
||||
return
|
||||
}
|
42
parse/core/base.go
Normal file
42
parse/core/base.go
Normal file
@ -0,0 +1,42 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
Rest Status = "rest" // 假日
|
||||
Work Status = "work" // 补班
|
||||
)
|
||||
|
||||
// Holidays data
|
||||
type Holidays []Holiday
|
||||
|
||||
// Holiday data per day
|
||||
type Holiday struct {
|
||||
Group string
|
||||
Date time.Time
|
||||
Name string
|
||||
Type Status
|
||||
Nth int
|
||||
Total int
|
||||
}
|
||||
|
||||
func (h Holidays) Select(t Status) Holidays {
|
||||
return lo.Filter(h, func(d Holiday, _ int) bool { return d.Type == t })
|
||||
}
|
||||
|
||||
func (h Holidays) Print(titles ...string) Holidays {
|
||||
lo.ForEach(titles, func(title string, _ int) { log.Println(title) })
|
||||
lo.ForEach(h, func(day Holiday, _ int) { log.Printf("%+v\n", day) })
|
||||
return h
|
||||
}
|
||||
|
||||
func (h Holidays) Len() int { return len(h) }
|
||||
func (h Holidays) Less(i, j int) bool { return h[i].Date.Before(h[j].Date) }
|
||||
func (h Holidays) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
|
@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"main/parse/base"
|
||||
"main/parse/core"
|
||||
"main/parse/data"
|
||||
)
|
||||
|
||||
@ -14,7 +14,7 @@ func NewParser() data.Parser {
|
||||
|
||||
type parser struct{}
|
||||
|
||||
func (p parser) Parse(raw data.Input) (result base.Holidays) {
|
||||
func (p parser) Parse(raw data.Input) (result core.Holidays) {
|
||||
for _, year := range raw {
|
||||
days, _ := parse(year)
|
||||
result = append(result, days...)
|
||||
@ -22,33 +22,33 @@ func (p parser) Parse(raw data.Input) (result base.Holidays) {
|
||||
return
|
||||
}
|
||||
|
||||
func parse(raw data.InputRaw) (result base.Holidays, err error) {
|
||||
dayCount := make(map[string]map[int]int)
|
||||
func parse(raw data.InputRaw) (result core.Holidays, err error) {
|
||||
dayCount := make(map[string]map[core.Status]int)
|
||||
|
||||
for group, holiday := range raw.Data {
|
||||
groupName := fmt.Sprintf("%04d%02d", raw.Year, group+1)
|
||||
dayCount[groupName] = make(map[int]int)
|
||||
dayCount[groupName] = make(map[core.Status]int)
|
||||
info := strings.Split(holiday, ";")
|
||||
|
||||
for i, day := range holidays(raw.Year, info[1]) {
|
||||
restDay := base.Holiday{
|
||||
restDay := core.Holiday{
|
||||
Group: groupName,
|
||||
Name: info[0],
|
||||
Nth: i + 1,
|
||||
Date: day,
|
||||
Type: base.Rest,
|
||||
Type: core.Rest,
|
||||
}
|
||||
result = append(result, restDay)
|
||||
dayCount[restDay.Group][restDay.Type]++
|
||||
}
|
||||
|
||||
for i, day := range holidays(raw.Year, info[2]) {
|
||||
workDay := base.Holiday{
|
||||
workDay := core.Holiday{
|
||||
Group: groupName,
|
||||
Name: info[0],
|
||||
Nth: i + 1,
|
||||
Date: day,
|
||||
Type: base.Work,
|
||||
Type: core.Work,
|
||||
}
|
||||
result = append(result, workDay)
|
||||
dayCount[workDay.Group][workDay.Type]++
|
||||
|
@ -1,17 +1,17 @@
|
||||
package data
|
||||
|
||||
import "main/parse/base"
|
||||
import "main/parse/core"
|
||||
|
||||
type Reader interface {
|
||||
Read() Input
|
||||
}
|
||||
|
||||
type Parser interface {
|
||||
Parse(Input) base.Holidays
|
||||
Parse(Input) core.Holidays
|
||||
}
|
||||
|
||||
type Formatter interface {
|
||||
Format(base.Holidays) Output
|
||||
Format(core.Holidays) Output
|
||||
}
|
||||
|
||||
type Writer interface {
|
||||
|
@ -6,8 +6,9 @@ import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/samber/lo"
|
||||
|
||||
"main/parse/base"
|
||||
"main/parse/core"
|
||||
"main/parse/data"
|
||||
)
|
||||
|
||||
@ -19,21 +20,21 @@ type formatter struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (f formatter) Format(info base.Holidays) (result data.Output) {
|
||||
result.Prefix = fmt.Sprintf(IcsHead, f.name)
|
||||
result.Suffix = IcsTail
|
||||
func (f formatter) Format(info core.Holidays) (result data.Output) {
|
||||
result.Prefix = fmt.Sprintf(icsHead, f.name)
|
||||
result.Suffix = icsTail
|
||||
|
||||
uuid.SetRand(rand.New(rand.NewSource(int64(crc32.ChecksumIEEE([]byte(f.name))))))
|
||||
|
||||
for _, day := range info {
|
||||
outputDay := event{
|
||||
Id: uuid.NewString(),
|
||||
Group: day.Group,
|
||||
Title: getTitle(day),
|
||||
Date: day.Date,
|
||||
Desc: getDesc(day),
|
||||
}
|
||||
result.Body = append(result.Body, outputDay.Ics())
|
||||
}
|
||||
result.Body = lo.Map(info, func(day core.Holiday, i int) string {
|
||||
return event{
|
||||
id: uuid.NewString(),
|
||||
group: day.Group,
|
||||
title: getTitle(day),
|
||||
date: day.Date,
|
||||
desc: getDesc(day),
|
||||
}.Ics()
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -4,46 +4,46 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"main/parse/base"
|
||||
"main/parse/core"
|
||||
)
|
||||
|
||||
const (
|
||||
IcsHead = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Rank Technology//Chinese Holidays//EN\nX-WR-CALNAME:%s"
|
||||
IcsEvent = "BEGIN:VEVENT\nUID:%s\nDTSTART;VALUE=DATE:%s\nSUMMARY:%s\nDESCRIPTION:%s\nEND:VEVENT"
|
||||
IcsTail = "END:VCALENDAR"
|
||||
icsHead = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Rank Technology//Chinese Holidays//EN\nX-WR-CALNAME:%s"
|
||||
icsEvent = "BEGIN:VEVENT\nUID:%s\nDTSTART;VALUE=DATE:%s\nSUMMARY:%s\nDESCRIPTION:%s\nEND:VEVENT"
|
||||
icsTail = "END:VCALENDAR"
|
||||
)
|
||||
|
||||
// event data
|
||||
type event struct {
|
||||
Id string
|
||||
Group string
|
||||
Title string
|
||||
Date time.Time
|
||||
Desc string
|
||||
id string
|
||||
group string
|
||||
title string
|
||||
date time.Time
|
||||
desc string
|
||||
}
|
||||
|
||||
func (d event) Ics() string {
|
||||
return fmt.Sprintf(
|
||||
IcsEvent,
|
||||
d.Id,
|
||||
d.Date.Format("20060102"),
|
||||
d.Title,
|
||||
d.Desc,
|
||||
icsEvent,
|
||||
d.id,
|
||||
d.date.Format("20060102"),
|
||||
d.title,
|
||||
d.desc,
|
||||
)
|
||||
}
|
||||
|
||||
func getStatusName(status int) string {
|
||||
name := map[int]string{
|
||||
base.Rest: "假期",
|
||||
base.Work: "补班",
|
||||
func getStatusName(status core.Status) string {
|
||||
name := map[core.Status]string{
|
||||
core.Rest: "假期",
|
||||
core.Work: "补班",
|
||||
}
|
||||
return name[status]
|
||||
}
|
||||
|
||||
func getTitle(item base.Holiday) string {
|
||||
func getTitle(item core.Holiday) string {
|
||||
return fmt.Sprintf("%s%s", item.Name, getStatusName(item.Type))
|
||||
}
|
||||
|
||||
func getDesc(item base.Holiday) string {
|
||||
func getDesc(item core.Holiday) string {
|
||||
return fmt.Sprintf("%s 第%d天/共%d天", getStatusName(item.Type), item.Nth, item.Total)
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/samber/lo"
|
||||
|
||||
"main/parse/data"
|
||||
)
|
||||
|
||||
@ -37,7 +39,7 @@ func (dw dataReader) Read() (result data.Input) {
|
||||
defer wg.Done()
|
||||
raw, err := dw.load(file.Name)
|
||||
if err != nil {
|
||||
fmt.Printf("Error loading %s: %s", file.Name, err)
|
||||
log.Printf("Error loading %s: %s\n", file.Name, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -46,7 +48,7 @@ func (dw dataReader) Read() (result data.Input) {
|
||||
Data: lines(raw),
|
||||
}
|
||||
if len(result.Data) == 0 {
|
||||
fmt.Printf("No data in %s", file.Name)
|
||||
log.Printf("No data in %s\n", file.Name)
|
||||
return
|
||||
}
|
||||
|
||||
@ -71,12 +73,11 @@ func (dw dataReader) fileList() (result []fileInfo) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
if yr, err := year(file.Name(), dw.File); err == nil && !file.IsDir() {
|
||||
result = append(result, fileInfo{Name: file.Name(), Year: yr})
|
||||
}
|
||||
}
|
||||
return result
|
||||
return lo.FilterMap(files, func(file os.DirEntry, _ int) (fileInfo, bool) {
|
||||
yr, err := year(file.Name(), dw.File)
|
||||
isFile := err == nil && !file.IsDir()
|
||||
return fileInfo{Name: file.Name(), Year: yr}, isFile
|
||||
})
|
||||
}
|
||||
|
||||
func (dw dataReader) load(filename string) (result string, err error) {
|
||||
@ -105,12 +106,11 @@ func lines(data string) (result []string) {
|
||||
dateRegex = regexp.MustCompile(fmt.Sprintf(`^[^;]+;%s;%s$`, dateAccept, dateAccept))
|
||||
)
|
||||
|
||||
for _, line := range strings.Split(data, "\n") {
|
||||
line = strings.Split(line, "//")[0]
|
||||
line = strings.TrimSpace(line)
|
||||
if dateRegex.MatchString(line) {
|
||||
result = append(result, line)
|
||||
}
|
||||
}
|
||||
return result
|
||||
return lo.FilterMap(strings.Split(data, "\n"),
|
||||
func(line string, _ int) (string, bool) {
|
||||
line = strings.Split(line, "//")[0]
|
||||
line = strings.TrimSpace(line)
|
||||
return line, dateRegex.MatchString(line)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -45,18 +45,18 @@ func Test_lines(t *testing.T) {
|
||||
args args
|
||||
wantResult []string
|
||||
}{
|
||||
{"1", args{"// none"}, nil},
|
||||
{"2", args{";1.1;2.2"}, nil},
|
||||
{"1", args{"// none"}, []string{}},
|
||||
{"2", args{";1.1;2.2"}, []string{}},
|
||||
{"3", args{"3;1.1;2.2"}, []string{"3;1.1;2.2"}},
|
||||
{"4", args{"4;1.1;"}, []string{"4;1.1;"}},
|
||||
{"5", args{"5;1.1;2.2,3.3"}, []string{"5;1.1;2.2,3.3"}},
|
||||
{"6", args{"6;1.1,2.2;3.3,4.4"}, []string{"6;1.1,2.2;3.3,4.4"}},
|
||||
{"7", args{"7;1.1,2.2;3.3,4.4-5.5"}, []string{"7;1.1,2.2;3.3,4.4-5.5"}},
|
||||
{"8", args{"8;1.1;2.2;"}, nil},
|
||||
{"9", args{"9;,1.1;2.2"}, nil},
|
||||
{"10", args{"10;1.1"}, nil},
|
||||
{"11", args{"11;1.1;2.2,"}, nil},
|
||||
{"12", args{"// 13;1.1;2.2 "}, nil},
|
||||
{"8", args{"8;1.1;2.2;"}, []string{}},
|
||||
{"9", args{"9;,1.1;2.2"}, []string{}},
|
||||
{"10", args{"10;1.1"}, []string{}},
|
||||
{"11", args{"11;1.1;2.2,"}, []string{}},
|
||||
{"12", args{"// 13;1.1;2.2 "}, []string{}},
|
||||
{"13", args{"13;1.1;2.2 // none"}, []string{"13;1.1;2.2"}},
|
||||
{"14", args{"14;1.1;2.2 "}, []string{"14;1.1;2.2"}},
|
||||
{"15", args{" 15;1.1;2.2"}, []string{"15;1.1;2.2"}},
|
||||
|
@ -1,7 +1,6 @@
|
||||
package write
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
@ -38,5 +37,5 @@ func (dw dataWriter) Write(data data.Output) {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Println("write", n, "bytes to", dw.File)
|
||||
log.Println("write", n, "bytes to", dw.File)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user