Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock bustime server #30

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ go.work

node_modules

# Binaries
nola-transit-map
server
__debug_*

.vscode/*
# Track vscode debugger config
!.vscode/launch.json

.DS_Store
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": "0.2.0",
"configurations": [

{
"name": "Dev Mode",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "./",
"env": {
"DEV": "1",
"CLEVER_DEVICES_KEY": "DEV",
"CLEVER_DEVICES_IP": "DEV"
}
}
]
}
15 changes: 11 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
CLEVER_DEVICES_KEY?=""
CLEVER_DEVICES_IP?=""

build:
npm install
npm run build
Expand All @@ -12,5 +9,15 @@ run:
show:
open http://localhost:8080

### DEV ###

mock:
cd mock_bustime_server && go build && ./server

dev:
npm install
go build
sh -c 'DEV=1 CLEVER_DEVICES_KEY=1 CLEVER_DEVICES_IP=1 ./nola-transit-map' || echo "Couldn't run the binary."

watch:
npm run watch
npm run watch
47 changes: 29 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,52 @@ Realtime map of all New Orleans public transit vehicles (streetcars and busses).
For some reason, going from the old RTA app to the new Le Pass app has resulted in the loss of realtime functionality. Not having realtime makes
getting around the city extremely frustrating. This map is just a stop gap to get the data out to people again.

### Needs to be done
### Needs to be Done

* somehow communicate the staleness of the data to the user (we have a status indicator for the connection but could use the vehicle timestamps)
* nice icons and popups for the vehicles
* show the user's location on the map

### Developing
### Contributing

You need to get the key from Ben on Slack in #civic-hacking. If you aren't in the NOLA Devs slack here is an invite: https://nola.slack.com/join/shared_invite/zt-4882ja82-iGm2yO6KCxsi2aGJ9vnsUQ
Join #civic-hacking in the Nola Devs Slack channel, where this project is discussed: https://nola.slack.com/join/shared_invite/zt-4882ja82-iGm2yO6KCxsi2aGJ9vnsUQ.

You need a few things your machine on your machine to build the project. If you are an `asdf` user there is a .tool-versions file with acceptable versions of node, npm, and go, but not make to keep from conflicting with system build tools.
The API key is a protected secret. Only a few have access, hence the included mock server that is used in DEV mode.

You need a few things on your machine to build the project. If you are an `asdf` user there is a .tool-versions file with acceptable versions of node, npm, and go, but not make to keep from conflicting with system build tools.

* node and npm
* go
* make

First build. This builds the frontend application and compiles the go code:
### To Run in Development:

```
make build
```
1. Run the mock bustime server in a terminal. The mock server serves fake vehicle data. Vehicles will appear stationary.
```
# terminal tab 1 - Mock bustime server
make mock
```

To run:
2. Run the main server _in another terminal_.
```
# terminal tab 2 - Go backend
make dev
```

```
make run CLEVER_DEVICES_KEY=thekey CLEVER_DEVICES_IP=ipaddr
```
3. (Optional) If working on the frontend, you probably want changes to trigger a JS build automatically. You'll still have to refresh the page to see changes.
_In a 3rd terminal_:
```
# terminal tab 3 - React frontend
make watch
```

Open the frontend [http://localhost:8080](http://localhost:8080)
4. Open the frontend [http://localhost:8080](http://localhost:8080)

You may need to refresh the page after the browser window is automatically opened by the `make` command.

You need to run `make build` (or `npm run build`) to build the frontend code. It doesn't auto-build. You can run an auto-build in a new tab:
### To Run in Production:

Add the API and IP env vars to `make run`:
```
make watch
```

but you still need to refresh the page
make build && make run CLEVER_DEVICES_KEY=thekey CLEVER_DEVICES_IP=ipaddr
```
46 changes: 36 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ const (

// Send pings to client with this period. Must be less than pongWait.
pingPeriod = (pongWait * 9) / 10

// Use in place of Clever Devices URL when in DEV mode
mockCleverDevicesUrl = "http://localhost:8081/getvehicles"

// Clever Devices API URL: http://[host:port]/bustime/api/v3/getvehicles
// http://ride.smtd.org/bustime/apidoc/docs/DeveloperAPIGuide3_0.pdf
cleverDevicesUrlFormatter = "https://%s/bustime/api/v3/getvehicles"

// Append to Clever Devices base url (above).
// tmres=m -> time resolution: minute.
// rtpidatafeed=bustime -> specify the bustime data feed.
// format=json -> respond with json (as opposed to XML).
its-all-waves marked this conversation as resolved.
Show resolved Hide resolved
cleverDevicesVehicleQueryFormatter = "%s?key=%s&tmres=m&rtpidatafeed=bustime&format=json"
)

var (
Expand All @@ -30,6 +43,8 @@ var (
ReadBufferSize: 1024,
WriteBufferSize: 1024,
}

DEV = false
)

type VehicleTimestamp struct {
Expand Down Expand Up @@ -127,7 +142,7 @@ type BustimeResponse struct {
type Config struct {
Key string `yaml:"key"`
Interval time.Duration `yaml:"interval"`
Url string `yaml:"url"`
BaseUrl string `yaml:"url"`
}

type Scraper struct {
Expand All @@ -145,16 +160,22 @@ func NewScraper() *Scraper {
panic("Need to set environment variable CLEVER_DEVICES_KEY. Try `make run CLEVER_DEVICES_KEY=thekey`. Get key from Ben on slack")
}

baseUrl := fmt.Sprintf(cleverDevicesUrlFormatter, ip)
if DEV {
baseUrl = mockCleverDevicesUrl
}
config := &Config{
Url: fmt.Sprintf("https://%s/bustime/api/v3/getvehicles", ip),
BaseUrl: baseUrl,
Interval: 10 * time.Second,
Key: api_key,
}

tr := &http.Transport{
MaxIdleConnsPerHost: 1024,
TLSHandshakeTimeout: 0 * time.Second,
}
client := &http.Client{Transport: tr}

return &Scraper{
client,
config,
Expand All @@ -172,18 +193,19 @@ func (s *Scraper) Start(vs chan []Vehicle) {

func (v *Scraper) fetch() *BustimeData {
key := v.config.Key
baseURL := v.config.Url
url := fmt.Sprintf("%s?key=%s&tmres=m&rtpidatafeed=bustime&format=json", baseURL, key)
baseURL := v.config.BaseUrl
url := fmt.Sprintf(cleverDevicesVehicleQueryFormatter, baseURL, key)
log.Println("Scraper URL:", url)
resp, err := v.client.Get(url)
if err != nil {
log.Println("ERROR: Scraper response:", err)
}
if resp.Body != nil {
defer resp.Body.Close()
}
if err != nil {
log.Println(err)
}
body, readErr := ioutil.ReadAll(resp.Body)
if readErr != nil {
log.Fatal(readErr)
log.Fatal("ERROR: Scraper response reader:", readErr)
}

result := &BustimeResponse{}
Expand Down Expand Up @@ -220,10 +242,9 @@ func (b *VehicleBroadcaster) Unregister(c VehicleChannel) {
}

func (b *VehicleBroadcaster) Start() {
//config := bustime.GetConfig()
scraper := NewScraper()
defer scraper.Close()
log.Println("start sraper")
log.Println("Starting scraper")
go scraper.Start(b.incoming)
b.broadcast()
}
Expand Down Expand Up @@ -341,6 +362,11 @@ func (s *Server) serveWs(w http.ResponseWriter, r *http.Request) {
}

func main() {
if _, exists := os.LookupEnv("DEV"); exists {
DEV = true
log.Println("Set to DEV mode.")
}

server := NewServer()
server.Start()
}
3 changes: 3 additions & 0 deletions mock_bustime_server/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module server

go 1.23.3
20 changes: 20 additions & 0 deletions mock_bustime_server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"log"
"net/http"
)

const port = ":8081"

func main() {
http.HandleFunc(
"/getvehicles", // ignores query params
func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./mock_vehicles.json")
log.Println("GET /getvehicles :: Served Vehicles")
},
)
log.Printf("\n\nMock Clever Devices Bustime server is running at: http://localhost%s \n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
Loading