Вторым проектом, за который я взялся после RSS-транспорта, стал транспорт для получения данных о погоде с сайта https://gismeteo.ru. Один из немногих таких транспортов был найден на сервере jabbercity.ru, и пока собирал архив jabber-проектов, получил в том числе копию этого транспорта. Из пожеланий (если вдруг буду им заниматься) были реализация поиска и vCard’ов. Честно говоря, на момент получения архива я был весьма далек от того, чтобы что-то такое делать, однако после работы над RSS-транспортом набрался немного опыта и подумал – а почему бы и нет?
Транспорт был сделан на базе кода почтового транспорта и погодного плагина, написанного для бота Talisman. Во всех местах были кучи неиспользуемого кода, но основную задачу транспорт все же выполнял – при добавлении ботов вида “код@сервер” (код соответствия городу надо было самостоятельно посмотреть в базе либо на сайте gismeteo.ru) в ответ на любое сообщение бот присылал погоду (и отображал ее в своем статусе) – на этом, в общем-то, все.
Чуть почистил код от явно неиспользуемого; начал добавлять знакомые вещи – использовал те же методы работы с конфиг-файлом, чтобы оформить чтение переменных из него и убрать ошметки старой системы, в которой использовался ряд дополнительных файлов. Транспорт использовал XMPPPY в качестве библиотеки для работы с XMPP; готовых примеров нужных функций под руками не было, поэтому начал с малого – поделал обвязку для реализации мелких функций, вроде ответа на запрос версии или аптайма. Более-менее получилось – хотя не все реализовал, как выяснилось позже, плюс случайно потерял немного кода :).
Перешел к реализации поиска; тут было чуть сложнее: диалог состоит из 4 сообщений определенной структуры. Реализовал запрос данных и передачу поля запроса в код, пришло время работать с базой. В качестве базы решил использовать sqlite – тут не требовалась какая-то сложная логика и, фактически, нужен был просто удобный интерфейс для чтения из файла. Полезные ссылки на тему sqlite, использованные в работе:
- https://docs.python.org/3/library/sqlite3.html
- https://stackoverflow.com/questions/973541/how-to-set-sqlite3-to-be-case-insensitive-when-string-comparing
- https://habr.com/ru/post/321510/
Пришло время определяться с тем, какие данные будут браться из базы – т.е., нужен был ее контент. Текстовый файлик, шедший в комплекте, был весьма скромным в этом плане и хотелось чего-то большего. Большее нашел на flymeteo.org – тут уже была и страна, и координаты, и высота над уровнем моря. Причем, старая база и эта не всегда перекрывали друг друга, а взаимно дополняли. Захотелось собрать максимально большую базу со всеми подробностями. Создал в том числе тред на ЛОРе, но с него толку не было. Попутно попался сайт http://www.meteonova.ru – как альтернатива gismeteo. Причем, для каждой погодной станции была RSS-лента, а коды станций совпадали с той базой, что я искал. Обратился к админу сайта, чтобы поделился базой, но ответа так и не получил. В итоге просто сдампил весь сайт перебором по индексам за пару дней, получив около 2 ГБ данных и примерно 38000 полезных страниц. В дальнейшем написал несколько скриптов для их парсинга. Позже добавил данные с flymeteo – данные высоты для совпадающих индексов + влил в базу уникальные записи. На момент релиза транспорта эти данные и используются в качестве базы, хотя, конечно, еще есть над чем поработать: есть уникальные записи, которые были в других базах, но которые пока не добавил. Ну и был ряд записей с одинаковыми индексами, но разным описанием – что делать с ними пока не знаю.
Так или иначе, с полями в таблице определился, схему для базы создал, залил данные, сформировал саму базу и сделал запрос на выборку данных. Все работало, со стороны кода начал получать результаты по запросу данных из Jabber-клиента. Начал оформлять последний блок для формирования таблицы с результатами поиска, но тут возникла задержка. В итоге, как выяснилось, в 3 из 4 запросов должно присутствовать скрытое значение FORM_TYPE и разбирательство с тем, как именно должен выглядеть код, чтобы получить нужный XML, заняло довольно много времени. Так или иначе, все же разобрался – не в последнюю очередь помог код из IRC-транспорта, Gajim, а также некоторых других найденных в сети примеров. Таблица результатов поиска начала перерисовываться с нужными полями, однако после этого выяснилось, что метод, через который раньше удавалось получать данные для запроса в базу, перестал работать – хотя согласно XML-консоли, весь XML был правильно составлен. В итоге разобрался, а в процессе начал лучше понимать, как работать с XML-данными.
Оставался последний шаг – по полученным с базы данным вырисовать child’ы для отображения в таблице. Пошел смотреть детали того, как оно сделано в RSS-транспорте и в процессе этого удалось выкинуть из него лишний цикл и пару массивов. Аналогичным образом сделал и в погодном транспорте. Работа над функцией поиска была завершена :).
После всего этого работа с vCard пошла вообще легко. Сделал vCard как для самого транспорта, так и для создаваемых ботов. Конечно, можно было бы чуть расписать код и не отрисовывать, например, скобки, когда в выборке из базы поле содержит пустое значение. Но это минимально портит вид, да и хочется двигаться к противоположному варианту – максимально заполнить базу данными. Но это как-нибудь попозже.
На той же волне реализовал поддержку и остальных namespace’ов, которые только можно было сделать – ping’и и время. Тогда-то и обнаружилось, что я случайно удалил кусочек кода, ответственного за запрос версии.
Поделал косметические изменения, сделал файлы README, CHANGELOG и gismjwt.service – на этом работа, в общем-то, была закончена.
Решил еще глянуть, что там с xmpppy. В последние годы ее пытаются поддерживать в актуальном состоянии, переписывают на Python3, но уже другие люди. Попытка использовать последнюю версию была неудачной. В итоге, после ряда проб оказалось, что вполне можно пользоваться только версией до попыток переделки на Python3, дальше что-то сломали. Транспорт вроде запускается, но вылетает на любом действии. Кроме того, как выяснилось, версия библиотеки, шедшая в комплекте с транспортом, была с некоторыми правками: там были добавлены штатно отсутствующие namespace’ы NS_PING и NS_URN_TIME – причем, их там нет до сих пор. Пришлось поправить код транспорта, чтобы использовалось напрямую значение этих namespace’ов, без обращения к библиотеке.
А получится ли использовать в дальнейшем последнюю версию – да и в целом, переделать транспорт под использование Python3 – пока не знаю. В целом, не вижу никаких ограничений. Библиотеку пилят, сделать правки в коде транспорта тоже несложно. Но это попозже, на сейчас и так все работает.
В планах на ближайшее будущее – сделать возможность работы с данными с meteonova – чего зря возможности пропадать? Будет или форк транспорта, либо просто расширю список функций для обработки данных с какой-то возможностью выбора источника данных. С учетом того, что на meteonova используется RSS – как раз есть примеры работы с лентами из RSS-транспорта.
Одна мысль про “Jabber-проекты: работа над погодным транспортом”