add the Command operator

cleaner Operator API
This commit is contained in:
Johann Dreo 2017-12-03 15:40:12 +01:00
commit e0dfdbc60b

View file

@ -7,6 +7,7 @@ import glob
import shutil import shutil
import logging import logging
import datetime import datetime
import subprocess
from watchdog.observers import Observer from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler from watchdog.events import LoggingEventHandler
@ -75,20 +76,37 @@ class Flick:
class Operator: class Operator:
"""Interface example for an Operator (but can actually be any callable with the same signature).""" """Interface example for an Operator (but can actually be any callable with the same signature)."""
def __call__(self, filename, event): def __call__(self, target, flickname):
raise NotImplemented raise NotImplemented
class Command(Operator):
"""Run a user-defined command.
Takes the target and the flick as argument.
The command should be a python 3 format string.
For example: 'cp {target} {flick}'
You can omit one of the named arguments.
For example: 'touch {flick}'"""
def __init__(self, command):
self.cmd = command
def __call__(self, target, flickname):
cmd = self.cmd.format(target=target,flick=flickname)
logging.info("Run command: %s", cmd )
# Subprocess want a list of cmd and arguments.
subprocess.run(cmd.split())
class Save(Operator): class Save(Operator):
"""Make a copy of the target file.""" """Make a copy of the target file.
def __call__(self, filename, event): Takes care to create a missing directory if necessary."""
logging.info("Copy %s as %s", event.src_path, filename) def __call__(self, target, flickname):
logging.info("Copy %s as %s", target, flickname)
try: try:
shutil.copy(event.src_path, filename) shutil.copy(target, flickname)
except FileNotFoundError: except FileNotFoundError:
logging.warning('WARNING create missing directory: %s',os.path.dirname(filename)) logging.warning('WARNING create missing directory: %s',os.path.dirname(flickname))
os.mkdir(os.path.dirname(filename)) os.mkdir(os.path.dirname(flickname))
shutil.copy(event.src_path, filename) shutil.copy(target, flickname)
#FIXME more error handling? #FIXME more error handling?
except: except:
logging.error("ERROR while copying file: %s", sys.exc_info()[0]) logging.error("ERROR while copying file: %s", sys.exc_info()[0])
@ -113,15 +131,16 @@ class Handler(FileSystemEventHandler):
# so we filter it in this event handler. # so we filter it in this event handler.
if (not event.is_directory) and os.path.abspath(event.src_path) == os.path.abspath(self.target): if (not event.is_directory) and os.path.abspath(event.src_path) == os.path.abspath(self.target):
logging.debug("Handle event") logging.debug("Handle event")
filename = self.flick.next() flickname = self.flick.next()
logging.debug("New flick for %s: %s", event.src_path, filename) logging.debug("New flick for %s: %s", event.src_path, flickname)
for op in self.ops: for op in self.ops:
logging.debug("Calling %s", op) logging.debug("Calling %s", op)
op(filename,event) op(event.src_path, flickname)
def flicksave(target, operators=None, save_dir=".", delay=10, stamp_sep='_', date_template="%Y-%m-%dT%H:%M:%S"): def flicksave(target, operators=None, save_dir=".", delay=10, stamp_sep='_', date_template="%Y-%m-%dT%H:%M:%S"):
"""Start the watch thread."""
# Handle files specified without a directory. # Handle files specified without a directory.
root = os.path.dirname(target) root = os.path.dirname(target)
if not root: if not root:
@ -179,6 +198,8 @@ if __name__=="__main__":
logging.basicConfig(level=log_as[asked.verbose], format='%(asctime)s -- %(message)s', datefmt=asked.template) logging.basicConfig(level=log_as[asked.verbose], format='%(asctime)s -- %(message)s', datefmt=asked.template)
# Start it. operators = [Command("cp {target} {flick}"),Command("touch {flick}")]
flicksave(asked.target, None, asked.directory, asked.delay, asked.separator, asked.template)
# Start it.
flicksave(asked.target, operators, asked.directory, asked.delay, asked.separator, asked.template)