Fri, 24 Aug 2018 10:27:47 +0200
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) |