Anjandev Momi: 3 formatters: add csv support for stoptimesmap formatters.go: use defer for flush formatters.go: add csv support to formatroute 4 files changed, 54 insertions(+), 24 deletions(-)
Thanks - applied! I think eventually will make sense to refactor this code so CSV & tables are generated automatically via helper fn passing just [][]string data etc. / so there are no for loops in printing since this is bit repetitive in this formatter code.. but for now this is good. Miles
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~mil/mepo-devel/patches/41441/mbox | git am -3Learn more about email & git
--- calculator/formatters.go | 38 +++++++++++++++++++++++++++----------- main.go | 2 +- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/calculator/formatters.go b/calculator/formatters.go index ef58b49..f5ddb56 100644 --- a/calculator/formatters.go +++ b/calculator/formatters.go @@ -7,26 +7,42 @@ import ( "git.sr.ht/~mil/mobroute/types" "git.sr.ht/~mil/mobroute/util" "os" + "strings" "text/tabwriter" "time" ) func (c *Calculator) FormatStopTimesMap(format string, stopTimesMap map[string]map[types.RouteDirection]*mgtfs.StopTime) { + header := []string{"Stop", "Route", "Direction", "Headsign", "ETA Mins", "ETA Departure"} + underline := []string{"======", "======", "======", "======", "======", "======"} + formattedDats := [][]string{} + for stopID, routesStopTimeMap := range stopTimesMap { + stop := c.LookupStop(stopID) + for routeDirection, stopTime := range routesStopTimeMap { + trip := c.LookupTrip(stopTime.TripID) + minutesAway := int(util.DurationToTime(stopTime.Departure).Sub(time.Now()).Minutes()) + stopDat := []string{stop.Name, routeDirection.Route, routeDirection.Direction, trip.Headsign, fmt.Sprint(minutesAway), fmt.Sprint(stopTime.Departure)} + formattedDats = append(formattedDats, stopDat) + } + } if format == "ascii" { + seperator := "\t" w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - fmt.Fprintf(w, "Stop:\tRoute:\tDirection:\tHeadsign:\tETA Mins\tETA Departure:\n") - fmt.Fprintf(w, "======\t====\t=====\t=====\t=====\t=====\n") - - for stopID, routesStopTimeMap := range stopTimesMap { - stop := c.LookupStop(stopID) - for routeDirection, stopTime := range routesStopTimeMap { - trip := c.LookupTrip(stopTime.TripID) - minutesAway := int(util.DurationToTime(stopTime.Departure).Sub(time.Now()).Minutes()) - fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%dm\t%s\n", stop.Name, routeDirection.Route, routeDirection.Direction, trip.Headsign, minutesAway, stopTime.Departure) - } + defer w.Flush() + fmt.Fprintf(w, strings.Join(header, seperator)+"\n") + fmt.Fprintf(w, strings.Join(underline, seperator)+"\n") + for _, stopDat := range formattedDats { + fmt.Fprintf(w, strings.Join(stopDat, seperator)+"\n") + } + } else if format == "csv" { + seperator := "," + w := os.Stdout + fmt.Fprintf(w, strings.Join(header, seperator)+"\n") + for _, stopDat := range formattedDats { + fmt.Fprintf(w, strings.Join(stopDat, seperator)+"\n") } - w.Flush() } + } func (c *Calculator) FormatStops(format string, stops []*mgtfs.Stop) { diff --git a/main.go b/main.go index 44f1cfe..a16246b 100644 --- a/main.go +++ b/main.go @@ -33,7 +33,7 @@ func main() { debugVVV = flag.Bool("vvv", false, "Debugging info+warnings+debugging enabled") cmd = flag.String("cmd", "help", "Command: one of {stops,stoptimes,route,graph}") - format = flag.String("format", "ascii", "Command: one of {ascii,mepolang,geojson}") + format = flag.String("format", "ascii", "Command: one of {ascii,mepolang,geojson,csv}") cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file") ) -- 2.40.1
--- calculator/formatters.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/calculator/formatters.go b/calculator/formatters.go index f5ddb56..65430e0 100644 --- a/calculator/formatters.go +++ b/calculator/formatters.go @@ -114,6 +114,7 @@ func (c *Calculator) FormatRoute(format string, fromNode *types.Node, toNode *ty if format == "ascii" { w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + defer w.Flush() fmt.Fprintf(w, "Location:\tRoute:\tHeadsign:\tType:\tTransfer\tTime:\n") fmt.Fprintf(w, "=====\t=====\t=====\t=====\t=====\t=====\n") for i := len(nodes) - 1; i >= 0; i-- { @@ -133,7 +134,6 @@ func (c *Calculator) FormatRoute(format string, fromNode *types.Node, toNode *ty nodeDetails.Depart.Format("15:04:05"), ) } - w.Flush() } else if format == "mepolang" { w := bufio.NewWriter(os.Stdout) defer w.Flush() -- 2.40.1
--- calculator/formatters.go | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/calculator/formatters.go b/calculator/formatters.go index 65430e0..6984992 100644 --- a/calculator/formatters.go +++ b/calculator/formatters.go @@ -112,27 +112,41 @@ func (c *Calculator) FormatRoute(format string, fromNode *types.Node, toNode *ty currentNode = currentNode.Parent } - if format == "ascii" { - w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) - defer w.Flush() - fmt.Fprintf(w, "Location:\tRoute:\tHeadsign:\tType:\tTransfer\tTime:\n") - fmt.Fprintf(w, "=====\t=====\t=====\t=====\t=====\t=====\n") + if format == "ascii" || format == "csv" { + header := []string{"Location", "Route", "Headsign", "Type", "Transfer", "Time"} + underline := []string{"=====", "=====", "=====", "=====", "=====", "====="} + nodeDats := [][]string{} for i := len(nodes) - 1; i >= 0; i-- { var prevNode *types.Node = nil if i > 0 { prevNode = nodes[i-1] } nodeDetails := getNodeDetails(nodes[i], prevNode) - fmt.Fprintf( - w, - "%s\t%s\t%s\t%s\t%s\t%s\n", - nodeDetails.From, + nodeDetailsNoSeperator := []string{nodeDetails.From, nodeDetails.Route, nodeDetails.Headsign, nodeDetails.Node.PathFrom, nodeDetails.Transfer, - nodeDetails.Depart.Format("15:04:05"), - ) + nodeDetails.Depart.Format("15:04:05")} + nodeDats = append(nodeDats, nodeDetailsNoSeperator) + } + if format == "ascii" { + seperator := "\t" + w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0) + defer w.Flush() + fmt.Fprintf(w, strings.Join(header, seperator)+"\n") + fmt.Fprintf(w, strings.Join(underline, seperator)+"\n") + for _, nodeDat := range nodeDats { + fmt.Fprintf(w, strings.Join(nodeDat, seperator)+"\n") + } + } else if format == "csv" { + seperator := "," + w := bufio.NewWriter(os.Stdout) + defer w.Flush() + fmt.Fprintf(w, strings.Join(header, seperator)+"\n") + for _, nodeDat := range nodeDats { + fmt.Fprintf(w, strings.Join(nodeDat, seperator)+"\n") + } } } else if format == "mepolang" { w := bufio.NewWriter(os.Stdout) -- 2.40.1
Thanks - applied! I think eventually will make sense to refactor this code so CSV & tables are generated automatically via helper fn passing just [][]string data etc. / so there are no for loops in printing since this is bit repetitive in this formatter code.. but for now this is good. Miles