2024-09-15 10:46:07 +02:00
|
|
|
package transports
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"github.com/carlmjohnson/requests"
|
2024-10-21 23:14:55 +02:00
|
|
|
"log/slog"
|
2024-09-15 10:46:07 +02:00
|
|
|
"net/http"
|
2024-10-21 23:14:55 +02:00
|
|
|
"time"
|
2024-09-15 10:46:07 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type Stop struct {
|
|
|
|
ID int `json:"id"`
|
|
|
|
Name string `json:"name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Passage struct {
|
|
|
|
Ligne string `json:"ligne"`
|
|
|
|
Delays []string `json:"delais"`
|
|
|
|
Destination Stop `json:"destination"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Passages struct {
|
|
|
|
Passages []Passage `json:"passages"`
|
|
|
|
Stop Stop `json:"stop"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type Config struct {
|
|
|
|
}
|
|
|
|
|
2024-10-21 23:14:55 +02:00
|
|
|
const cacheTimeout = 2 * time.Minute
|
|
|
|
|
2024-09-15 10:46:07 +02:00
|
|
|
type Client struct {
|
|
|
|
client *http.Client
|
|
|
|
config Config
|
2024-10-21 23:14:55 +02:00
|
|
|
|
|
|
|
passagesCache *Passages
|
|
|
|
passagesCacheTime time.Time
|
|
|
|
|
|
|
|
stationCache *Station
|
|
|
|
stationCacheTime time.Time
|
2024-09-15 10:46:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(httpClient *http.Client, config Config) *Client {
|
|
|
|
if httpClient == nil {
|
|
|
|
httpClient = &http.Client{}
|
|
|
|
}
|
|
|
|
return &Client{
|
|
|
|
client: httpClient,
|
|
|
|
config: config,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) GetTCLPassages(ctx context.Context, stop int) (res *Passages, err error) {
|
|
|
|
err = requests.URL("https://tcl.augendre.info").
|
2024-09-15 14:19:01 +02:00
|
|
|
Pathf("/tcl/stop/%v", stop).
|
|
|
|
Client(c.client).
|
|
|
|
ToJSON(&res).
|
|
|
|
Fetch(ctx)
|
|
|
|
if err != nil {
|
2024-10-21 23:14:55 +02:00
|
|
|
if res = c.getPassagesCache(); res != nil {
|
|
|
|
slog.WarnContext(ctx, "retrieving passages from cache")
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2024-09-15 14:19:01 +02:00
|
|
|
return nil, fmt.Errorf("calling api: %w", err)
|
|
|
|
}
|
2024-10-21 23:14:55 +02:00
|
|
|
|
|
|
|
c.passagesCache = res
|
|
|
|
c.passagesCacheTime = time.Now()
|
|
|
|
|
2024-09-15 14:19:01 +02:00
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2024-10-21 23:14:55 +02:00
|
|
|
func (c *Client) getPassagesCache() *Passages {
|
|
|
|
if c.passagesCache != nil && time.Since(c.passagesCacheTime) < cacheTimeout {
|
|
|
|
return c.passagesCache
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-09-15 14:19:01 +02:00
|
|
|
type Station struct {
|
|
|
|
Name string `json:"name"`
|
|
|
|
BikesAvailable int `json:"bikes_available"`
|
|
|
|
DocksAvailable int `json:"docks_available"`
|
|
|
|
AvailabilityCode int `json:"availability_code"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) GetVelovStation(ctx context.Context, station int) (res *Station, err error) {
|
|
|
|
err = requests.URL("https://tcl.augendre.info").
|
|
|
|
Pathf("/velov/station/%v", station).
|
2024-09-15 10:46:07 +02:00
|
|
|
Client(c.client).
|
|
|
|
ToJSON(&res).
|
|
|
|
Fetch(ctx)
|
|
|
|
if err != nil {
|
2024-10-21 23:14:55 +02:00
|
|
|
if res = c.getStationCache(); res != nil {
|
|
|
|
slog.WarnContext(ctx, "retrieving station from cache")
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
2024-09-15 10:46:07 +02:00
|
|
|
return nil, fmt.Errorf("calling api: %w", err)
|
|
|
|
}
|
2024-10-21 23:14:55 +02:00
|
|
|
|
|
|
|
c.stationCache = res
|
|
|
|
c.stationCacheTime = time.Now()
|
|
|
|
|
2024-09-15 10:46:07 +02:00
|
|
|
return res, nil
|
|
|
|
}
|
2024-10-21 23:14:55 +02:00
|
|
|
|
|
|
|
func (c *Client) getStationCache() *Station {
|
|
|
|
if c.stationCache != nil && time.Since(c.stationCacheTime) < cacheTimeout {
|
|
|
|
return c.stationCache
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|