#!/usr/bin/env python # -*- coding: iso-8859-1 -*- """pyinotify_rst2html: watch specific files and rebuild ReST files automatically usage: to watch specific files: pyinotify_rst2html FILE1 FILE2 FILE3 to watch an entire directory and all the *.rst files in it: pyinotify_rst2html --filespec="*.rst" DIRECTORY """ __author__ = 'Andrew Ittner' __version__ = '0.2.0' __license__ = 'Expat License (AKA MIT), http://www.fsf.org/licensing/licenses/index_html' __copyright__ = 'Copyright (C) 2007, Andrew Ittner' __lastchangeddate__ = '$Date: 2007-03-23 13:14:03 -0700 (Fri, 23 Mar 2007) $' # stdlib import os, fnmatch from optparse import OptionParser # pyinotify from pyinotify import WatchManager, Notifier, EventsCodes, ProcessEvent # docutils ReST from docutils.core import publish_file, default_description # parse options #parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0") parser = OptionParser(usage='%prog [-f] [-v] [FILE1 FILE2 | DIRECTORY]\n' + __doc__, version='%prog ' + __version__) parser.add_option("-f", "--filespec", dest="filespec", default="*", help="filespec (in fnmatch pattern) of files to parse") parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="controls verbosity") (options, args) = parser.parse_args() # prep pyinotify wm = WatchManager() mask = EventsCodes.IN_MODIFY # watched events class PTmp(ProcessEvent): def process_IN_CREATE(self, event): print "Create: %s" % os.path.join(event.path, event.name) def process_IN_DELETE(self, event): print "Remove: %s" % os.path.join(event.path, event.name) def process_IN_MODIFY(self, event): if options.verbose: print "Modify (event.path=%s, event.name=%s" % (event.path, event.name) # all IN_MODIFY events are file-related if not event.is_dir: # generate source & dest if os.path.isdir(event.path): # if event.path is dir, then user specified a directory to watch sourcepath = os.path.join(event.path, event.name) destpath = os.path.join(event.path, os.path.splitext(event.name)[0] + '.html') else: # user specified individual files to watch sourcepath = event.path destpath = os.path.splitext(sourcepath)[0] + '.html' if options.verbose: print '\tsourcepath=%s\n\tdestpath=%s' % (sourcepath, destpath) # do NOT publish if source end with .html if fnmatch.fnmatch(sourcepath, '*.html'): if options.verbose: print 'ignoring change on %s' % sourcepath else: # is file in spec? if fnmatch.fnmatch(sourcepath, options.filespec): if options.verbose: print 'parse %s to %s' % (sourcepath, destpath) publish_file(source_path=sourcepath, destination_path=destpath, writer_name='html') else: if options.verbose: print 'will NOT parse %s' % sourcepath notifier = Notifier(wm, PTmp()) if options.verbose: for path in args: print 'adding watch on %s' % path wdd = wm.add_watch(args, mask) # notify user if options.verbose: print 'Starting pyinotify_rst2html watch; Ctrl-C to quit' while True: # loop forever try: # process the queue of events as explained above notifier.process_events() if notifier.check_events(): # read notified events and enqeue them notifier.read_events() except KeyboardInterrupt: # destroy the inotify's instance on this interrupt (stop monitoring) notifier.stop() break