You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

150 lines
3.2 KiB

package statusscreen
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/olekukonko/tablewriter"
"io/ioutil"
"log"
"net/http"
"time"
)
// SL is my SL struct
type SL struct {
Config *Config
lastResponse SLResponse
lastRefresh int64
}
// SLResponse is a struct to get the interesting data from API Responses
type SLResponse struct {
StatusCode int
ExecutionTime int
ResponseData struct {
LatestUpdate string
Metros []struct {
LineNumber string
Destination string
TimeTabledDateTime string
ExpectedDateTime string
TransportMode string
}
StopPointDeviations []struct {
Deviation struct {
Text string
}
}
}
}
// GetOutput returns a rendered result of this module
func (sl *SL) GetOutput() string {
var b bytes.Buffer
// Prepare table
table := tablewriter.NewWriter(&b)
table.SetHeader([]string{
"Line",
"Destination",
"DisplayTime",
"Timetable",
"Expcted",
})
// Check if it's time to refresh yet
if (sl.lastRefresh + sl.Config.SL.RefreshDelay) <= time.Now().Unix() {
// If it is, refresh
sldata, err := sl.getTimeTable()
// If no error occured, save the latest data to the struct
if err == nil {
sl.lastResponse = sldata
sl.lastRefresh = time.Now().Unix()
}
if err != nil {
log.Fatal(err)
}
}
for _, v := range sl.lastResponse.ResponseData.Metros {
formattedTime, _ := sl.formatDisplayTime(v.ExpectedDateTime)
table.Append([]string{
v.LineNumber,
v.Destination,
formattedTime,
v.TimeTabledDateTime[11:], // Remove YYYY-MM-DDT from the beginning of the string
v.ExpectedDateTime[11:], // Remove YYYY-MM-DDT from the beginning of the string
})
}
table.Render()
return b.String()
}
func (sl *SL) getTimeTable() (SLResponse, error) {
parsedResponse := SLResponse{}
// Construct URL with APIKey and Site
url := fmt.Sprintf(sl.Config.SL.APIURL, sl.Config.SL.APIKey, sl.Config.SL.SiteID)
// Set up http client to talk to SL
client := http.Client{
Timeout: time.Second * 5,
}
// Do request
resp, err := client.Get(url)
if err != nil {
return parsedResponse, err
}
// Read response
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
return parsedResponse, readErr
}
// Parse response from SL
parseErr := json.Unmarshal(body, &parsedResponse)
if parseErr != nil {
return parsedResponse, parseErr
}
return parsedResponse, nil
}
func (sl *SL) formatDisplayTime(expected string) (string, error) {
myTimeZone, _ := time.Now().Zone()
then, err := time.Parse("2006-01-02T15:04:05 MST", expected+" "+myTimeZone)
if err != nil {
log.Fatal(err)
}
timeLeft := time.Since(then).Seconds() * -1
// If time is less than zero
if timeLeft < 0 {
return "undefined", errors.New("Train is gone already")
}
// If time is less than one minute, show seconds
if timeLeft <= 60 && timeLeft > 0 {
return fmt.Sprintf("%d sec", int(timeLeft)), nil
}
// If time is less than one hour, show minutes
if timeLeft <= 3600 && timeLeft > 0 {
return fmt.Sprintf("%d min", int(timeLeft)/60), nil
}
// Otherwise, just return a timestamp: HH:MM:SS
return fmt.Sprintf("%02d:%02d:%02d", then.Hour(), then.Minute(), then.Second()), nil
}