Directory watcher daemon

You can use this script to watch some directories, for some specific files. If something changes the make an action... for example I reload the ZServer.

by humancoder 2 years, 3 months ago and tagged with: directory-watcher python reload zope
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env python
from __future__ import nested_scopes
import os, sys, time
import subprocess
WATCHED_EXTENSIONS = ('.py', '.zcml',)
def watch_directories (paths, func, delay=1.0):
	"""(paths:[str], func:callable, delay:float)
	Continuously monitors the paths and their subdirectories
	for changes.  If any files or directories are modified,
	the callable 'func' is called with a list of the modified paths of both
	files and directories.  'func' can return a Boolean value
	for rescanning; if it returns True, the directory tree will be
	rescanned without calling func() for any found changes.
	(This is so func() can write changes into the tree and prevent itself
	from being immediately called again.)
	"""

	# Basic principle: all_files is a dictionary mapping paths to
	# modification times.  We repeatedly crawl through the directory
	# tree rooted at 'path', doing a stat() on each file and comparing
	# the modification time.

	all_files = {}
	def f (unused, dirname, files):
		# Traversal function for directories
		for filename in files:
			path = os.path.join(dirname, filename)
			try:
				t = os.stat(path)
			except os.error:
				# If a file has been deleted between os.path.walk()
				# scanning the directory and now, we'll get an
				# os.error here.  Just ignore it -- we'll report
				# the deletion on the next pass through the main loop.
				continue			
			mtime = remaining_files.get(path)
			if mtime is not None:
				# Record this file as having been seen
				del remaining_files[path]
				# File's mtime has been changed since we last looked at it.
				if t.st_mtime > mtime:
					changed_list.append(path)
			else:
				# No recorded modification time, so it must be
				# a brand new file.
				changed_list.append(path)
			# Record current mtime of file.
			
			all_files[path] = t.st_mtime
	# Main loop
	rescan = False
	while True:
		changed_list = []
		remaining_files = all_files.copy()
		all_files = {}
		for path in paths:
			os.path.walk(path, f, None)
		removed_list = remaining_files.keys()
		if rescan:
			rescan = False
		elif changed_list or removed_list:
			rescan = func(changed_list, removed_list)
		time.sleep(delay)
if __name__ == '__main__':
	def notify (changed_files, removed_files):
		#Restart zope daemon
		files = changed_files[:]
		for file in removed_files:
			files.append(file)
		
		RELOAD = False
		for file in files:			
			for extension in WATCHED_EXTENSIONS:
				if os.path.isfile(file) and file.endswith(extension):
					print file
					RELOAD = True
					break
			if RELOAD:
				break
		if RELOAD:
			subprocess.Popen(['killall','-9','runzope'])
			subprocess.Popen(['./bin/zopectl','fg'])
	watch_directories(sys.argv[1:], notify, 1)

Currently 0 comments

To post a comment, you must login.