printrun-src/printrun/module_watcher.py

Fri, 24 Aug 2018 10:27:47 +0200

author
mdd
date
Fri, 24 Aug 2018 10:27:47 +0200
changeset 38
700241b53fe7
parent 30
9188235e3bbf
permissions
-rw-r--r--

disabled power management, since it prevents also going monitor to sleep

30
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
1 #!/usr/bin/env python
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
2 # Author: Chris Eberle <eberle1080@gmail.com>
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
3 # Watch for any changes in a module or package, and reload it automatically
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
4
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
5 import pyinotify
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
6 import imp
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
7 import os
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
8
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
9 class ModuleWatcher(pyinotify.ProcessEvent):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
10 """
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
11 Automatically reload any modules or packages as they change
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
12 """
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
13
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
14 def __init__(self):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
15 "El constructor"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
16
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
17 self.wm = pyinotify.WatchManager()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
18 self.notifier = None
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
19 self.mod_map = {}
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
20
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
21 def _watch_file(self, file_name, module):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
22 "Add a watch for a specific file, and map said file to a module name"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
23
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
24 file_name = os.path.realpath(file_name)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
25 self.mod_map[file_name] = module
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
26 self.wm.add_watch(file_name, pyinotify.EventsCodes.IN_MODIFY)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
27 print 'Watching', file_name
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
28
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
29 def watch_module(self, name):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
30 "Load a module, determine which files it uses, and watch them"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
31
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
32 if imp.is_builtin(name) != 0:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
33 # Pretty pointless to watch built-in modules
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
34 return
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
35
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
36 (fd, pathname, description) = imp.find_module(name)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
37
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
38 try:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
39 mod = imp.load_module(name, fd, pathname, description)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
40 if fd:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
41 self._watch_file(fd.name, name)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
42 else:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
43 for root, dirs, files in os.walk(pathname):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
44 for filename in files:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
45 fpath = os.path.join(root, filename)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
46 if fpath.endswith('.py'):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
47 self._watch_file(fpath, name)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
48 finally:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
49 if fd:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
50 fd.close()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
51
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
52 def start_watching(self):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
53 "Start the pyinotify watch thread"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
54
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
55 if self.notifier is None:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
56 self.notifier = pyinotify.ThreadedNotifier(self.wm, self)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
57 self.notifier.start()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
58
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
59 def stop_watching(self):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
60 "Stop the pyinotify watch thread"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
61
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
62 if self.notifier is not None:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
63 self.notifier.stop()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
64
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
65 def process_IN_MODIFY(self, event):
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
66 "A file of interest has changed"
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
67
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
68 # Is it a file I know about?
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
69 if event.path not in self.mod_map:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
70 return
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
71
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
72 # Find out which module is using that file
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
73 modname = self.mod_map[event.path]
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
74
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
75 # Reload the module
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
76 (fd, pathname, description) = imp.find_module(modname)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
77 try:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
78 print "Reloading changed file: %s" % pathname
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
79 imp.load_module(modname, fd, pathname, description)
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
80 finally:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
81 if fd:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
82 fd.close()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
83
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
84 #print 'Reload', modname
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
85
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
86 if __name__ == '__main__':
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
87 # Test everything
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
88
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
89 import sys
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
90
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
91 mw = ModuleWatcher()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
92 mw.watch_module('module1')
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
93 mw.watch_module('module2')
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
94 mw.start_watching()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
95
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
96 try:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
97 raw_input('Press ENTER to exit')
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
98 finally:
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
99 mw.stop_watching()
9188235e3bbf Added module watcher for easier development (automatic module reload)
mdd
parents:
diff changeset
100 sys.exit(0)

mercurial