2 Commits d220feb4ef ... cc5dcb50ab

Author SHA1 Message Date
  Adam cc5dcb50ab start adding nl feed 2 months ago
  Adam d220feb4ef start adding nl feed 2 months ago
4 changed files with 166 additions and 20 deletions
  1. 1 1
      traffic/access.go
  2. 134 19
      traffic/nl_ovapi.go
  3. 2 0
      traffic/structs.go
  4. 29 0
      transformers/dk.go

+ 1 - 1
traffic/access.go

@@ -645,7 +645,7 @@ func EnableFeeds(cfg config.Config, traffic *Traffic) {
 
 func Initialise(sigChan chan os.Signal, doneChan chan bool, initedChan chan bool, cfg config.Config,
 	traffic *Traffic) {
-	bare.MaxMapSize(8192)
+	bare.MaxMapSize(12288)
 	alreadyInitialised := false
 	for {
 		sig := <-sigChan

+ 134 - 19
traffic/nl_ovapi.go

@@ -5,10 +5,19 @@
 package traffic
 
 import (
+	"strings"
+
+	"apiote.xyz/p/szczanieckiej/transformers"
+
+	"bufio"
+	"encoding/csv"
+	"fmt"
+	"io"
 	"net/http"
+	"os"
+	"path/filepath"
 	"time"
 
-	"apiote.xyz/p/szczanieckiej/transformers"
 	"golang.org/x/text/transform"
 )
 
@@ -50,7 +59,7 @@ func (NlOvapi) RealtimeFeeds() map[RealtimeFeedType]string {
 }
 
 func (NlOvapi) Transformer() transform.Transformer {
-	return transform.Chain(transformers.TransformerFY, transformers.TransformerNL, transformers.TransformerDE, transformers.TransformerFR)
+	return transform.Chain(transformers.TransformerFY, transformers.TransformerNL, transformers.TransformerDE, transformers.TransformerFR, transformers.TransformerDK)
 }
 
 func (NlOvapi) Name() string {
@@ -81,26 +90,132 @@ Everything that is not correct acording to the GTFS documentation is considered
 This function has access to unzipped GTFS file and can operate on files at `path/specific_file.txt`
 */
 func (NlOvapi) FeedPrepareZip(path string) error {
-	// TODO replace '›' (\u0155) with ø
-	/* TODO
-	ï 2548706,HA2700,"Rotterdam, Port Sa�dstraat",51.946745,4.566797,0,,,1,,
-	ï 2548707,HA2957,"Rotterdam, Port Sa�dstraat",51.946645,4.56661,0,,,1,,
-	ö 2548714,HA2102,"Rotterdam, Selma Lagerl�fweg",51.966129,4.550916,0,,,1,,
-	ö 2548715,HA2103,"Rotterdam, Selma Lagerl�fweg",51.966244,4.550565,0,,,1,,
-	ï 2548716,HA2401,"Rotterdam, Ca�rostraat",51.941438,4.404498,0,,,1,,
-	é 2548717,HA2473,"Vlaardingen, Verploegh Chass�plein",51.909207,4.352548,0,,,0,,
-	é 2548718,HA2496,"Vlaardingen, Verploegh Chass�plein",51.90956,4.35174,0,,,0,,
-
-
-	*/
+	// NOTE fix wrong encoded characters and add ZWNJ for Dutch diaeresises
+	stopsFile, err := os.Open(filepath.Join(path, "stops.txt"))
+	if err != nil {
+		return fmt.Errorf("while opening stops file: %w", err)
+	}
+	defer stopsFile.Close()
+	stops2File, err := os.OpenFile(filepath.Join(path, "stops2.txt"), os.O_RDWR|os.O_CREATE, 0644)
+	if err != nil {
+		return fmt.Errorf("while opening stops2 file: %w", err)
+	}
+	defer stops2File.Close()
+	r := csv.NewReader(bufio.NewReader(stopsFile))
+	w := csv.NewWriter(stops2File)
+	header, err := r.Read()
+	if err != nil {
+		return fmt.Errorf("while reading stops header: %w", err)
+	}
+	fields := map[string]int{}
+	for i, headerField := range header {
+		fields[headerField] = i
+	}
+	err = w.Write(header)
+	if err != nil {
+		return fmt.Errorf("while writing stops header: %w", err)
+	}
+	for {
+		record, err := r.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return fmt.Errorf("while reading a stop record: %w", err)
+		}
+
+		switch record[fields["stop_code"]] {
+		case "HA2700":
+			fallthrough
+		case "HA2957":
+			record[fields["stop_name"]] = "Rotterdam, Port Saïdstraat"
+		case "HA2102":
+			fallthrough
+		case "HA2103":
+			record[fields["stop_name"]] = "Rotterdam, Selma Lagerlöfweg"
+		case "HA2401":
+			record[fields["stop_name"]] = "Rotterdam, Caïrostraat"
+		case "HA2473":
+			fallthrough
+		case "HA2496":
+			record[fields["stop_name"]] = "Vlaardingen, Verploegh Chasséplein"
+		}
+
+		record[fields["stop_name"]] = strings.ReplaceAll(record[fields["stop_name"]], "›", "ø")
+		record[fields["stop_code"]] = strings.ReplaceAll(record[fields["stop_code"]], "ë", ZWNJ+"ë") // TODO also in routes
+		record[fields["stop_name"]] = strings.ReplaceAll(record[fields["stop_name"]], "ë", ZWNJ+"ë")
+		record[fields["stop_code"]] = strings.ReplaceAll(record[fields["stop_code"]], "ï", ZWNJ+"ï")
+		record[fields["stop_name"]] = strings.ReplaceAll(record[fields["stop_name"]], "ï", ZWNJ+"ï")
+		record[fields["stop_name"]] = strings.ReplaceAll(record[fields["stop_name"]], "Nös", "N"+ZWNJ+"ös")
+		// TODO … ü & ö
+
+		err = w.Write(record)
+		if err != nil {
+			return fmt.Errorf("while writing a stop record: %w", err)
+		}
+	}
+	w.Flush()
+	err = os.Remove(filepath.Join(path, "stops.txt"))
+	if err != nil {
+		return fmt.Errorf("while removing stops: %w", err)
+	}
+	err = os.Rename(filepath.Join(path, "stops2.txt"), filepath.Join(path, "stops.txt"))
+	if err != nil {
+		return fmt.Errorf("while renaming stops: %w", err)
+	}
+
+	routesFile, err := os.Open(filepath.Join(path, "routes.txt"))
+	if err != nil {
+		return fmt.Errorf("while opening routes file: %w", err)
+	}
+	defer routesFile.Close()
+	routes2File, err := os.OpenFile(filepath.Join(path, "routes2.txt"), os.O_RDWR|os.O_CREATE, 0644)
+	if err != nil {
+		return fmt.Errorf("while opening routes2 file: %w", err)
+	}
+	defer routes2File.Close()
+	r = csv.NewReader(bufio.NewReader(routesFile))
+	w = csv.NewWriter(routes2File)
+	header, err = r.Read()
+	if err != nil {
+		return fmt.Errorf("while reading routes header: %w", err)
+	}
+	fields = map[string]int{}
+	for i, headerField := range header {
+		fields[headerField] = i
+	}
+	err = w.Write(header)
+	if err != nil {
+		return fmt.Errorf("while writing routes header: %w", err)
+	}
+	for {
+		record, err := r.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			return fmt.Errorf("while reading a route record: %w", err)
+		}
+
+		record[fields["stop_code"]] = strings.ReplaceAll(record[fields["route_long_name"]], "ë", ZWNJ+"ë")
+
+		err = w.Write(record)
+		if err != nil {
+			return fmt.Errorf("while writing a route record: %w", err)
+		}
+	}
+	w.Flush()
+	err = os.Remove(filepath.Join(path, "routes.txt"))
+	if err != nil {
+		return fmt.Errorf("while removing routes: %w", err)
+	}
+	err = os.Rename(filepath.Join(path, "routes2.txt"), filepath.Join(path, "routes.txt"))
+	if err != nil {
+		return fmt.Errorf("while renaming routes: %w", err)
+	}
 	return nil
 }
 
 func (NlOvapi) QRInfo() (string, QRLocation, string) {
 	return "", QRLocationNone, ""
 }
-
-/*
-TODO(14)
-Add description and attribution to strings in `translations/messages.en.yml` and any other languages if You can.
-*/

+ 2 - 0
traffic/structs.go

@@ -20,6 +20,8 @@ const (
 	DEPARTURES_FULL
 )
 
+const ZWNJ = "\u8204"
+
 func LuaAlertToAlert(luaAlert AlertLua) (Alert, error) {
 	resultAlert := Alert{
 		TimeRanges:   make([][2]time.Time, len(luaAlert.TimeRanges)),

+ 29 - 0
transformers/dk.go

@@ -0,0 +1,29 @@
+// SPDX-FileCopyrightText: Adam Evyčędo
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+package transformers
+
+import (
+	"golang.org/x/text/transform"
+)
+
+//nolint:gochecknoglobals
+var TransformerDK transform.Transformer = Replace(func(r rune) []rune {
+	switch r {
+	case 'æ':
+		return []rune{'a', 'e'}
+	case 'Æ':
+		return []rune{'A', 'E'}
+	case 'å':
+		return []rune{'a', 'a'}
+	case 'Å':
+		return []rune{'A', 'A'}
+	case 'ø':
+		return []rune{'o', 'e'}
+	case 'Ø':
+		return []rune{'O', 'E'}
+	default:
+		return []rune{r}
+	}
+})