Init repo

This commit is contained in:
Paul Brinkmeier 2024-07-17 07:29:45 +02:00
commit dceea169c2
5 changed files with 192 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
result
vrnp
*.swp

27
flake.lock generated Normal file
View File

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1720957393,
"narHash": "sha256-oedh2RwpjEa+TNxhg5Je9Ch6d3W1NKi7DbRO1ziHemA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "693bc46d169f5af9c992095736e82c3488bf7dbb",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

19
flake.nix Normal file
View File

@ -0,0 +1,19 @@
{
description = "vrnp";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
};
outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in {
devShell.${system} = pkgs.mkShellNoCC {
packages = [
pkgs.go
];
};
};
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module pbrinkmeier/vrnp
go 1.22.5

140
main.go Normal file
View File

@ -0,0 +1,140 @@
package main
import "encoding/json"
import "fmt"
import "log"
import "net/http"
import "net/url"
import "slices"
import "strconv"
type DMResponse struct {
Departures []DMDeparture `json:"departureList"`
}
type DMDeparture struct {
StopName string `json:"stopName"`
Platform string `json:"platform"`
Countdown string `json:"countdown"`
DateTime DMDateTime `json:"dateTime"`
RealDateTime *DMDateTime `json:"realDateTime"`
ServingLine DMServingLine `json:"servingLine"`
OnwardStopSeq []DMStop `json:"onwardStopSeq"`
}
type DMServingLine struct {
Symbol string `json:"symbol"`
Direction string `json:"direction"`
}
type DMStop struct {
PlaceID string `json:"placeID"`
Place string `json:"place"`
NameWO string `json:"nameWO"`
}
type DMDateTime struct {
Hour string `json:"hour"`
Minute string `json:"minute"`
}
// TODO: Use different client (with timeout)
func FetchDepartures(stopId string) (*DMResponse, error) {
// Create request object
req, err := http.NewRequest("GET", "https://www.vrn.de/mngvrn/XML_DM_REQUEST", nil)
if err != nil {
return nil, err
}
// Configure our request
query := url.Values{}
query.Set("coordOutputFormat", "EPSG:4326")
query.Set("depType", "stopEvents")
query.Set("includeCompleteStopSeq", "1")
query.Set("limit", "10")
query.Set("locationServerActive", "0")
query.Set("mode", "direct")
query.Set("name_dm", stopId)
query.Set("outputFormat", "json")
query.Set("type_dm", "stop")
query.Set("useOnlyStops", "1")
query.Set("useRealtime", "1")
req.URL.RawQuery = query.Encode()
// Send the request
res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
var dmResponse DMResponse
err = json.NewDecoder(res.Body).Decode(&dmResponse)
if err != nil {
return nil, err
}
return &dmResponse, nil
}
func main() {
http.HandleFunc("/departures", func(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
if query["stop_id"] == nil || len(query["stop_id"]) < 1 {
http.Error(w, "Missing query parameter: stop_id", http.StatusBadRequest)
return
}
stopId := query["stop_id"][0]
var platform *string = nil
if query["platform"] != nil && len(query["platform"]) != 0 {
platform = &query["platform"][0]
}
ds, err := FetchDepartures(stopId)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, d := range ds.Departures {
if platform != nil {
if d.Platform != *platform {
continue
}
}
direction := d.ServingLine.Direction
if len(d.OnwardStopSeq) != 0 {
last := d.OnwardStopSeq[len(d.OnwardStopSeq) - 1]
if slices.Contains([]string{"5", "6"}, last.PlaceID) {
direction = last.NameWO
}
}
leaving := fmt.Sprintf("%s min", d.Countdown)
countdown, err := strconv.Atoi(d.Countdown)
if err == nil {
if countdown == 0 {
leaving = "sofort"
}
if countdown > 20 {
dt := d.DateTime
if d.RealDateTime != nil {
dt = *d.RealDateTime
}
leaving = fmt.Sprintf("%02s:%02s", dt.Hour, dt.Minute)
}
}
fmt.Fprintf(w, "%2s %-22s %6s\n",
d.ServingLine.Symbol,
direction[:min(len(direction), 22)],
leaving,
)
}
})
log.Fatal(http.ListenAndServe(":8000", nil))
}