Phase 6b/7b: per-child decoded periods, separate brief blocks, idempotent calendar (AUD-119)
- Parse each child's own "Today" day widget for the timetable (FR-16); drop the school-wide week calendar's lesson grid and clean the leaked routine rows. - Add the editable codes map (FR-17): subjects, rooms, teachers and period labels, seeded, an unknown code falls back to the raw code; `school codes` CLI. - Brief: Finn's block first, then Harry's, four sections always present (FR-9); periods decoded into plain English; the undated tail is one counted line (FR-18). - Calendar: write periods + work due + work overdue + major events, per child, on every pass. Identity is the stable per-item key, so a re-run never re-inserts (FR-8). morning-brief.sh now runs scan -> calendar push -> notify. - Day-widget labels are 12-hour: 1-6 read as PM, fixing afternoon periods. Proven live on .13: image 0.6.2-phase6b7b; both children's briefs decoded and separate; 35 events in calendar.school; runs 2 and 3 of the scan added nothing. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.lab.audasmedia.com.au/sam/compass_teams_nhs/internal/period"
|
||||
)
|
||||
|
||||
// calendarPxPerHour is the Compass week-grid scale: the day gutter is 1200px
|
||||
@@ -21,13 +23,12 @@ var (
|
||||
calendarTop = regexp.MustCompile(`top:\s*([0-9.]+)px`)
|
||||
// clockPrefix matches the leading "8:55: " of an event label.
|
||||
clockPrefix = regexp.MustCompile(`^(\d{1,2}):(\d{2}):\s*(.*)$`)
|
||||
// periodLabel matches the period part of a lesson label: "5", "C" or
|
||||
// "RLE GROUP D".
|
||||
periodLabel = regexp.MustCompile(`^(\d{1,2}|[A-Z]|RLE GROUP [A-Z])$`)
|
||||
)
|
||||
|
||||
// parseCalendar parses the week calendar into event items. It fails loudly when
|
||||
// the page has no calendar grid (FR-12).
|
||||
// parseCalendar parses the week calendar page. The week calendar is
|
||||
// school-wide and its lesson grid belongs to the eldest child, so routine
|
||||
// lessons are dropped here: each child's own periods come from that child's
|
||||
// day widget (FR-16). Only real school events are kept.
|
||||
func parseCalendar(child string, page Page, loc *time.Location) ([]Item, error) {
|
||||
items, found, err := extractCalendar(child, page, loc)
|
||||
if err != nil {
|
||||
@@ -36,7 +37,13 @@ func parseCalendar(child string, page Page, loc *time.Location) ([]Item, error)
|
||||
if !found {
|
||||
return nil, fmt.Errorf("parse: %s: no calendar grid found in %s (layout changed or fetch failed)", child, page.Slug)
|
||||
}
|
||||
return items, nil
|
||||
out := items[:0]
|
||||
for _, it := range items {
|
||||
if eventIsSchoolEvent(it.Title) {
|
||||
out = append(out, it)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// extractCalendar returns the calendar events in one page. found reports whether
|
||||
@@ -140,8 +147,8 @@ func eventItem(child string, ev *node, page Page, loc *time.Location) (Item, boo
|
||||
// label is "5 - 11HLEGB5 - D8 - LHT"; a school event is
|
||||
// "End of Year Senior Music Concert - HALL (...) - KSH, CFR, ...".
|
||||
func splitEvent(label, title string) (subject, teacher, body string) {
|
||||
parts := splitDash(title)
|
||||
if len(parts) >= 2 && periodLabel.MatchString(parts[0]) {
|
||||
parts := period.SplitDash(title)
|
||||
if len(parts) >= 2 && period.IsPeriodLabel(parts[0]) {
|
||||
for _, p := range parts[1:] {
|
||||
if subject == "" && classCode.MatchString(p) {
|
||||
subject = p
|
||||
@@ -159,11 +166,4 @@ func splitEvent(label, title string) (subject, teacher, body string) {
|
||||
}
|
||||
|
||||
// splitDash splits on " - " and trims each part.
|
||||
func splitDash(s string) []string {
|
||||
raw := strings.Split(s, " - ")
|
||||
out := make([]string, 0, len(raw))
|
||||
for _, p := range raw {
|
||||
out = append(out, strings.TrimSpace(p))
|
||||
}
|
||||
return out
|
||||
}
|
||||
func splitDash(s string) []string { return period.SplitDash(s) }
|
||||
|
||||
Reference in New Issue
Block a user