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

В статье упоминается:
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/.
Во время изучения основ, приступаем к написанию программы.
В сети встречается много реализаций демонов, выбрал один из готовых с положительными отзывами и привлекательным названием: http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/. У этого демона были проблемы с завершением работы командой "daemon.py stop" вот в этом месте:
Это как видно возникло это из-за русской локали, фраза "No such process" в моей системе возвращалась на русском языке. Простой способ исправить — удалить эту проверку:
Простейшим средством оповещение о процессе работы программы является использование функции 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:
Для хранения конфигурации приложений используется ini файл и встроенный модуль работы с ними ConfigParser (http://docs.python.org/library/configparser.html):
Получение значения параметров функциями (в данном случае получение integer значения):
Для выполнения системных команд используется метод check_output() модуля subprocess (http://docs.python.org/library/subprocess.html):
Также можно использовать методы модуля os:
Документация рекомендует использовать subprocess.
Для просмотра последних изменений репозитория удобно использовать команду whatchanged (http://schacon.github.com/git/git-whatchanged.html). Эта команда позволяет задавать формат выводимых сообщений лога, устанавливать количество выводимых изменений. Пример использования команды:
Аргументы по порядку:
master — ветка репозитория;
-10 — количество выводимых записей;
--date-order — сортировка по дате изменения;
--pretty=format:"..." — формат вывода.
Работа со всплывающими уведомлениями в Ubuntu осуществляется через библиотеку libnotify (https://wiki.ubuntu.com/NotificationDevelopmentGuidelines). Проверить установлена ли она можно командой:
Либо сразу выполнить:
Отобразить уведомление можно используя команду:
Флаг -i — изображение, указывается системное название или путь к любому изображению в формате svg, png или jpg.
Необходимо сделать файл исполняемым:
Перед запуском в конфигурационном файле необходимо указать путь к репозиторию и частоту опроса:
Запуск:
Если всё прошло успешно:
Появится стартовое уведомление:

Теперь демона можно увидеть в списке процессов, выполнив команду:
За процессом работы демона можно наблюдать используя лог:
Также можно отдельно запускать файл 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.html — Python, модуль Logging;
5. http://docs.python.org/library/configparser.html — Python, модуль ConfigParser;
6. http://docs.python.org/library/subprocess.html — Python, модуль Subprocess;
7. https://wiki.ubuntu.com/NotificationDevelopmentGuidelines — описание libnotify;
8. http://schacon.github.com/git/git-whatchanged.html описание команды git-whatchanged.
Язык — Python!

В статье упоминается:
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..
Появится стартовое уведомление:

Теперь демона можно увидеть в списке процессов, выполнив команду:
$ 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.html — Python, модуль Logging;
5. http://docs.python.org/library/configparser.html — Python, модуль ConfigParser;
6. http://docs.python.org/library/subprocess.html — Python, модуль Subprocess;
7. https://wiki.ubuntu.com/NotificationDevelopmentGuidelines — описание libnotify;
8. http://schacon.github.com/git/git-whatchanged.html описание команды git-whatchanged.