add class Rule to configure FileManager

This commit is contained in:
2020-11-03 14:45:55 +01:00
parent 0da73e0c5b
commit 4716326410
2 changed files with 35 additions and 24 deletions

Binary file not shown.

View File

@@ -244,45 +244,56 @@ class Watch:
return pyinotify.AsyncioNotifier(wm, loop, default_proc_fun=handler) return pyinotify.AsyncioNotifier(wm, loop, default_proc_fun=handler)
class Rule:
valid_actions = ["copy", "move", "delete"]
def __init__(self, action, src_re, dst_re="", auto_create=False,
rec=False):
assert action in self.valid_actions, \
f"action: expected [{Rule.valid_actions.join(', ')}], got{action}"
self.action = action
self.src_re = re.compile(src_re)
assert isinstance(dst_re, str), \
f"dst_re: expected {type('')}, got {type(dst_re)}"
self.dst_re = dst_re
assert isinstance(auto_create, bool), \
f"auto_create: expected {type(bool)}, got {type(auto_create)}"
self.auto_create = auto_create
assert isinstance(rec, bool), \
f"rec: expected {type(bool)}, got {type(rec)}"
self.rec = rec
class FileManager: class FileManager:
def __init__(self, rules, auto_create=True, rec=False, def __init__(self, rules, logname="FileManager"):
logname="FileManager"):
self._rules = []
if not isinstance(rules, list): if not isinstance(rules, list):
rules = [rules] rules = [rules]
for rule in rules: for rule in rules:
if rule["action"] in ["copy", "move"]: assert isinstance(rule, Rule), \
self._rules.append((rule["action"], f"rules: expected {type(Rule)}, got {type(rule)}"
re.compile(rule["src_re"]),
rule["dst_re"]))
elif rule["action"] == "delete":
self._rules.append(
(rule["action"], re.compile(rule["src_re"])))
else:
raise ValueError(f"invalid action type: {rule['action']}")
self._auto_create = auto_create self._rules = rules
self._rec = rec
self._log = logging.getLogger(logname) self._log = logging.getLogger(logname)
def add_rule(self, *args, **kwargs):
self._rules.append(Rule(*args, **kwargs))
async def task(self, event, task_id): async def task(self, event, task_id):
path = event.pathname path = event.pathname
match = None match = None
for rule in self._rules: for rule in self._rules:
src_re = rule[1] match = rule.src_re.match(path)
match = src_re.match(path)
if match: if match:
break break
if match is not None: if match is not None:
action = rule[0]
try: try:
if action in ["copy", "move"]: if rule.action in ["copy", "move"]:
dst_re = rule[2] dest = src_re.sub(rule.dst_re, path)
dest = src_re.sub(dst_re, path)
dest_dir = os.path.dirname(dest) dest_dir = os.path.dirname(dest)
if not os.path.isdir(dest_dir) and self._auto_create: if not os.path.isdir(dest_dir) and rule.auto_create:
self._log.info( self._log.info(
f"{task_id}: create directory '{dest_dir}'") f"{task_id}: create directory '{dest_dir}'")
os.makedirs(dest_dir) os.makedirs(dest_dir)
@@ -301,11 +312,11 @@ class FileManager:
else: else:
os.rename(path, dest) os.rename(path, dest)
elif action == "delete": elif rule.action == "delete":
self._log.info( self._log.info(
f"{task_id}: {action} '{path}'") f"{task_id}: delete '{path}'")
if os.path.isdir(path): if os.path.isdir(path):
if self._rec: if rule.rec:
shutil.rmtree(path) shutil.rmtree(path)
else: else:
shutil.rmdir(path) shutil.rmdir(path)