Python
December 2011 28

Python на примере демона уведомления о новых коммитах Git

From Sandbox
Работая в команде я люблю быть в курсе активности участников. Поэтому было решено написать демона наблюдающего за поступлением новых коммитов в репозиторий git’а. Так как я работаю в Ubuntu, то уведомление было реализовано встроенным способом — библиотекой libnotify.
Язык — Python!

image

В статье упоминается:
1. Демон на Python;
2. Логирование на Python;
3. Хранение конфигурационных файлов программ на Python;
4. Работа с командами ОС из скриптов Python;
5. Получения списка последних изменений из git’а;
6. Стандартные всплывающие уведомления Ubuntu.

Для реализации задачи был выбран язык Python (высокоуровневый, интерпретируемый, объектно-ориентированный и расширяемый язык программирования), так как я его не знаю.
Для начала мне очень помогли два источника:
— официальная документация: http://docs.python.org/tutorial/index.html;
— цикл статей IBM на русском языке: https://www.ibm.com/developerworks/ru/library/l-python_part_1/.

Во время изучения основ, приступаем к написанию программы.

1. Демон


В сети встречается много реализаций демонов, выбрал один из готовых с положительными отзывами и привлекательным названием: http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/. У этого демона были проблемы с завершением работы командой "daemon.py stop" вот в этом месте:
except OSError, err:
    err = str(err)
    if err.find("No such process") > 0:
        if os.path.exists(self.pidfile):
            os.remove(self.pidfile)

Это как видно возникло это из-за русской локали, фраза "No such process" в моей системе возвращалась на русском языке. Простой способ исправить — удалить эту проверку:
except OSError, err:
    if os.path.exists(self.pidfile):
        os.remove(self.pidfile)


2. Ведение логов


Простейшим средством оповещение о процессе работы программы является использование функции print(). Но эта программа будет запускаться в качестве демона и не предполагает вывод информации о своем состоянии в консоль запуска. Удобным вариантом в этом случае является запись лога в файл. В Python’е есть встроенный способ логирования входящий в стандартную библиотеку — модуль logging (http://docs.python.org/library/logging.html).
Модуль имеет множество вариантов ведения лога (handlers, http://docs.python.org/library/logging.handlers.html): StreamHandler, FileHandler, WatchedFileHandler, RotatingFileHandler, TimedRotatingFileHandler, SocketHandler, DatagramHandler, SysLogHandler, NTEventLogHandler, SMTPHandler, MemoryHandler, HTTPHandler. Для контроля работы демона использовался FileHandler:
logging.basicConfig(filename = tempfile.gettempdir() + '/gitPushNotify.log',
                    level = logging.DEBUG,
                    format = '%(asctime)s %(levelname)s: %(message)s',
                    datefmt = '%Y-%m-%d %I:%M:%S')
logging.info('Daemon start')


3. Хранение конфигурации программ на Python


Для хранения конфигурации приложений используется ini файл и встроенный модуль работы с ними ConfigParser (http://docs.python.org/library/configparser.html):
config = ConfigParser.ConfigParser()
configPath = os.path.dirname(__file__) + '/config.ini'
config.read(configPath)

Получение значения параметров функциями (в данном случае получение integer значения):
timeout = config.getint('daemon', 'timeout')


4. Работа с командам ОС из скриптов Python


Для выполнения системных команд используется метод check_output() модуля subprocess (http://docs.python.org/library/subprocess.html):
sourceOutput = subprocess.check_output('cd ' + repositoryPath, shell=True)

Также можно использовать методы модуля os:
sourceOutput = os.system(commandString)

Документация рекомендует использовать subprocess.

5. Получения списка последних изменений из git’а


Для просмотра последних изменений репозитория удобно использовать команду whatchanged (http://schacon.github.com/git/git-whatchanged.html). Эта команда позволяет задавать формат выводимых сообщений лога, устанавливать количество выводимых изменений. Пример использования команды:
$ git whatchanged master -10 --date=raw --date-order --pretty=format:"%H %n%cn %n%ce %n%ct %n%s"

Аргументы по порядку:
master — ветка репозитория;
-10 — количество выводимых записей;
--date-order — сортировка по дате изменения;
--pretty=format:"..." — формат вывода.

6. Стандартные всплывающие уведомления Ubuntu


Работа со всплывающими уведомлениями в Ubuntu осуществляется через библиотеку libnotify (https://wiki.ubuntu.com/NotificationDevelopmentGuidelines). Проверить установлена ли она можно командой:
$ dpkg -l | grep libnotify-bin

Либо сразу выполнить:
$ sudo apt-get install libnotify-bin

Отобразить уведомление можно используя команду:
$ notify-send "Habr!"
$ notify-send -i notification-message-email "Title" "Message"

Флаг -i — изображение, указывается системное название или путь к любому изображению в формате svg, png или jpg.

Запуск демона


Необходимо сделать файл исполняемым:
$ chmod +x gitPushNotifyDaemon.py

Перед запуском в конфигурационном файле необходимо указать путь к репозиторию и частоту опроса:
$ vim config.ini

Запуск:
$ python gitPushNotifyDaemon.py start

Если всё прошло успешно:
Daemon starting..

Появится стартовое уведомление:

image

Теперь демона можно увидеть в списке процессов, выполнив команду:
$ ps uax | grep gitPushNotifyDaemon.py

За процессом работы демона можно наблюдать используя лог:
$ tail -f /tmp/gitPushNotify.log

Также можно отдельно запускать файл gitPushNotify.py для отладки:
$ python gitPushNotify.py


Репозиторий проекта: https://github.com/antonfisher/gitPushNotify

На этом всё. Удачного дня!

Ссылки:
1. http://docs.python.org/tutorial/index.html — официальный туториал;
2. https://www.ibm.com/developerworks/ru/library/l-python_part_1/ — цикл статей IBM;
3. http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ — реализация демона от Sander Marechal;
4. http://docs.python.org/library/logging.htmlPython, модуль Logging;
5. http://docs.python.org/library/configparser.htmlPython, модуль ConfigParser;
6. http://docs.python.org/library/subprocess.htmlPython, модуль Subprocess;
7. https://wiki.ubuntu.com/NotificationDevelopmentGuidelines — описание libnotify;
8. http://schacon.github.com/git/git-whatchanged.html описание команды git-whatchanged.
+61
21.3k 280
Comments 27