package main import ( "encoding/json" "fmt" "log" "net/http" "net/url" "regexp" "strconv" "strings" "github.com/hamcha/tg" ) const viaggiurl = "http://free.rome2rio.com/api/1.2/json/Search?key=X5JMLHNc&languageCode=IT¤cyCode=EUR" var reg *regexp.Regexp func viaggi_init() { reg = regexp.MustCompile("([^-]+) -> (.+)") } func viaggi_message(broker *tg.Broker, update tg.APIMessage) { if isCommand(update, "viaggi") { usage := func() { broker.SendTextMessage(update.Chat, "Formato: /viaggi <PARTENZA> -> <DESTINAZIONE>", &update.MessageID) } parts := strings.SplitN(*(update.Text), " ", 2) if len(parts) < 2 { usage() return } text := parts[1] msgs := reg.FindStringSubmatch(text) if len(msgs) <= 2 { usage() return } msgs[1] = strings.Replace(msgs[1], ",", "", -1) msgs[1] = strings.Replace(msgs[1], " ", "-", -1) msgs[2] = strings.Replace(msgs[2], ",", "", -1) msgs[2] = strings.Replace(msgs[2], " ", "-", -1) out, err := viaggiAPI(msgs[1], msgs[2]) if err != nil { log.Println("[viaggi] " + err.Error()) broker.SendTextMessage(update.Chat, "ERRORE! @hamcha controlla la console!", &update.MessageID) return } broker.SendTextMessage(update.Chat, out, &update.MessageID) } } func parseData(route Romeroute) string { // Get time minutes := int(route.Duration) hours := minutes / 60 minutes -= hours * 60 days := hours / 24 hours -= days * 24 timestamp := "" if days > 0 { timestamp += strconv.Itoa(days) + "d " } if hours > 0 { timestamp += strconv.Itoa(hours) + "h " } if minutes > 0 { timestamp += strconv.Itoa(minutes) + "m" } return strconv.Itoa(int(route.IndicativePrice.Price)) + " " + route.IndicativePrice.Currency + " - " + strconv.Itoa(int(route.Distance)) + " Km - " + timestamp } type Romeplace struct { Name string } type Romeprice struct { Price float64 Currency string } type Romeroute struct { Name string Distance float64 Duration float64 IndicativePrice Romeprice } type Romejson struct { Places []Romeplace Routes []Romeroute } func viaggiAPI(from string, to string) (string, error) { src := url.QueryEscape(from) dst := url.QueryEscape(to) url := viaggiurl + "&oName=" + src + "&dName=" + dst resp, err := http.Get(url) if err != nil { return "", fmt.Errorf("GET error: %s", err.Error()) } defer resp.Body.Close() var outjson Romejson err = json.NewDecoder(resp.Body).Decode(&outjson) if err != nil { return "Hm, Rome2rio non ha trovato nulla, mi spiace :(\nForse non hai scritto bene uno dei due posti?", nil } var moreeco Romeroute var lesstim Romeroute if len(outjson.Routes) < 1 { // Should never happen return "", fmt.Errorf("No routes found (??)") } // Calculate cheapest and fastest moreeco = outjson.Routes[0] lesstim = outjson.Routes[0] for _, v := range outjson.Routes { if v.IndicativePrice.Price < moreeco.IndicativePrice.Price { moreeco = v } if v.Duration < lesstim.Duration { lesstim = v } } return fmt.Sprintf("Viaggio da %s a %s\n\nPiu economico: %s (%s)\nPiu veloce: %s (%s)\n\nMaggiori informazioni", outjson.Places[0].Name, outjson.Places[1].Name, moreeco.Name, parseData(moreeco), lesstim.Name, parseData(lesstim), src, dst), nil }