PyGTK / GIO: резервное копирование каталога изменений

Возьмите следующий демо-код (из ответа GIO на этот вопрос), который использует GIO FileMonitor для мониторинга каталога для изменений:

import gio def directory_changed(monitor, file1, file2, evt_type): print "Changed:", file1, file2, evt_type gfile = gio.File(".") monitor = gfile.monitor_directory(gio.FILE_MONITOR_NONE, None) monitor.connect("changed", directory_changed) import glib ml = glib.MainLoop() ml.run() 

После запуска этого кода я могу затем создать и изменить дочерние узлы и получать уведомления об изменениях. Однако это работает только для непосредственных детей (я знаю, что документы не говорят иначе). Последняя из следующих команд оболочки не приведет к уведомлению:

 touch one mkdir two touch two/three 

Есть ли простой способ сделать его рекурсивным? Я бы предпочел не вручную кодировать что-то, что ищет создание каталога, и добавляет монитор, удаляя их при удалении и т. Д.

Предназначен для расширения браузера файлов VCS, чтобы иметь возможность кэшировать статусы файлов в рабочей копии и обновлять их отдельно при изменениях. Таким образом, там может быть от десятков до тысяч (или более) каталогов для мониторинга. Я хотел бы просто найти корень рабочей копии и добавить туда монитор файлов.

Я знаю о pyinotify , но я избегаю этого, чтобы это работало в ядрах , отличных от Linux, таких как FreeBSD или … другие. Насколько мне известно, GIO FileMonitor использует inotify внизу, где это доступно, и я понимаю, что не подчеркиваю реализацию, чтобы поддерживать некоторую степень абстракции, но она предложила мне, чтобы это было возможно.

(В случае, если это имеет значение, я изначально разместил это в списке рассылки PyGTK .)

  • Домашнее задание - Прокси-сервер Python
  • Установка двух массивов равными
  • Почему это преобразование в utf8 не работает?
  • Слияние подпроцесса скрипта Python 'stdout и stderr, сохраняя их различимыми
  • Получение WM_COPYDATA в Python
  • Контуры с наложением карты на нерегулярную сетку в питоне
  • Как получить описание работы с помощью scrapy?
  • Используйте команды a.any () или a.all ()
  • 2 Solutions collect form web for “PyGTK / GIO: резервное копирование каталога изменений”

    Я не уверен, что GIO позволяет вам иметь сразу несколько мониторов, но если это не так, то вы не можете сделать что-то вроде этого:

     import gio import os def directory_changed(monitor, file1, file2, evt_type): if os.path.isdir(file2): #maybe this needs to be file1? add_monitor(file2) print "Changed:", file1, file2, evt_type def add_monitor(dir): gfile = gio.File(dir) monitor = gfile.monitor_directory(gio.FILE_MONITOR_NONE, None) monitor.connect("changed", directory_changed) add_monitor('.') import glib ml = glib.MainLoop() ml.run() 

    * Когда я не говорю о причине, есть вероятность, что это может стать ресурсоемкой, хотя с почти нулевым знанием о GIO я не мог сказать. Также вполне возможно свернуть свой собственный в Python с помощью нескольких команд ( os.listdir среди других). Это может выглядеть примерно так

     import time import os class Watcher(object): def __init__(self): self.dirs = [] self.snapshots = {} def add_dir(self, dir): self.dirs.append(dir) def check_for_changes(self, dir): snapshot = self.snapshots.get(dir) curstate = os.listdir(dir) if not snapshot: self.snapshots[dir] = curstate else: if not snapshot == curstate: print 'Changes: ', for change in set(curstate).symmetric_difference(set(snapshot)): if os.path.isdir(change): print "isdir" self.add_dir(change) print change, self.snapshots[dir] = curstate print def mainloop(self): if len(self.dirs) < 1: print "ERROR: Please add a directory with add_dir()" return while True: for dir in self.dirs: self.check_for_changes(dir) time.sleep(4) # Don't want to be a resource hog w = Watcher() w.add_dir('.') w.mainloop() 

    «Есть ли простой способ сделать его рекурсивным?»

    Я не знаю ни одного «легкого пути» для достижения этого. Базовые системы, такие как inotify на Linux или kqueue на BSD, не предоставляют возможности автоматического добавления рекурсивных часов. Я также не знаю ни одной библиотеки, которую вы хотите на вершине GIO.

    Таким образом, вам, скорее всего, придется строить это самостоятельно. Поскольку это может быть небольшим трюком в некоторых случаях (например, mkdir -p foo/bar/baz ), я бы предложил посмотреть, как pynotify реализует свою функцию auto_add (grep через источник pynotify ) и переносит это на GIO.

    Python - лучший язык программирования в мире.