Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Опять чинил PogodaStatusBar

Сегодня участвовал в довольно скучной видеоконференции. Моё участие там было хоть и необходимое, но небольшое. А чтобы не одуреть от безделья, пока я слушал всю эту скуку, решил чем-то занять руки. Давно хотел починить свой плагин для «Саблайма» «PogodaStatusBar», этим и занялся.

Внешний вид плагина на настоящий момент

Плагин в строке статуса показывает текущую погоду и пробки в вашем городе. Много лет данные для этого я брал с неофициального урла «Яндекса», но компания решила коммерциализировать погоду и, сколько я не искал новый способ получить её бесплатно, так и не нашёл.

Пробки, кстати, тоже перестали нормально работать. Когда-то регион определялся автоматически, но это сломали. Я чинил это через парсинг страницы погоды, но теперь и это не работает — «Яндекс» борется с автоматическими роботами. Поэтому пришлось искать другой способ.

Я перебрал несколько малоизвестных сервисов, пока, наконец, не увидел, что страница yandex.ru/tune/geo/ содержит в себе необходимый номер. Этого хватило, чтобы починить показ пробок.

С «Гисметео» пришлось повозиться. Не нашёл официальную информацию о каких-либо АПИ, которые можно вызвать без токена, но внутри погодного плагина для браузера нашёлся адрес services.gismeteo.ru/inform-service/inf_chrome/forecast. В нём есть всё что нужно — текущая температура и закодированная иконка погоды.

Определить номер города в формате «Гисметео» помогает сервис www.gismeteo.ru/rmq/search/{название}/1/, куда я подставляю название, полученное от «Яндекс.Пробок» — там он возвращается вместе с остальными данными.

Оставалось только расшифровать иконку погоды. В документации есть часть описания (остаток можно понять, скачав с «Гисметео» значки погоды), выглядит всё несложно. Например, d.r3 означает «день» (day) и «дождь максимальной интенсивности» (rain 3).

Поскольку у меня Юникод, в нём есть не все необходимые значки, я сделал вот такой объект, содержащий признаки, которые позволяют мне выбрать какую иконку показать:

_icons = {
    "🌞": {"d"}, # day
    "🌙": {"n"}, # nite
    "☁️": {"n", "c"}, # night, cloud
    "🌧": {"rs", "c", "r"}, # rain+snow, cloud, rain
    "🌤": {"d", "c"}, # day, cloud
    "🌦": {"d", "r"}, # day, rain
    "🌩️": {"c", "st"}, # #day, storm
    "⛈️": {"c", "st", "r"}, # cloud, storm, rain
    "🌨": {"c", "s"}, # cloud, storm
    "💨": {"mist"}, # mist
    "⚡️": {"st"}, # storm
}

И вот такой простой алгоритм для выбора иконки:

def _getStatus(self, coded_weather):
    codes = {x.strip("0123456789") for x in coded_weather.split(".")}

    max_icon = None
    max_score = 0

    for icon, code in self._icons.items():
        result = codes & code
        score = sum(len(x) for x in result)
        if score > max_score:
            max_icon, max_score = icon, score

    return max_icon

Идея простая — чем больше значков совпало, тем лучше; если совпал значок с более длинным названием (st, mist), считаем его более конкретным и важным.

2 комментария
Azim 2 мес

А как установить-то?

Евгений Степанищев 2 мес

Как обычно — через Sublime Package Manager.

Azim 1 мес

Я поэтому и написал коммент, что там его поиском не удаётся найти. По крайней мере для ST3 не получилось.

Евгений Степанищев 1 мес

Я ему операционные системы ограничил — только «МакОС», у меня нет возможности тестировать под другими ОС.