Partially working draft

This commit is contained in:
斟酌 鵬兄 2022-09-14 21:21:39 +08:00
parent afb73b70ff
commit 534bc70f0f
6 changed files with 151 additions and 40 deletions

View File

@ -0,0 +1,27 @@
package bus
type BusStop struct {
RouteId string
Direction string
StationSeq int
StationId string
Latitude float64
Longtitude float64
Name *map[string] string
RouteStops *map[int] *BusStop
}
func ( busStop BusStop ) PrevStop() *BusStop {
if v, hasKey := (*busStop.RouteStops)[ busStop.StationSeq - 1 ]; hasKey {
return v
}
return nil
}
func ( busStop BusStop ) NextStop() *BusStop {
if v, hasKey := (*busStop.RouteStops)[ busStop.StationSeq + 1 ]; hasKey {
return v
}
return nil
}

View File

@ -0,0 +1,48 @@
package bus
import (
"fmt"
"strings"
)
type QueryResult struct {
Schedules *map[BusStop] *BusStopBuses
Lang string
Error error
}
func ( result QueryResult ) Message() string {
if result.Error != nil {
return fmt.Sprintf( "%s", result.Error )
}
sb := strings.Builder{}
for busStop, buses := range *result.Schedules {
if busStop.PrevStop() != nil {
sb.WriteString( (*busStop.PrevStop().Name)[ result.Lang ] )
sb.WriteString( " > *" )
}
sb.WriteString( (*busStop.Name)[ result.Lang ] )
sb.WriteString( "*" )
if busStop.NextStop() != nil {
sb.WriteString( " > " )
sb.WriteString( (*busStop.NextStop().Name)[ result.Lang ] )
}
sb.WriteString( "\n" )
for _, bus := range buses.Buses {
sb.WriteString( " * " )
sb.WriteString( bus.ETAText )
sb.WriteString( "\n" )
}
sb.WriteString( "\n" )
}
return sb.String()
}

View File

@ -27,14 +27,15 @@ type Bus struct {
LineRef string `json:"lineRef"`
}
type BusStopSchedules struct {
type BusStopBuses struct {
Buses [] Bus `json:"bus"`
BusStopId string `json:"busStopId"`
Suspended string `json:"isSuspended"`
}
type BusSchedule struct {
RefreshTime int `json:"appRefreshTimeInSecond,string"`
BusStops [] BusStopSchedules `json:"busStop"`
BusStops [] BusStopBuses `json:"busStop"`
}
func getSchedule( lang string, routeName string ) ( *BusSchedule, error ) {

View File

@ -12,19 +12,6 @@ import (
"github.com/tgckpg/golifehk/utils"
)
type BusStop struct {
RouteId string
Direction string
StationSeq string
StationId string
Latitude float64
Longtitude float64
Name_zhant string
Name_en string
}
var mBusStops *map[string]BusStop
var CSV_BUSSTOPS string = filepath.Join( utils.WORKDIR, "mtr_bus_stops.csv" )
func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
@ -36,6 +23,8 @@ func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
}
busStops := map[string]BusStop{}
routeStops := map[string] map[string] map[int] *BusStop{}
var headers []string
for i, line := range entries {
if i == 0 {
@ -45,6 +34,8 @@ func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
}
var entry BusStop
i18n_Name := map[string] string{}
for j, value := range line {
switch headers[j] {
case "ROUTE_ID":
@ -52,7 +43,8 @@ func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
case "DIRECTION":
entry.Direction = value
case "STATION_SEQNO":
entry.StationSeq = value
v, _ := strconv.Atoi( value )
entry.StationSeq = v
case "STATION_ID":
entry.StationId = value
case "STATION_LATITUDE":
@ -62,9 +54,9 @@ func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
v, _ := strconv.ParseFloat( value, 64 )
entry.Longtitude = v
case "STATION_NAME_CHI":
entry.Name_zhant = value
i18n_Name["zh"] = value
case "STATION_NAME_ENG":
entry.Name_en = value
i18n_Name["en"] = value
default:
return nil, fmt.Errorf( "Unknown header \"%s\"", headers[j] )
}
@ -74,6 +66,26 @@ func readBusStopData( r io.Reader ) ( *map[string]BusStop, error ) {
return nil, fmt.Errorf( "Duplicated entry %+v", entry )
}
routeDir, hasKey := routeStops[ entry.RouteId ]
if !hasKey {
routeStops[ entry.RouteId ] = map[string] map[int] *BusStop{}
routeDir = routeStops[ entry.RouteId ]
}
route, hasKey := routeDir[ entry.Direction ]
if !hasKey {
routeDir[ entry.Direction ] = map[int] *BusStop{}
route = routeDir[ entry.Direction ]
}
_, hasKey = route[ entry.StationSeq ]
if !hasKey {
route[ entry.StationSeq ] = &entry
}
entry.Name = &i18n_Name
entry.RouteStops = &route
busStops[ entry.StationId ] = entry
}
return &busStops, nil

View File

@ -1,41 +1,68 @@
package bus
import (
"errors"
"fmt"
"strings"
"github.com/tgckpg/golifehk/utils"
)
type QueryObject struct {
type queryObj struct {
Route string
BusStops *[]BusStop
}
type QueryResult struct {
BusStops []BusStop
err string
}
type Term struct {
type qTerm struct {
Value string
ProblyRoute bool
}
func Query( message string ) *QueryResult {
return &QueryResult{ err: "No Result" }
func Query( lang string, message string ) *QueryResult {
qo, err := parse( message )
if err != nil {
return &QueryResult{ Error: err }
}
if qo.Route != "" {
schedules, err := getSchedule( lang, qo.Route )
if err != nil {
return &QueryResult{ Error: err }
}
if len( schedules.BusStops ) == 0 {
return &QueryResult{ Error: errors.New( "Schedules are empty. Maybe outside service time?" ) }
}
matches := map[BusStop] *BusStopBuses{}
for _, busStop := range *qo.BusStops {
for _, busStopSch := range schedules.BusStops {
if busStopSch.BusStopId == busStop.StationId {
matches[busStop] = &busStopSch
break
}
}
}
return &QueryResult{ Lang: lang, Schedules: &matches }
}
return &QueryResult{ Error: errors.New( "No Result" ) }
}
func test( entry BusStop, val string ) bool {
switch true {
case strings.Contains( entry.Name_zhant, val ):
case strings.Contains( (*entry.Name)["zh"], val ):
fallthrough
case strings.Contains( entry.Name_en, val ):
case strings.Contains( (*entry.Name)["en"], val ):
return true
}
return false
}
func parse( line string ) ( *QueryObject, error ) {
func parse( line string ) ( *queryObj, error ) {
busStops, err := getBusStops()
if err != nil {
@ -47,10 +74,10 @@ func parse( line string ) ( *QueryObject, error ) {
matches := []BusStop{}
// Sanitize and assume properties for each of the keywords
terms := []Term{}
terms := []qTerm{}
for _, val := range strings.Split( line, " " ) {
val = strings.ToUpper( strings.Trim( val, " " ) )
term := Term{
term := qTerm{
Value: val,
ProblyRoute: strings.ContainsAny( val, utils.ROUTE_CHARS ),
}
@ -99,5 +126,5 @@ func parse( line string ) ( *QueryObject, error ) {
matches = matches_in
}
return &QueryObject{ Route: route, BusStops: &matches }, err
return &queryObj{ Route: route, BusStops: &matches }, err
}

View File

@ -5,12 +5,8 @@ import (
"testing"
)
func TestQuerySchedule(t *testing.T) {
qo, err := parse( "K74 天瑞" )
if err != nil {
t.Error( err )
}
func TestQuerySchedule( t *testing.T ) {
qo := Query( "zh", "K73 池" )
fmt.Printf( "%+v", qo )
fmt.Print( qo.Message() )
}