-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmd_editTimetable.go
131 lines (107 loc) · 3.13 KB
/
cmd_editTimetable.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"log"
"encoding/json"
"github.com/hjson/hjson-go"
"github.com/gwd/session-scheduler/event"
)
type TimetableEditSlot struct {
Time string
IsBreak bool `json:",omitempty"`
}
type TimetableEditDay struct {
DayName string
Slots []TimetableEditSlot
}
type TimetableEdit struct {
Location string
Days []TimetableEditDay
}
var header = `// Location is the normal timezone location; e.g., 'Europe/Berlin'.
// Time should be in the format "2020 Jan 2 15:04".
// Add 'IsBreak: true' to any slot which should be labeled as a break.
`
var format = "2006 Jan 2 15:04"
func EditTimetable() {
// Get timetable. If it's not empty, marshal it to json (perhaps
// with a comment at the top?). Otherwise, use the starter schedule
tt, err := event.GetTimetable("", nil)
if err != nil {
log.Fatalf("Getting timetable: %v")
}
ett := TimetableEdit{Location: DefaultLocation}
if len(tt.Days) > 0 {
// If the timetable is non-empty, copy from tt into ett
ett.Days = make([]TimetableEditDay, len(tt.Days))
for i := range tt.Days {
ed := &ett.Days[i]
td := &tt.Days[i]
ed.DayName = td.DayName
ed.Slots = make([]TimetableEditSlot, len(td.Slots))
for j := range td.Slots {
ed.Slots[j].Time = td.Slots[j].Time.Format(format)
ed.Slots[j].IsBreak = td.Slots[j].IsBreak
}
}
} else {
// Set up an example timetable
ett.Days = []TimetableEditDay{
{"Monday",
[]TimetableEditSlot{
{"2020 Jul 6 14:00", false},
{"2020 Jul 6 14:30", false},
{"2020 Jul 6 15:00", true},
{"2020 Jul 6 15:30", false}}}}
}
outb, err := hjson.MarshalWithOptions(ett, hjson.EncoderOptions{BracesSameLine: true, Eol: "\n", IndentBy: " "})
if err != nil {
log.Fatalf("Marshalling structure: %v", err)
}
outb = append([]byte(header), outb...)
// Execute the editor
inb, err := ExternalEditorBytes(outb)
if err != nil {
log.Fatalf("Editing json: %v", err)
}
// Unmarshal the modified data.
// HACK: hjson seems to have trouble marshalling into
// actual structs, so send it through encoding/json.
ints := map[string]interface{}{}
err = hjson.Unmarshal(inb, &ints)
if err != nil {
log.Fatalf("Importing structure: %v", err)
}
intb, err := json.Marshal(ints)
if err != nil {
log.Fatalf("Intermediate marshal: %v", err)
}
err = json.Unmarshal(intb, &ett)
if err != nil {
log.Fatalf("Intermediate unmarshal: %v", err)
}
// FIXME: It might be nice to feed back the error to the use with
// the same file so they can fix it up.
loc, err := event.LoadLocation(ett.Location)
if err != nil {
log.Fatalf("Loading location: %v", err)
}
tt = event.Timetable{}
tt.Days = make([]event.TimetableDay, len(ett.Days))
for i := range ett.Days {
td := &tt.Days[i]
ed := &ett.Days[i]
td.DayName = ed.DayName
td.Slots = make([]event.TimetableSlot, len(ed.Slots))
for j := range ed.Slots {
td.Slots[j].Time, err = event.ParseInLocation(format, ed.Slots[j].Time, loc)
if err != nil {
log.Fatalf("Error parsing time: %v", err)
}
td.Slots[j].IsBreak = ed.Slots[j].IsBreak
}
}
err = event.TimetableSet(&tt)
if err != nil {
log.Fatalf("Error setting timetable: %v", err)
}
}