123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- // SPDX-FileCopyrightText: Adam Evyčędo
- //
- // SPDX-License-Identifier: AGPL-3.0-or-later
- package traffic
- import (
- "fmt"
- "os"
- "path/filepath"
- "git.sr.ht/~sircmpwn/go-bare"
- "notabug.org/apiote/gott"
- )
- func openTrips(context Context) (*os.File, error) {
- fileName := filepath.Join(context.DataHome, context.FeedID, string(context.Version), "trips.bare")
- return os.Open(fileName)
- }
- func GetTripsByOffset(offsets []uint, context Context, filter func(Trip) bool) (map[uint]Trip, error) {
- trips := map[uint]Trip{}
- file, err := os.Open(filepath.Join(context.DataHome, context.FeedID, string(context.Version), "trips.bare"))
- if err != nil {
- return trips, fmt.Errorf("while opening file: %w", err)
- }
- defer file.Close()
- offsetsSet := map[uint]struct{}{}
- for _, offset := range offsets {
- offsetsSet[offset] = struct{}{}
- }
- for offset := range offsetsSet {
- _, err = file.Seek(int64(offset), 0)
- if err != nil {
- return trips, fmt.Errorf("while seeking to %d: %w", offset, err)
- }
- trip := Trip{}
- err = bare.UnmarshalReader(file, &trip)
- if err != nil {
- return trips, fmt.Errorf("while unmarshalling at %d: %w", offset, err)
- }
- if filter(trip) {
- trips[offset] = trip
- }
- }
- return trips, nil
- }
- func GetTripByOffset(file *os.File, offset uint, context Context) (Trip, error) {
- result := _Result{
- file: file,
- Offset: offset,
- }
- r, e := gott.NewResult(result).
- Bind(seek).
- Bind(unmarshalTrip).
- Finish()
- if e != nil {
- return Trip{}, e
- } else {
- return r.(_Result).Trip, nil
- }
- }
- func GetTrips(ids []string, ctx Context, traffic *Traffic) (map[string]Trip, error) {
- trips := map[string]Trip{}
- file, err := openTrips(ctx)
- if err != nil {
- return trips, fmt.Errorf("while opening trips: %w", err)
- }
- defer file.Close()
- tripOffsets := map[string]struct{}{}
- for _, id := range ids {
- tripOffsets[id] = struct{}{}
- }
- tripIndex := traffic.TripIndexes[ctx.FeedID][ctx.Version]
- for _, o := range tripIndex {
- if _, ok := tripOffsets[o.Name]; ok {
- trip, err := GetTripByOffset(file, o.Offsets[0], ctx)
- if err != nil {
- return trips, fmt.Errorf("while getting trip %s: %w", o.Name, err)
- }
- trips[trip.Id] = trip
- }
- }
- return trips, nil
- }
- func GetTrip(file *os.File, id string, context Context, traffic *Traffic) (Trip, error) {
- tripIndex := traffic.TripIndexes[context.FeedID][context.Version]
- for _, o := range tripIndex {
- if o.Name == id {
- return GetTripByOffset(file, o.Offsets[0], context)
- }
- }
- return Trip{}, fmt.Errorf("trip by id %s not found", id)
- }
- func unmarshalDepartures(input ...interface{}) (interface{}, error) {
- result := input[0].(_Result)
- result.DeparturesSchedule = []Departure{}
- err := bare.UnmarshalReader(result.file, &result.DeparturesSchedule)
- result.file.Close()
- return result, err
- }
|