Source code for tagrenamer.fs.node

# -*- coding: utf-8 -*-
"""
Represent any file, directory or other reference found on the file system.
"""
import os


[docs] class Node(): """ Represent any file, directory or other reference found on the file system. Hooks: - init (obj) - remove (obj) - move (obj, dest) - shell_collect (command) """ dl = 1 # Short for debuglevel. def __init__(self, output, path, hooks={}, parent=None, dl=1): """Initialize the file-system node object.""" self.out = output self.dl = self.dl + dl self.relpath = '' self.root = '' self.type = self.__class__.__name__ self.path = os.path.abspath(path) self.base = os.path.basename(self.path) self.dryrun = False self.parent = parent self.hooks = hooks if parent is None: if os.path.isdir(self.path): self.root = self.path else: self.root = os.path.dirname(self.path) else: self.root = self.parent.root self.relpath = self.path.replace('%s/' % self.root, '') # Invoke the init hook, see main class description. self.invoke('init', self) def __str__(self): """Format our own base representation.""" if ' ' in self.base: return "'%s'" % self.base return self.base
[docs] def invoke(self, hook, *args): """Invoke the given hook when they have been registered at object construction.""" if len(self.hooks) == 0: return if hook in self.hooks: return self.hooks[hook](*args)
[docs] def shellCollect(self, command, *args): """Collect the shell equivalent of a file or directory action.""" # Stop the call if there's no registered hook for this. if 'shell_collect' not in self.hooks: return # Sub function to clean incoming argument values. def escape(string): string = string.replace('"', '\\"') string = string.replace("&", "\&") # noqa: W605 string = string.replace('\/', '|') # noqa: W605 string = string.replace('`', '\`') # noqa: W605 return string # Create a new arguments list and escape the values. newargs = [] for a in args: newargs.append(escape(a)) args = tuple(newargs) # Parse the command and call our shell_collect hook. self.invoke('shell_collect', command.format(*newargs))
[docs] def enableDryRun(self): """Enable a dry-run mode on this object so that no real will things happen.""" self.dryrun = True
[docs] def exists(self): """Determine whether the object really exists or not.""" self.out.log(str(self), '%s.exists' % self.type, self.dl) return os.path.exists(self.path)
[docs] def remove(self): """Delete the file system object from disk.""" self.out.log(str(self), '%s.remove' % self.type, self.dl) self.shellCollect('rm -v "{}"', self.path) if not self.dryrun: os.unlink(self.path) # Remove this instance from the parents list of children. if self.parent is not None: self.parent.removeChild(self) # Invoke the remove hook, see main class description. self.invoke('remove', self)
[docs] def move(self, dest, newFileName=None, onlyReferences=False): """Move the file system object onto a different location..""" self.out.log(str(self), '%s.move' % self.type, self.dl) # Thrown an exception when we're being moved to the same location: if id(self) == id(dest): raise AssertionError("Can't move '%s' to itself" % dest) # Declare the new path and physically move the object. self.oldpath = self.path if newFileName is not None: self.path = os.path.abspath('%s/%s' % (dest.path, newFileName)) else: self.path = os.path.abspath('%s/%s' % (dest.path, self.base)) if not onlyReferences: self.shellCollect('mv -v "{}" "{}"', self.oldpath, self.path) if not self.dryrun: os.rename(self.oldpath, self.path) # Log the move action for retrospection. self.out.log("src: '%s'" % self.oldpath.replace(self.root + '/', ''), '%s.move' % self.type, self.dl + 1) self.out.log("dst: '%s'" % self.path.replace(self.root + '/', ''), '%s.move' % self.type, self.dl + 1) # Unregister ourselves at our current parent and register at new parent. if self.parent: self.parent.removeChild(self) dest.addChild(self) # Re-parent ourselves and update several properties. self.parent = dest self.base = os.path.basename(self.path) self.dryrun = self.parent.dryrun self.root = self.parent.root self.relpath = self.path.replace('%s/' % self.root, '') self.dl = self.parent.dl + 1 # Invoke the move hook, see main class description. self.invoke('move', self, dest)