package api import ( "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "strings" "unicode" "github.com/gin-gonic/gin" "golang.org/x/text/transform" "golang.org/x/text/unicode/norm" ) type IDFMStation struct { Type string `json:"type"` Id string `json:"id"` X float64 `json:"x"` Y float64 `json:"y"` Name string `json:"name"` ZipCode string `json:"zipCode"` City string `json:"city"` Elevator bool `json:"elevator"` } func (s *IDFMStation) ComputeSlug() string { isMn := func(r rune) bool { return unicode.Is(unicode.Mn, r) // Mn: nonspacing marks } t := transform.Chain(norm.NFD, transform.RemoveFunc(isMn), norm.NFC) r, _ := ioutil.ReadAll(transform.NewReader(strings.NewReader(s.Name), t)) return strings.ToLower(strings.Replace(strings.Replace(strings.Replace(string(r), " ", "+", -1), "'", "+", -1), "-", "+", -1)) } type PGStation struct { Id string `json:"id"` Name string `json:"name"` Slug string `json:"slug"` } var IDFMStations []IDFMStation func searchStation(code, station string) (string, error) { stations, err := getStations(code) if err != nil { return station, err } code = strings.TrimPrefix(code, "line:IDFM:") for _, st := range stations { if st.ComputeSlug() == station { return st.Id, nil } } return station, nil } func getStations(code string) (stations []IDFMStation, err error) { rurl, err := url.JoinPath(IDFM_BASEURL, "lines", code, "stops") if err != nil { return nil, err } requrl, err := url.Parse(rurl) if err != nil { return nil, err } reqquery := url.Values{} reqquery.Add("stopPoints", "false") reqquery.Add("routes", "false") requrl.RawQuery = reqquery.Encode() req, err := http.NewRequest("GET", requrl.String(), nil) if err != nil { return nil, err } req.Header.Add("Accept", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode >= 400 { return nil, fmt.Errorf("Line not found") } dec := json.NewDecoder(res.Body) if err = dec.Decode(&stations); err != nil { return nil, err } return } func declareStationsRoutes(router *gin.RouterGroup) { router.GET("/stations/:type/:code", func(c *gin.Context) { t := convertLineType(string(c.Param("type"))) code := convertCode(t, string(c.Param("code"))) stations, err := getStations(code) if err != nil { c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": err.Error()}) return } var pgs []PGStation for _, station := range stations { pgs = append(pgs, PGStation{ Id: station.Id, Name: station.Name, Slug: station.ComputeSlug(), }) } c.JSON(http.StatusOK, APIResult(c, map[string][]PGStation{ "stations": pgs, })) }) }