add early version without tracking with using db-vendo-client
This commit is contained in:
parent
4c409224b0
commit
be7b48ac07
5 changed files with 208 additions and 55 deletions
21
LICENSE
Normal file
21
LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) [year] [fullname]
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -5,26 +5,23 @@ services:
|
|||
build: .
|
||||
depends_on:
|
||||
- mariadb
|
||||
- db-rest
|
||||
environment:
|
||||
- DB_HOST=mariadb
|
||||
- DB_USER=root
|
||||
- DB_PASSWORD=password
|
||||
- DB_NAME=traindb
|
||||
- DB_DSN=root:password@tcp(mariadb:3306)/traindb
|
||||
- API_BASE_URL=http://db-rest:3000
|
||||
- DB_DSN=root:password@tcp(172.28.0.66:3306)/traindb
|
||||
- API_BASE_URL=http://172.28.0.65:3000
|
||||
- MAX_RESULTS=200
|
||||
- DURATION=240
|
||||
- DELETE_AFTER_MINUTES=30
|
||||
- BUS=false
|
||||
- FERRY=false
|
||||
- TRAM=false
|
||||
- TAXI=false
|
||||
# Hildesheim HBF, Braunschweig HBF, Hannover HBF
|
||||
- STATION_IDS=8000169,8000049,8000152
|
||||
restart: always
|
||||
networks:
|
||||
default:
|
||||
dns:
|
||||
ipv4_address: 172.28.0.64
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.5
|
||||
|
@ -38,15 +35,7 @@ services:
|
|||
networks:
|
||||
default:
|
||||
dns:
|
||||
ipv4_address: 172.28.0.65
|
||||
|
||||
db-rest:
|
||||
image: docker.io/derhuerst/db-rest:6
|
||||
ports:
|
||||
- 127.0.0.1:3010:3000
|
||||
restart: always
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: 172.28.0.66
|
||||
|
||||
networks:
|
||||
dns:
|
||||
|
|
3
init.sql
3
init.sql
|
@ -4,5 +4,6 @@ CREATE TABLE IF NOT EXISTS trips (
|
|||
longitude DOUBLE,
|
||||
timestamp DATETIME,
|
||||
train_name VARCHAR(50),
|
||||
fahrt_nr VARCHAR(20)
|
||||
fahrt_nr VARCHAR(20),
|
||||
trip_id VARCHAR(255)
|
||||
);
|
||||
|
|
52
main.go
52
main.go
|
@ -17,11 +17,8 @@ import (
|
|||
)
|
||||
|
||||
type Departure struct {
|
||||
CurrentTripPosition struct {
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
} `json:"currentTripPosition"`
|
||||
When time.Time `json:"when"`
|
||||
TripId string `json:"tripId"`
|
||||
When string `json:"when"`
|
||||
Line struct {
|
||||
Name string `json:"name"`
|
||||
FahrtNr string `json:"fahrtNr"`
|
||||
|
@ -39,30 +36,10 @@ func main() {
|
|||
|
||||
dbDSN := os.Getenv("DB_DSN")
|
||||
apiBaseURL := os.Getenv("API_BASE_URL")
|
||||
maxResults, err := strconv.Atoi(os.Getenv("MAX_RESULTS"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für MAX_RESULTS: %v", err)
|
||||
}
|
||||
duration, err := strconv.Atoi(os.Getenv("DURATION"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für DURATION: %v", err)
|
||||
}
|
||||
includeBus, err := strconv.ParseBool(os.Getenv("BUS"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für BUS: %v", err)
|
||||
}
|
||||
includeFerry, err := strconv.ParseBool(os.Getenv("FERRY"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für FERRY: %v", err)
|
||||
}
|
||||
includeTram, err := strconv.ParseBool(os.Getenv("TRAM"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für TRAM: %v", err)
|
||||
}
|
||||
includeTaxi, err := strconv.ParseBool(os.Getenv("TAXI"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für TAXI: %v", err)
|
||||
}
|
||||
deleteAfter, err := strconv.Atoi(os.Getenv("DELETE_AFTER_MINUTES"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für DELETE_AFTER_MINUTES: %v", err)
|
||||
|
@ -77,7 +54,7 @@ func main() {
|
|||
|
||||
for {
|
||||
for _, stationID := range stationIDs {
|
||||
departures := fetchDepartures(apiBaseURL, stationID, maxResults, duration, includeBus, includeFerry, includeTram, includeTaxi)
|
||||
departures := fetchDepartures(apiBaseURL, stationID, duration)
|
||||
for _, dep := range departures {
|
||||
savePosition(db, dep)
|
||||
}
|
||||
|
@ -87,9 +64,9 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchDepartures(apiBaseURL, stationID string, maxResults, duration int, includeBus, includeFerry, includeTram, includeTaxi bool) []Departure {
|
||||
url := fmt.Sprintf("%s/stops/%s/departures?results=%d&duration=%d&bus=%t&ferry=%t&tram=%t&taxi=%t",
|
||||
apiBaseURL, stationID, maxResults, duration, includeBus, includeFerry, includeTram, includeTaxi)
|
||||
func fetchDepartures(apiBaseURL, stationID string, duration int) []Departure {
|
||||
url := fmt.Sprintf("%s/stops/%s/departures?duration=%d&linesOfStops=false&remarks=false&language=de&nationalExpress=true&national=true®ionalExpress=true®ional=true&suburban=true&bus=false&ferry=false&subway=false&tram=false&taxi=false&pretty=true",
|
||||
apiBaseURL, stationID, duration)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Abrufen der Abfahrten für Station %s: %v\n", stationID, err)
|
||||
|
@ -120,28 +97,29 @@ func fetchDepartures(apiBaseURL, stationID string, maxResults, duration int, inc
|
|||
}
|
||||
|
||||
func savePosition(db *sql.DB, dep Departure) {
|
||||
if dep.CurrentTripPosition.Latitude == 0 && dep.CurrentTripPosition.Longitude == 0 {
|
||||
log.Println("Keine gültige Position verfügbar")
|
||||
whenTime, err := time.Parse(time.RFC3339, dep.When)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Parsen der Zeit: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
today := time.Now().Format("2006-01-02")
|
||||
today := whenTime.Format("2006-01-02")
|
||||
|
||||
var existingID string
|
||||
err := db.QueryRow("SELECT id FROM trips WHERE fahrt_nr = ? AND DATE(timestamp) = ?", dep.Line.FahrtNr, today).Scan(&existingID)
|
||||
err = db.QueryRow("SELECT id FROM trips WHERE fahrt_nr = ? AND DATE(timestamp) = ?", dep.Line.FahrtNr, today).Scan(&existingID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
id := uuid.New().String()
|
||||
_, err = db.Exec("INSERT INTO trips (id, latitude, longitude, timestamp, train_name, fahrt_nr) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
id, dep.CurrentTripPosition.Latitude, dep.CurrentTripPosition.Longitude, dep.When, dep.Line.Name, dep.Line.FahrtNr)
|
||||
_, err = db.Exec("INSERT INTO trips (id, timestamp, train_name, fahrt_nr, trip_id) VALUES (?, ?, ?, ?, ?)",
|
||||
id, whenTime, dep.Line.Name, dep.Line.FahrtNr, dep.TripId)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Speichern der neuen Position: %v\n", err)
|
||||
} else {
|
||||
log.Printf("Neue Position gespeichert (ID: %s, Zug: %s, FahrtNr: %s)\n", id, dep.Line.Name, dep.Line.FahrtNr)
|
||||
}
|
||||
} else if err == nil {
|
||||
_, err = db.Exec("UPDATE trips SET latitude = ?, longitude = ?, timestamp = ?, train_name = ? WHERE id = ?",
|
||||
dep.CurrentTripPosition.Latitude, dep.CurrentTripPosition.Longitude, dep.When, dep.Line.Name, existingID)
|
||||
_, err = db.Exec("UPDATE trips SET timestamp = ?, train_name = ?, trip_id = ? WHERE id = ?",
|
||||
whenTime, dep.Line.Name, dep.TripId, existingID)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Aktualisieren der Position: %v\n", err)
|
||||
} else {
|
||||
|
|
164
main.go.old
Normal file
164
main.go.old
Normal file
|
@ -0,0 +1,164 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type Departure struct {
|
||||
CurrentTripPosition struct {
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
} `json:"currentTripPosition"`
|
||||
When time.Time `json:"when"`
|
||||
Line struct {
|
||||
Name string `json:"name"`
|
||||
FahrtNr string `json:"fahrtNr"`
|
||||
} `json:"line"`
|
||||
}
|
||||
|
||||
type APIResponse struct {
|
||||
Departures []Departure `json:"departures"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||
log.Println("Anwendung gestartet")
|
||||
|
||||
dbDSN := os.Getenv("DB_DSN")
|
||||
apiBaseURL := os.Getenv("API_BASE_URL")
|
||||
maxResults, err := strconv.Atoi(os.Getenv("MAX_RESULTS"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für MAX_RESULTS: %v", err)
|
||||
}
|
||||
duration, err := strconv.Atoi(os.Getenv("DURATION"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für DURATION: %v", err)
|
||||
}
|
||||
includeBus, err := strconv.ParseBool(os.Getenv("BUS"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für BUS: %v", err)
|
||||
}
|
||||
includeFerry, err := strconv.ParseBool(os.Getenv("FERRY"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für FERRY: %v", err)
|
||||
}
|
||||
includeTram, err := strconv.ParseBool(os.Getenv("TRAM"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für TRAM: %v", err)
|
||||
}
|
||||
includeTaxi, err := strconv.ParseBool(os.Getenv("TAXI"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für TAXI: %v", err)
|
||||
}
|
||||
deleteAfter, err := strconv.Atoi(os.Getenv("DELETE_AFTER_MINUTES"))
|
||||
if err != nil {
|
||||
log.Fatalf("Ungültiger Wert für DELETE_AFTER_MINUTES: %v", err)
|
||||
}
|
||||
stationIDs := strings.Split(os.Getenv("STATION_IDS"), ",")
|
||||
|
||||
db, err := sql.Open("mysql", dbDSN)
|
||||
if err != nil {
|
||||
log.Fatal("Fehler beim Verbinden mit der Datenbank: ", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
for {
|
||||
for _, stationID := range stationIDs {
|
||||
departures := fetchDepartures(apiBaseURL, stationID, maxResults, duration, includeBus, includeFerry, includeTram, includeTaxi)
|
||||
for _, dep := range departures {
|
||||
savePosition(db, dep)
|
||||
}
|
||||
}
|
||||
deleteOldEntries(db, deleteAfter)
|
||||
time.Sleep(1 * time.Minute)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchDepartures(apiBaseURL, stationID string, maxResults, duration int, includeBus, includeFerry, includeTram, includeTaxi bool) []Departure {
|
||||
url := fmt.Sprintf("%s/stops/%s/departures?results=%d&duration=%d&bus=%t&ferry=%t&tram=%t&taxi=%t",
|
||||
apiBaseURL, stationID, maxResults, duration, includeBus, includeFerry, includeTram, includeTaxi)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Abrufen der Abfahrten für Station %s: %v\n", stationID, err)
|
||||
return nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Lesen der Antwort für Station %s: %v\n", stationID, err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(body) == 0 {
|
||||
log.Printf("Leere Antwort vom Server für Station %s erhalten\n", stationID)
|
||||
return nil
|
||||
}
|
||||
|
||||
var response APIResponse
|
||||
err = json.Unmarshal(body, &response)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Dekodieren der Abfahrten für Station %s: %v\nAntwort-Body: %s\n", stationID, err, string(body))
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Erfolgreich %d Abfahrten für Station %s abgerufen\n", len(response.Departures), stationID)
|
||||
return response.Departures
|
||||
}
|
||||
|
||||
func savePosition(db *sql.DB, dep Departure) {
|
||||
if dep.CurrentTripPosition.Latitude == 0 && dep.CurrentTripPosition.Longitude == 0 {
|
||||
log.Println("Keine gültige Position verfügbar")
|
||||
return
|
||||
}
|
||||
|
||||
today := time.Now().Format("2006-01-02")
|
||||
|
||||
var existingID string
|
||||
err := db.QueryRow("SELECT id FROM trips WHERE fahrt_nr = ? AND DATE(timestamp) = ?", dep.Line.FahrtNr, today).Scan(&existingID)
|
||||
|
||||
if err == sql.ErrNoRows {
|
||||
id := uuid.New().String()
|
||||
_, err = db.Exec("INSERT INTO trips (id, latitude, longitude, timestamp, train_name, fahrt_nr) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
id, dep.CurrentTripPosition.Latitude, dep.CurrentTripPosition.Longitude, dep.When, dep.Line.Name, dep.Line.FahrtNr)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Speichern der neuen Position: %v\n", err)
|
||||
} else {
|
||||
log.Printf("Neue Position gespeichert (ID: %s, Zug: %s, FahrtNr: %s)\n", id, dep.Line.Name, dep.Line.FahrtNr)
|
||||
}
|
||||
} else if err == nil {
|
||||
_, err = db.Exec("UPDATE trips SET latitude = ?, longitude = ?, timestamp = ?, train_name = ? WHERE id = ?",
|
||||
dep.CurrentTripPosition.Latitude, dep.CurrentTripPosition.Longitude, dep.When, dep.Line.Name, existingID)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Aktualisieren der Position: %v\n", err)
|
||||
} else {
|
||||
log.Printf("Position aktualisiert (ID: %s, Zug: %s, FahrtNr: %s)\n", existingID, dep.Line.Name, dep.Line.FahrtNr)
|
||||
}
|
||||
} else {
|
||||
log.Printf("Fehler bei der Überprüfung des existierenden Eintrags: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteOldEntries(db *sql.DB, deleteAfterMinutes int) {
|
||||
deleteTime := time.Now().Add(time.Duration(-deleteAfterMinutes) * time.Minute)
|
||||
result, err := db.Exec("DELETE FROM trips WHERE timestamp < ?", deleteTime)
|
||||
if err != nil {
|
||||
log.Printf("Fehler beim Löschen alter Einträge: %v\n", err)
|
||||
return
|
||||
}
|
||||
rowsAffected, _ := result.RowsAffected()
|
||||
log.Printf("%d alte Einträge gelöscht\n", rowsAffected)
|
||||
}
|
Loading…
Reference in a new issue