'''Update a symlink hierachy to match the tag collection values.''' import sys import os from lib.tagfiles import TagCollection from lib.relpath import relpath def create_target_links(basepath, dirpath, targets, our_files, msgs): '''Create links for targets in dirpath. Add link names to our_files.''' for target in targets: if os.path.isdir(os.path.join(basepath, target)): # Just the last part for directories tname = target.split('/')[-1] else: # Directory and filename tname = '-'.join(target.split('/')[-2:]) tyear = target.split('/')[0] linkname = tyear + '-' + tname linkpath = os.path.join(dirpath, linkname) targetpath = relpath(dirpath, os.path.join(basepath, target)) our_files.add(linkpath) if os.path.islink(linkpath) and os.readlink(linkpath) == targetpath: # Nothing to do continue # Only remove links, do not remove real files if os.path.lexists(linkpath): if os.path.islink(linkpath): os.unlink(linkpath) else: msgs.append('File already exists: ' + linkpath) continue os.symlink(targetpath, linkpath) def remove_unnecessary(linkdir, our_files, msgs): '''Remove empty directories and symlinks from file system if they are not in our_files.''' def onerror(error): '''Add notes to msgs for errors from os.walk.''' msgs.append('Directory traversal error: ' + str(error)) for dirpath, dirnames, filenames in os.walk(linkdir, False, onerror): for filename in filenames: filename = os.path.join(dirpath, filename) if filename not in our_files: if os.path.islink(filename): os.remove(filename) else: msgs.append('Unknown file: ' + filename) for dirname in dirnames: dirname = os.path.join(dirpath, dirname) for filename in our_files: if filename.startswith(dirname): break else: if os.path.islink(dirname): os.remove(dirname) # Our link elif not os.listdir(dirname): os.rmdir(dirname) # Empty dir else: msgs.append('Non-empty unnecessary directory: ' + dirname) def update_symlinks(basepath, linkdir, tagcollection, msgs): '''Remove any tags and symlinks that no-longer exist in the collection. Add any missing symlinks and tags to filesystem.''' # Check that all tags are in place our_files = set() for tag, targets in tagcollection.tags.items(): # Verify that the tag directory exists dirpath = os.path.join(linkdir, tag) our_files.add(dirpath) if not os.path.isdir(dirpath): try: os.makedirs(dirpath, 0755) except os.error, ex: msgs.append('Could not create directory ' + dirpath + ': ' + str(ex)) continue create_target_links(basepath, dirpath, targets, our_files, msgs) remove_unnecessary(linkdir, our_files, msgs) def main(path): tc = TagCollection() tc.import_recursively(path, 'Merkinnat.txt') if tc.msgs: print "Import messages (%d):" % len(tc.msgs) for msg in tc.msgs: print msg print '-' * 20 print "Symlinks were not updated." return False msgs = [] update_symlinks(path, os.path.join(path, 'Luokiteltuna'), tc, msgs) if msgs: print "Symlink creation messages (%d):" % len(msgs) for msg in msgs: print msg print '-' * 20 return False return True if __name__ == '__main__': sys.exit(int(not main(os.getcwd())))