Make the file watching classes re-useable

This commit is contained in:
Kovid Goyal 2015-06-09 08:32:25 +05:30
parent 532fd2a7e9
commit bd8ca5a020

View File

@ -14,14 +14,12 @@ from calibre.constants import islinux, iswindows, isosx
class NoAutoReload(EnvironmentError): class NoAutoReload(EnvironmentError):
pass pass
EXTENSIONS_TO_WATCH = frozenset('py pyj'.split())
BOUNCE_INTERVAL = 2 # seconds
def file_is_watched(fname):
return fname and fname.rpartition('.')[-1] in EXTENSIONS_TO_WATCH
class WatcherBase(object): class WatcherBase(object):
EXTENSIONS_TO_WATCH = frozenset('py pyj'.split())
BOUNCE_INTERVAL = 2 # seconds
def __init__(self, server, log): def __init__(self, server, log):
self.server, self.log = server, log self.server, self.log = server, log
fpath = os.path.abspath(__file__) fpath = os.path.abspath(__file__)
@ -31,7 +29,7 @@ class WatcherBase(object):
def handle_modified(self, modified): def handle_modified(self, modified):
if modified: if modified:
if time.time() - self.last_restart_time > BOUNCE_INTERVAL: if time.time() - self.last_restart_time > self.BOUNCE_INTERVAL:
modified = {os.path.relpath(x, self.base) if x.startswith(self.base) else x for x in modified if x} modified = {os.path.relpath(x, self.base) if x.startswith(self.base) else x for x in modified if x}
changed = os.pathsep.join(sorted(modified)) changed = os.pathsep.join(sorted(modified))
self.log('') self.log('')
@ -40,20 +38,20 @@ class WatcherBase(object):
self.server.restart() self.server.restart()
self.last_restart_time = time.time() self.last_restart_time = time.time()
def file_is_watched(self, fname):
return fname and fname.rpartition('.')[-1] in self.EXTENSIONS_TO_WATCH
if islinux: if islinux:
import select import select
from calibre.utils.inotify import INotifyTreeWatcher from calibre.utils.inotify import INotifyTreeWatcher
def ignore_event(path, name):
return not file_is_watched(name)
class Watcher(WatcherBase): class Watcher(WatcherBase):
def __init__(self, root_dirs, server, log): def __init__(self, root_dirs, server, log):
WatcherBase.__init__(self, server, log) WatcherBase.__init__(self, server, log)
self.fd_map = {} self.fd_map = {}
for d in frozenset(root_dirs): for d in frozenset(root_dirs):
w = INotifyTreeWatcher(d, ignore_event) w = INotifyTreeWatcher(d, self.ignore_event)
self.fd_map[w._inotify_fd] = w self.fd_map[w._inotify_fd] = w
def loop(self): def loop(self):
@ -65,6 +63,9 @@ if islinux:
modified |= w() modified |= w()
self.handle_modified() self.handle_modified()
def ignore_event(self, path, name):
return not self.file_is_watched(name)
elif iswindows: elif iswindows:
import win32file, win32con import win32file, win32con
from Queue import Queue from Queue import Queue
@ -104,7 +105,7 @@ elif iswindows:
None, None None, None
) )
for action, filename in results: for action, filename in results:
if file_is_watched(filename): if self.file_is_watched(filename):
self.modified_queue.put(os.path.join(self.path_to_watch, filename)) self.modified_queue.put(os.path.join(self.path_to_watch, filename))
except Exception: except Exception:
import traceback import traceback
@ -156,7 +157,7 @@ elif isosx:
name = ev.name name = ev.name
if isinstance(name, bytes): if isinstance(name, bytes):
name = name.decode('utf-8') name = name.decode('utf-8')
if file_is_watched(name): if self.file_is_watched(name):
self.handle_modified({name}) self.handle_modified({name})
else: else: