~mil/mepo-devel

mobroute: formatters: add csv support for stoptimesmap v1 APPLIED

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
Export patchset (mbox)
How do I use this?

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 -3
Learn more about email & git

[PATCH mobroute 1/3] formatters: add csv support for stoptimesmap Export this patch

---
 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

[PATCH mobroute 2/3] formatters.go: use defer for flush Export this patch

---
 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

[PATCH mobroute 3/3] formatters.go: add csv support to formatroute Export this patch

---
 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