Created
August 6, 2011 16:01
-
-
Save zoranzaric/1129461 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/usr/bin/env python | |
""" | |
This is a simple prototype for a bup inotify command. It watches a directory | |
and backs its created, modified, or deleted content up. | |
Requirements: | |
- bup | |
Get it from http://github.com/apenwarr/bup | |
- pyinotify | |
Use a OS package or `pip install pyinotify` | |
""" | |
import pyinotify | |
import shlex | |
import subprocess | |
import os | |
from Queue import Queue | |
from time import time | |
INDEX_CMD = "bup -d %s index %s" | |
SAVE_CMD = "bup -d %s save -q -n %s %s" | |
WATCH_DIR = '/home/zz/tmp/inotify/' | |
BUP_DIR = '/home/zz/tmp/stas/.bup' | |
BACKUP_TARGET = 'inotify' | |
QUEUE_TIMEOUT = 1# seconds | |
wm = pyinotify.WatchManager() | |
mask = pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MODIFY | |
def backup(path): | |
p = subprocess.Popen(shlex.split(INDEX_CMD % (BUP_DIR, path))) | |
p.wait() | |
p = subprocess.Popen(shlex.split(SAVE_CMD % (BUP_DIR, BACKUP_TARGET, path))) | |
p.wait() | |
def WORK(timeout=1): | |
""" | |
Backup paths in queue. | |
Only use the last event for a path. If a path is created and deleted | |
immedialty it is ignored. Backup all paths in one bup call. | |
TODO the timeout should be handled differently. | |
""" | |
global last_work | |
if last_work + timeout < time(): | |
paths = dict() | |
while not q.empty(): | |
event, path = q.get() | |
if event == 'create': | |
paths[path] = 'create' | |
elif event == 'modify': | |
paths[path] = 'modify' | |
elif event == 'delete': | |
if path in paths: | |
last_action = paths[path] | |
if last_action != 'delete': | |
del(paths[path]) | |
else: | |
paths[path] = 'delete' | |
backup_paths = [] | |
for path, event in paths.iteritems(): | |
if event == 'create' or event == 'modify': | |
# TODO new directories should be added to the watchlist | |
backup_paths.append(path) | |
elif event == 'delete': | |
backup_paths.append(os.path.join(event.pathname, | |
os.path.pardir)) | |
if len(backup_paths) > 0: | |
print " ".join(backup_paths) | |
backup(" ".join(backup_paths)) | |
last_work = time() | |
class EventHandler(pyinotify.ProcessEvent): | |
def process_IN_CREATE(self, event): | |
print "Creating:", event.pathname | |
q.put(('create', event.pathname)) | |
WORK() | |
def process_IN_DELETE(self, event): | |
print "Removing:", event.pathname | |
# if a file or directory is deleted we have to index and save its parent | |
q.put(('delete', event.pathname)) | |
WORK() | |
def process_IN_MODIFY(self, event): | |
print "Modifying:", event.pathname | |
q.put(('modify', event.pathname)) | |
WORK() | |
handler = EventHandler() | |
notifier = pyinotify.Notifier(wm, handler, timeout=10) | |
wdd = wm.add_watch(WATCH_DIR, mask, rec=True) | |
backup(WATCH_DIR) | |
q = Queue() | |
last_work = 0 | |
print "Starting loop..." | |
notifier.loop() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment