В первой части было показано как написать простейший враппер вокруг существующего http API ржд. В этой части продолжим и напишем действующий мониторинг с уведомлением на почту. Сайт проекта засполагается по прежнему тут и тут запасной
В первой части приложение было не threadsafe, т.е. в настройках app.yaml значилось:
threadsafe: false
исправим эту ситуацию, изменим:
def main():
application.run()
if __name__ == "__main__":
main()
на:
app = webapp2.WSGIApplication([
('/', MainPage),
], debug=False)
Есстественно пришлось также переписать немного кода, выигрыш от всего этого следующий: при threadsafe: false appengine ставит новые сессии в очередь и запускает для каждой сессии новый инстанс (с небольшим временным лагом), при включенном threadsafe подразумевается что разработчик верно реализовал многопоточную логику.
Далее нужно было решить два вопроса: почта и запуск по крону, начнем с крона: для этого нужно создать в рабочей дире файл cron.yaml и указать куда и как часто следует обращаться крон демону:
cron:
- description: mail summary job
url: /summary_mail
schedule: every 1 hours
На
/summary_mail
повесим обработчик для рассыслки на активные аккаунты, а для того чтобы нехорошие дяди не могли его дергать самостоятельно и как следствие — скушать все наши квоты и заспамить активных пользователей, нужно ограничить доступ к нему только для админов и гугл крона, добавим в app.yaml строки:
- url: /summary_mail
script: web.app
login: admin
Список админов для приложения настраивается из консоли администратора (ребята школьники хакеры, не беспокойтесь в данном приложении нет никакой админки и не нужно ее пробовать «пробивать» ибо как следовало из логов при публикации прошлого поста, таки находились специалисты..., данная консоль предоставляется средствами appengine).
Некоторое время я думал — что же делать с почтовой рассылкой, прикручивать стороннюю капчу или делать свою, в итоге пошел по простейшему пути — я использую гугл аккаунт и после прохождения гугл авторизации (есстественно все идет через редирект и никакие пароли я не храню) я получаю почтовый ящик пользователя, на который он и будет получать письма о свободных местах. Фунционал для работы с почтой простейший:
def sendMail(account, body):
mail.send_mail(sender = "rzd wrapper support <robot.sender.rzd@gmail.com>",
to = account.email(),
subject = "train report",
html = body,
body = body)
Да тело письма в текстовом представлении и html у меня счас одинаковое, но скоро я это исправлю.
Для полноты картины нужно сказать, что радиоактивные исходники по прежнему тут, конечно же я наведу там порядок со временем, так же могут наблюдаться редкие, но ошибки при работе, ибо отвечает РЖД не идеально, и я где мог подстелил соломку, но думается не везде, в целом функционал вполне рабочий, каждый может из исходников запустить свое локальное приложение и допилить его до собсвенных нужд. Крон опрашивает наличие билетов раз в час. На данный момент можно подписаться только на один поезд. В дальнейших планах прикрутить Jinja2 и сделать более приятный интерфейс, так же попробовать реализовать на APPENGINE интерфейс к open sourse морфологии и сделать что то наподобие спелл чекера. Надеюсь данный сервис будет для когото полезен.
Автор: zstan