Source code for mache.permissions

import grp
import os
import stat

import progressbar


[docs] def update_permissions(base_paths, group, show_progress=True, # noqa: C901 group_writable=False, other_readable=True): """ Update the group that a directory belongs to along with the "group" and "other" permissions for the directory Parameters ---------- base_paths : str or list The base path(s) to recursively update permissions on group : str The name of the group the contents of ``base_paths`` should belong to show_progress : bool, optional Whether to show a progress bar group_writable : bool, optional Whether to allow group write permissions other_readable : bool, optional Whether to allow world read (and, where appropriate, execute) permissions """ if isinstance(base_paths, str): directories = [base_paths] else: directories = base_paths new_uid = os.getuid() new_gid = grp.getgrnam(group).gr_gid read_write_perm = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP exec_perm = (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP) if group_writable: read_write_perm = read_write_perm | stat.S_IWGRP exec_perm = exec_perm | stat.S_IWGRP if other_readable: read_write_perm = read_write_perm | stat.S_IROTH exec_perm = exec_perm | stat.S_IROTH | stat.S_IXOTH mask = stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO # first the base directories that don't seem to be included in # os.walk() for directory in directories: try: dir_stat = os.stat(directory) except OSError: continue perm = dir_stat.st_mode & mask if perm == exec_perm and dir_stat.st_uid == new_uid and \ dir_stat.st_gid == new_gid: continue try: os.chown(directory, new_uid, new_gid) os.chmod(directory, exec_perm) except OSError: continue files_and_dirs = [] for base in directories: for root, dirs, files in os.walk(base): files_and_dirs.extend(dirs) files_and_dirs.extend(files) if show_progress: widgets = [progressbar.Percentage(), ' ', progressbar.Bar(), ' ', progressbar.ETA()] bar = progressbar.ProgressBar(widgets=widgets, maxval=len(files_and_dirs), maxerror=False).start() else: bar = None progress = 0 for base in directories: for root, dirs, files in os.walk(base): for directory in dirs: progress += 1 if show_progress: bar.update(progress) directory = os.path.join(root, directory) try: dir_stat = os.stat(directory) except OSError: continue perm = dir_stat.st_mode & mask if perm == exec_perm and dir_stat.st_uid == new_uid and \ dir_stat.st_gid == new_gid: continue try: os.chown(directory, new_uid, new_gid) os.chmod(directory, exec_perm) except OSError: continue for file_name in files: progress += 1 bar.update(progress) file_name = os.path.join(root, file_name) try: file_stat = os.stat(file_name) except OSError: continue perm = file_stat.st_mode & mask if perm & stat.S_IXUSR: # executable, so make sure others can execute it new_perm = exec_perm else: new_perm = read_write_perm if perm == new_perm and file_stat.st_uid == new_uid and \ file_stat.st_gid == new_gid: continue try: os.chown(file_name, new_uid, new_gid) os.chmod(file_name, new_perm) except OSError: continue if show_progress: bar.finish()