285 lines
10 KiB
Go
285 lines
10 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"strconv"
|
||
"strings"
|
||
|
||
owm "github.com/briandowns/openweathermap"
|
||
"github.com/go-redis/redis"
|
||
"github.com/yanzay/tbot/v2"
|
||
)
|
||
|
||
var opt, err = redis.ParseURL(os.Getenv("REDIS_URL"))
|
||
var client = redis.NewClient(&redis.Options{
|
||
Addr: opt.Addr,
|
||
Password: opt.Password,
|
||
DB: opt.DB,
|
||
})
|
||
|
||
type OWM struct {
|
||
City string `json:"city"`
|
||
}
|
||
|
||
func (a *application) startHandler(m *tbot.Message) {
|
||
msg := "\n*Привет!* Для начала напиши город в чат.\nДалее введи необходимую *команду*:\n" +
|
||
"Команда */today* - прогноз на сегодня.\nКоманда */week* - прогноз на 5 дней."
|
||
a.client.SendMessage(m.Chat.ID, msg, tbot.OptParseModeMarkdown)
|
||
}
|
||
|
||
// Handle the msg command here
|
||
func (a *application) msgHandler(m *tbot.Message) {
|
||
citycodes := map[string]string{
|
||
"абакан": "QYPM",
|
||
"алматы": "P8OF",
|
||
"анадырь": "SSWT",
|
||
"архангельск": "SRLE",
|
||
"астана": "QJNY",
|
||
"астрахань": "PQM0",
|
||
"ашхабад": "OCMV",
|
||
"баку": "OQM6",
|
||
"барнаул": "QWOZ",
|
||
"белгород": "QGL2",
|
||
"биробиджан": "Q5T3",
|
||
"бишкек": "P5O8",
|
||
"благовещенск": "QESN",
|
||
"брянск": "QWKV",
|
||
"вильнюс": "R4K4",
|
||
"владивосток": "P7T0",
|
||
"владикавказ": "P6LQ",
|
||
"владимир": "RDLD",
|
||
"волгоград": "Q4LP",
|
||
"вологда": "RVLC",
|
||
"воронеж": "QMLA",
|
||
"горно-алтайск": "QOP6",
|
||
"грозный": "P8LT",
|
||
"душанбе": "OFNQ",
|
||
"екатеринбург": "RHN2",
|
||
"ереван": "OPLQ",
|
||
"иваново": "RILF",
|
||
"ижевск": "RHMG",
|
||
"иркутск": "QQQP",
|
||
"йошкар-ола": "RGM0",
|
||
"казань": "RBM3",
|
||
"калининград": "R4JQ",
|
||
"калуга": "R3L1",
|
||
"кемерово": "R8P6",
|
||
"киев": "QFKK",
|
||
"киров": "RSM5",
|
||
"кишинёв": "PUKF",
|
||
"кострома": "RNLF",
|
||
"краснодар": "PIL9",
|
||
"красноярск": "RCPR",
|
||
"курган": "R9NG",
|
||
"курск": "QML1",
|
||
"кызыл": "QMPV",
|
||
"липецк": "QSLB",
|
||
"магадан": "RXUK",
|
||
"майкоп": "PGLC",
|
||
"махачкала": "P6LY",
|
||
"минеральныеводы": "PDLL",
|
||
"минск": "R0KB",
|
||
"москва": "RAL5",
|
||
"мурманск": "TIKR",
|
||
"набережные челны": "RAMD",
|
||
"назрань": "P7LQ",
|
||
"нальчик": "P9LN",
|
||
"нижний новгород": "RELO",
|
||
"новгород": "RRKM",
|
||
"новосибирск": "R6OX",
|
||
"омск": "R6O4",
|
||
"оренбург": "QNML",
|
||
"орёл": "QUL0",
|
||
"пенза": "QVLR",
|
||
"пермь": "ROMP",
|
||
"петрозаводск": "SBKV",
|
||
"петропавловск-камчатский": "QUV8",
|
||
"псков": "RNKD",
|
||
"рига": "RIK0",
|
||
"ростов-на-дону": "PVLB",
|
||
"рязань": "R4LB",
|
||
"салехард": "T3NK",
|
||
"самара": "QVM6",
|
||
"санкт-петербург": "S0KJ",
|
||
"саранск": "R1LS",
|
||
"саратов": "QLLU",
|
||
"симферополь": "PIKU",
|
||
"смоленск": "R5KO",
|
||
"сочи": "PALB",
|
||
"ставрополь": "PILI",
|
||
"станциявосток": "53QX",
|
||
"станциямирный": "73PR",
|
||
"сыктывкар": "SAM8",
|
||
"таллин": "RXK2",
|
||
"тамбов": "QSLG",
|
||
"ташкент": "OWNS",
|
||
"тбилиси": "OYLQ",
|
||
"тверь": "REL0",
|
||
"тольятти": "QXM4",
|
||
"томск": "RFP3",
|
||
"тула": "R1L5",
|
||
"тюмень": "RJNH",
|
||
"улан-удэ": "QNQZ",
|
||
"ульяновск": "R2M1",
|
||
"уфа": "R4MO",
|
||
"хабаровск": "Q3T9",
|
||
"ханты-мансийск": "S6NR",
|
||
"чебоксары": "RDLY",
|
||
"челябинск": "R7N4",
|
||
"череповец": "RVL6",
|
||
"черкесск": "PDLI",
|
||
"чита": "QORH",
|
||
"элиста": "PQLP",
|
||
"южно-сахалинск": "PUTW",
|
||
"якутск": "SCST",
|
||
"ярославль": "RMLC"}
|
||
a.client.SendChatAction(m.Chat.ID, tbot.ActionTyping)
|
||
msg, datecheck, cityname, desc, url, urldate := "", 0, "", "", "", ""
|
||
if m.Text == "/week" || m.Text == "/today" {
|
||
city, err := client.Get(m.Chat.ID).Result()
|
||
if err == redis.Nil {
|
||
msg = "Сначала выбери город!\nКоманда /start в помощь."
|
||
} else {
|
||
w, err := owm.NewForecast("5", "C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
city = strings.TrimLeft(city, `{"city":"`)
|
||
city = strings.TrimRight(city, `"}`)
|
||
w.DailyByName(city, 0)
|
||
if val, ok := w.ForecastWeatherJson.(*owm.Forecast5WeatherData); ok {
|
||
if len(val.List) != 0 {
|
||
if m.Text == "/week" {
|
||
cityname = val.City.Country + " " + val.City.Name + " Прогноз на неделю"
|
||
} else {
|
||
cityname = val.City.Country + " " + val.City.Name + " Прогноз на сегодня"
|
||
}
|
||
cst := strings.Split(fmt.Sprintf("%s", val.List[0]), " ")
|
||
cdt := strings.Split(cst[len(cst)-4], "-")
|
||
cdate := fmt.Sprintf("%s-%s-%s", cdt[2], cdt[1], cdt[0])
|
||
urldate = fmt.Sprintf("%s%s%s", cdt[0], cdt[1], cdt[2])
|
||
for i := 0; i < len(val.List)-1; i++ {
|
||
fl := strings.Split(fmt.Sprintf("%.2f", val.List[i:(i+1)]), " ")
|
||
st := strings.Split(fmt.Sprintf("%s", val.List[i:(i+1)]), " ")
|
||
dt := strings.Split(st[len(st)-4], "-")
|
||
date := fmt.Sprintf("%s-%s-%s", dt[2], dt[1], dt[0])
|
||
desc = strings.Title(strings.ToLower(st[11]))
|
||
if len(st) == 26 {
|
||
desc = desc + " " + st[12] + " " + st[13]
|
||
}
|
||
if len(st) == 25 {
|
||
desc = desc + " " + st[12]
|
||
}
|
||
if m.Text == "/week" && date != cdate {
|
||
if ((st[len(st)-3] == "09:00:00" || st[len(st)-3] == "15:00:00") && datecheck < 3) ||
|
||
(st[len(st)-3] == "15:00:00" && datecheck == 3)||
|
||
(st[len(st)-3] == "12:00:00" && datecheck == 10){
|
||
if st[len(st)-3] == "09:00:00" || datecheck == 0 || datecheck == 10 {
|
||
datecheck++
|
||
msg = msg + "\n\n> Прогноз на " + date
|
||
}
|
||
if st[len(st)-3] == "15:00:00" && datecheck == 3 {
|
||
datecheck = 10
|
||
}
|
||
msg = msg + fmt.Sprintf("\n\n%s - %s\nТемпература: %s°\nОщущается: %s°\nВетер: %s м/c\n%s.",
|
||
st[len(st)-3], fadvice(fl[4]), strings.TrimLeft(fl[1], "{"), fl[4],
|
||
strings.TrimLeft(fl[14], "{"), desc)
|
||
}
|
||
} else if m.Text == "/today" && date == cdate {
|
||
msg = msg + fmt.Sprintf("\n\n%s - %s\nТемпература: %s°\nОщущается: %s°\nВетер: %s м/c\n%s.",
|
||
st[len(st)-3], fadvice(fl[4]), strings.TrimLeft(fl[1], "{"), fl[4],
|
||
strings.TrimLeft(fl[14], "{"), desc)
|
||
}
|
||
}
|
||
if m.Text == "/today" {
|
||
w, err := owm.NewCurrent("C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
w.CurrentByName(city)
|
||
arr := strings.Split(fmt.Sprintf("", w.Weather), " ")
|
||
for i := 3; i < len(arr)-1; i++ {
|
||
if i == 3 {
|
||
desc = strings.Title(strings.ToLower(arr[i]))
|
||
} else {
|
||
desc = desc + " " + arr[i]
|
||
}
|
||
}
|
||
msg = fmt.Sprintf("%s\n\nСейчас - %s\nТемпература: %.2f°\nОщущается как: %.2f°\nСкорость ветра: %.2f м/c\n%s.",
|
||
cityname, fadvice(fmt.Sprintf("%.2f", w.Main.FeelsLike)), w.Main.Temp, w.Main.FeelsLike, w.Wind.Speed, desc) + msg
|
||
if citycodes[strings.ToLower(city)] != "" {
|
||
urldate = citycodes[strings.ToLower(city)] + "_" + urldate
|
||
}
|
||
url = "https://tesis.lebedev.ru/upload_test/files/kp_" + urldate + ".png?bg=1"
|
||
} else {
|
||
msg = cityname + msg
|
||
url = "https://tesis.lebedev.ru/upload_test/files/fc_" + urldate + ".png?bg=1"
|
||
}
|
||
}
|
||
} else {
|
||
msg = fmt.Sprintf("%v", len(val.List))
|
||
}
|
||
}
|
||
} else {
|
||
m.Text = strings.TrimRight(m.Text, " .!")
|
||
w, err := owm.NewCurrent("C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output
|
||
if err != nil {
|
||
log.Fatalln(err)
|
||
}
|
||
w.CurrentByName(m.Text)
|
||
if w.Cod != 200 {
|
||
msg = "Город не найден!"
|
||
} else {
|
||
json, err := json.Marshal(OWM{City: m.Text})
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
}
|
||
err = client.Set(m.Chat.ID, json, 0).Err()
|
||
if err != nil {
|
||
fmt.Println(err)
|
||
}
|
||
msg = "Город изменён - " + w.Name + " " + w.Sys.Country + "."
|
||
}
|
||
}
|
||
if url == "" {
|
||
a.client.SendMessage(m.Chat.ID, msg, tbot.OptParseModeMarkdown)
|
||
} else {
|
||
a.client.SendPhoto(m.Chat.ID, url, tbot.OptCaption(msg))
|
||
}
|
||
}
|
||
|
||
func fadvice(stemp string) (advice string) {
|
||
if temp, err := strconv.ParseFloat(stemp, 32); err == nil {
|
||
switch {
|
||
case temp <= -50.00:
|
||
advice = "Сиди дома"
|
||
case temp <= -40.00:
|
||
advice = "Одежда для высотных восхождений"
|
||
case temp <= -30.00:
|
||
advice = "Термобельё + свитер + пуховик + шарф + перчатки"
|
||
case temp <= -20.00:
|
||
advice = "Термобельё + лонгслив + пуховик"
|
||
case temp <= -10.00:
|
||
advice = "Лёгкая куртка + свитер"
|
||
case temp <= 00.00:
|
||
advice = "Лонгслив + лёгкая куртка"
|
||
case temp >= 50.00:
|
||
advice = "Сиди дома"
|
||
case temp >= 40.00:
|
||
advice = "Одежда не нужна"
|
||
case temp >= 30.00:
|
||
advice = "Шорты + футболка"
|
||
case temp >= 20.00:
|
||
advice = "Лонгслив"
|
||
case temp >= 10.00:
|
||
advice = "Свитер"
|
||
case temp >= 00.00:
|
||
advice = "Лонгслив + ветровка"
|
||
}
|
||
}
|
||
return
|
||
}
|