Files
golifehk/datasources/kmb/QueryResult.go
2026-03-08 15:38:28 +08:00

220 lines
4.7 KiB
Go

package kmb
import (
"fmt"
"sort"
"strings"
"time"
query "github.com/tgckpg/golifehk/query"
utils "github.com/tgckpg/golifehk/utils"
)
type QueryResult struct {
Schedules *map[*RouteStop]*[]*Schedule
Lang string
Error error
Query *query.QueryObject
isConsumed bool
dataType string
tableData [][]query.TableCell
}
func writeRouteHead(sb *strings.Builder, r *RouteStop) {
utils.WriteMDv2Text(sb, r.RouteId)
if r.Direction == "O" {
sb.WriteString("↑")
} else if r.Direction == "I" {
sb.WriteString("↓")
}
if r.ServiceType != "1" {
utils.WriteMDv2Text(sb, utils.ToPower(r.ServiceType))
}
}
func writeShortRoute(lang *string, sb *strings.Builder, r *RouteStop) {
if r.PrevStop() != nil {
utils.WriteMDv2Text(sb, (*(r.PrevStop().BusStop).Name)[*lang])
sb.WriteString(" \\> ")
}
sb.WriteString("*")
utils.WriteMDv2Text(sb, (*(r.BusStop).Name)[*lang])
sb.WriteString("*")
if r.NextStop() != nil {
sb.WriteString(" \\> ")
utils.WriteMDv2Text(sb, (*(r.NextStop().BusStop).Name)[*lang])
}
sb.WriteString("\n")
}
func (this QueryResult) DataType() string { return this.dataType }
func (this QueryResult) Consumed() bool { return this.isConsumed }
func (this QueryResult) GetTableData() [][]query.TableCell { return this.tableData }
func (this *QueryResult) Message() (string, error) {
this.dataType = "PlainText"
if this.Error != nil {
return "", this.Error
}
sb := strings.Builder{}
if 0 < len(*this.Query.Results) {
// Print Stop Names, then print the list of routes
if this.Query.Key == "" {
loc := this.Query.Message.Location
if loc != nil {
sb.WriteString("九巴 100m")
this.dataType = "Table"
table := [][]query.TableCell{}
for _, item := range *this.Query.Results {
b := any(item).(*BusStop)
row := []query.TableCell{}
cell := query.TableCell{
Name: fmt.Sprintf("%.2fm %s", b.Dist(loc.Lat(), loc.Lon()), (*b.Name)[this.Lang]),
Value: fmt.Sprintf("%s", b.BusStopId),
}
row = append(row, cell)
for _, r := range *b.Routes {
sb_i := strings.Builder{}
writeRouteHead(&sb_i, r)
cell := query.TableCell{
Name: sb_i.String(),
Value: fmt.Sprintf("%s %s", r.RouteId, (*b.Name)[this.Lang]),
}
row = append(row, cell)
}
table = append(table, row)
}
this.tableData = table
} else {
busStops := map[string]*BusStop{}
for _, item := range *this.Query.Results {
var r *RouteStop
r = any(item).(*RouteStop)
b := r.BusStop
if b.Routes == nil {
continue
}
busStops[b.BusStopId] = b
}
for _, b := range busStops {
utils.WriteMDv2Text(&sb, (*b.Name)[this.Lang])
sb.WriteString("\n ")
for _, route := range *b.Routes {
writeRouteHead(&sb, route)
sb.WriteString(" ")
}
sb.WriteString("\n")
}
}
// We got a route key
} else {
// We also got other search keys with 1 < Results
// Get the ETA for this stop
if 1 < len(*this.Query.SearchTerms) {
now := time.Now()
for _, item := range *this.Query.Results {
var r *RouteStop
r = any(item).(*RouteStop)
writeRouteHead(&sb, r)
sb.WriteString("\n")
writeShortRoute(&this.Lang, &sb, r)
for _, schedule := range *(*this.Schedules)[r] {
if !schedule.ETA.IsZero() {
_m := schedule.ETA.Sub(now).Minutes()
sb.WriteString(" \\* ")
txt := "%.0f min(s)"
if this.Lang == "zh-Hant" {
txt = "%.0f 分鐘"
}
utils.WriteMDv2Text(&sb, fmt.Sprintf(txt, _m))
if _m < 0 {
sb.WriteString(" 走左了?")
}
}
if schedule.Remarks_en != "" {
sb.WriteString(" \\*\\* ")
switch this.Lang {
case "en":
utils.WriteMDv2Text(&sb, schedule.Remarks_en)
case "zh-Hant":
utils.WriteMDv2Text(&sb, schedule.Remarks_tc)
}
}
sb.WriteString("\n")
}
sb.WriteString("\n")
}
// We got only the route key, proceed to list the route stops
} else {
// Result contains all route stops, we only need the starting one
routes := []*RouteStop{}
for _, item := range *this.Query.Results {
var r *RouteStop
r = any(item).(*RouteStop)
if r.PrevStop() == nil {
routes = append(routes, r)
}
}
sort.Sort(ByRoute(routes))
for _, r := range routes {
writeRouteHead(&sb, r)
sb.WriteString("\n")
for {
b := *r.BusStop
utils.WriteMDv2Text(&sb, (*b.Name)[this.Lang])
r = r.NextStop()
if r == nil {
break
}
sb.WriteString(" \\> ")
}
sb.WriteString("\n")
}
}
}
} else {
return "", fmt.Errorf("No Results")
}
return sb.String(), nil
}