idfm-api/api/lines.go

185 lines
4.4 KiB
Go

package api
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"sort"
"strings"
"time"
"github.com/gin-gonic/gin"
)
type IDFMLine struct {
DatasetID string `json:"datasetid"`
RecordIDs string `json:"recordid"`
Fields struct {
IdLine string `json:"id_line"`
Name string `json:"name_line"`
ShortName string `json:"shortname_line"`
TransportMode string `json:"transportmode"`
TransportSubmode string `json:"transportsubmode"`
Type string `json:"type"`
OperatorRef string `json:"operatorref"`
AdditionalOperators string `json:"additionaloperators,omitempty"`
OperatorName string `json:"operatorname"`
NetworkName string `json:"networkname,omitempty"`
WebColor string `json:"colourweb_hexa"`
PrintColor string `json:"colourprint_cmjn"`
WebTextColor string `json:"textcolourweb_hexa"`
TextPrintColor string `json:"textcolourprint_hexa"`
Accessibility string `json:"accessibility"`
AudibleSignAvailable string `json:"audiblesigns_available"`
VisualSignAvailable string `json:"visualsigns_available"`
NoticeTitle string `json:"notice_title"`
NoticeText string `json:"notice_text"`
Status string `json:"status"`
ShortNameGroup string `json:"shortname_groupoflines"`
IdGroup string `json:"id_groupoflines"`
ExternalCode string `json:"externalcode_line"`
} `json:"fields"`
RecordTimestamp time.Time `json:"record_timestamp"`
}
type PGLine struct {
Code string `json:"code"`
Name string `json:"name"`
Directions string `json:"directions"`
Id string `json:"id"`
}
type ByName []PGLine
func (s ByName) Len() int {
return len(s)
}
func (s ByName) Less(i, j int) bool {
return strings.Compare(s[i].Id, s[j].Id) <= 0
}
func (s ByName) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
var IDFMLines []IDFMLine
func init() {
fd, err := os.Open("referentiel-des-lignes.json")
if err != nil {
log.Fatal("Unable to open `referentiel-des-lignes.json`:", err.Error())
}
defer fd.Close()
dec := json.NewDecoder(fd)
if err = dec.Decode(&IDFMLines); err != nil {
log.Fatal("Unable to decode `referentiel-des-lignes.json`:", err.Error())
}
}
func convertLineType(old string) string {
switch old {
case "buses":
return "bus"
case "metros":
return "metro"
case "noctiliens":
return "noctilien"
case "rers":
return "rail"
case "tramways":
return "tram"
default:
return old
}
}
func convertCode(t, code string) string {
if !strings.HasPrefix(code, "line:IDFM:") {
if t == "tram" && !strings.HasPrefix(code, "T") {
code = "T" + code
}
if t == "noctilien" && !strings.HasPrefix(code, "N") {
code = "N" + code
}
if len(code) != 6 || !strings.HasPrefix(code, "C") {
code = searchLine(t, code)
}
code = "line:IDFM:" + code
}
return code
}
func searchLine(t, code string) string {
for _, line := range IDFMLines {
if line.Fields.ShortName == code && (line.Fields.TransportMode == t || strings.ToLower(line.Fields.NetworkName) == t) {
return line.Fields.IdLine
}
}
return code
}
func declareLinesRoutes(router *gin.RouterGroup) {
router.GET("/lines", func(c *gin.Context) {
var modes []string
for _, line := range IDFMLines {
mode := line.Fields.TransportMode
found := false
for _, m := range modes {
if mode == m {
found = true
break
}
}
if !found {
modes = append(modes, mode)
}
}
c.JSON(http.StatusOK, APIResult(c, modes))
})
router.GET("/lines/:type", func(c *gin.Context) {
t := convertLineType(string(c.Param("type")))
var lines []PGLine
for _, line := range IDFMLines {
if line.Fields.TransportMode == t || strings.ToLower(line.Fields.NetworkName) == t {
name := line.Fields.Name
if line.Fields.ShortNameGroup != "" {
if strings.Contains(line.Fields.ShortNameGroup, name) {
name = line.Fields.ShortNameGroup
} else if name == line.Fields.ShortName {
name = fmt.Sprintf("%s - %s", line.Fields.Name, line.Fields.ShortNameGroup)
}
}
pgline := PGLine{
Code: line.Fields.ShortName,
Name: name,
Directions: "",
Id: fmt.Sprintf("STIF:Line::%s:", line.Fields.IdLine),
}
lines = append(lines, pgline)
}
}
sort.Sort(ByName(lines))
c.JSON(http.StatusOK, APIResult(c, map[string][]PGLine{
string(c.Param("type")): lines,
}))
})
}