This commit is contained in:
Tomas Dvorak
2025-10-28 22:38:27 +01:00
parent 3d621e2187
commit 823fabee02
106 changed files with 9011 additions and 3930 deletions
+43 -13
View File
@@ -37,6 +37,11 @@ func BuildNewsletterDigest(cacheDir string, prefs NewsletterPrefs) (subject stri
art := readJSON(filepath.Join(cacheDir, "articles.json"))
ev := readJSON(filepath.Join(cacheDir, "events_upcoming.json"))
facr:= readJSON(filepath.Join(cacheDir, "facr_club_info.json"))
// Club name for subject personalization (fallback to default)
set := readJSON(filepath.Join(cacheDir, "settings.json"))
sm := asMap(set)
clubName := strings.TrimSpace(str(sm["club_name"], ""))
if clubName == "" { clubName = "Fotbal Club" }
sections := make([]string, 0, 4)
@@ -73,10 +78,10 @@ func BuildNewsletterDigest(cacheDir string, prefs NewsletterPrefs) (subject stri
}
if len(sections) == 0 {
return "Fotbal Club přehled", "<p>Pro vybrané preference nyní nemáme novinky.</p>"
return fmt.Sprintf("%s přehled", clubName), "<p>Pro vybrané preference nyní nemáme novinky.</p>"
}
subject = "Fotbal Club novinky a zápasy"
subject = fmt.Sprintf("%s novinky a zápasy", clubName)
html = strings.Join(sections, "\n\n")
return subject, html
}
@@ -125,12 +130,22 @@ func pickUpcomingEvents(v any, n int) []Event {
Time: str(m["time"], ""),
Url: str(m["url"], ""),
}
if e.Date == "" {
st := str(m["start_time"], "")
if st != "" {
if tm, err := time.Parse(time.RFC3339, st); err == nil {
lt := tm.In(time.Local)
e.Date = lt.Format("2006-01-02")
e.Time = lt.Format("15:04")
}
}
}
out = append(out, e)
}
return out
}
type Match struct { Home, Away, Date, Time, Competition, Link, Score string }
type Match struct { Home, Away, Date, Time, Competition, CompCode, Link, Score string }
func pickUpcomingMatchesFromFACR(v any, competitions []string, n int) []Match {
compSet := make(map[string]bool)
@@ -142,7 +157,9 @@ func pickUpcomingMatchesFromFACR(v any, competitions []string, n int) []Match {
ts := parseDateTimeISO(m.Date, m.Time)
if ts.IsZero() || ts.Before(now) { continue }
if len(compSet) > 0 {
if !compSet[strings.ToLower(m.Competition)] { continue }
nameKey := strings.ToLower(strings.TrimSpace(m.Competition))
codeKey := strings.ToLower(strings.TrimSpace(m.CompCode))
if !(compSet[nameKey] || (codeKey != "" && compSet[codeKey])) { continue }
}
out = append(out, m)
if len(out) >= n { break }
@@ -163,7 +180,9 @@ func pickRecentResultsFromFACR(v any, competitions []string, n int, window time.
// treat as result if score like "2:1" exists
if m.Score == "" || !strings.Contains(m.Score, ":") { continue }
if len(compSet) > 0 {
if !compSet[strings.ToLower(m.Competition)] { continue }
nameKey := strings.ToLower(strings.TrimSpace(m.Competition))
codeKey := strings.ToLower(strings.TrimSpace(m.CompCode))
if !(compSet[nameKey] || (codeKey != "" && compSet[codeKey])) { continue }
}
out = append(out, m)
}
@@ -188,19 +207,20 @@ func facrAllMatches(v any) []Match {
for _, c := range asList(comps) {
cm := asMap(c)
compName := str(cm["name"], str(cm["code"], ""))
compCode := str(cm["code"], "")
for _, mm := range asList(cm["matches"]) {
out = append(out, toMatch(asMap(mm), compName))
out = append(out, toMatch(asMap(mm), compName, compCode))
}
}
}
// flat matches fallback
for _, mm := range asList(m["matches"]) {
out = append(out, toMatch(asMap(mm), ""))
out = append(out, toMatch(asMap(mm), "", ""))
}
return out
}
func toMatch(m map[string]any, comp string) Match {
func toMatch(m map[string]any, compName, compCode string) Match {
dt := str(m["date_time"], "")
var date, tm string
if dt != "" && strings.Contains(dt, " ") {
@@ -215,7 +235,8 @@ func toMatch(m map[string]any, comp string) Match {
Away: str(m["away"], ""),
Date: date,
Time: tm,
Competition: str(m["competition"], str(m["competition_name"], comp)),
Competition: str(m["competition"], str(m["competition_name"], compName)),
CompCode: str(m["competition_code"], compCode),
Link: str(m["facr_link"], str(m["report_url"], "#")),
Score: str(m["score"], ""),
}
@@ -224,10 +245,19 @@ func toMatch(m map[string]any, comp string) Match {
func parseDateTimeISO(d, t string) time.Time {
if d == "" { return time.Time{} }
if t == "" { t = "00:00" }
layout := "2006-01-02T15:04:05"
// try shorter HH:MM format
if len(t) == 5 { return parseTime("2006-01-02T15:04", d+"T"+t) }
return parseTime(layout, d+"T"+t)
if strings.Contains(d, ".") {
if len(t) == 5 {
if tm := parseTime("02.01.2006 15:04", d+" "+t); !tm.IsZero() { return tm }
}
if tm := parseTime("02.01.2006 15:04:05", d+" "+t); !tm.IsZero() { return tm }
if tm := parseTime("02.01.2006 15:04", d+" "+t); !tm.IsZero() { return tm }
}
if len(t) == 5 {
if tm := parseTime("2006-01-02T15:04", d+"T"+t); !tm.IsZero() { return tm }
return parseTime("2006-01-02 15:04", d+" "+t)
}
if tm := parseTime("2006-01-02T15:04:05", d+"T"+t); !tm.IsZero() { return tm }
return parseTime("2006-01-02 15:04:05", d+" "+t)
}
func parseTime(layout, s string) time.Time {