def chmod(self, path: str, mode: oct, recursive: bool = False) -> None: """Change file/directory mode. :param path: Path to be modified. :param mode: Operating-system mode bitfield. Must be in octal's form. Eg: chmod with (mode=0o755) = Permissions(user='******', group='rx', other='rx') :param recursive: If the path is directory, setting recursive to true would change permissions to sub folders and contained files. :type recursive: bool """ assert (isinstance(mode, str) or isinstance(mode, int)) if isinstance(mode, str): # convert mode to octal mode = int(mode, 8) chmod_cache_info = { 'access': { 'permissions': Permissions.create(mode) } } if self.isdir(path) and recursive: if path is not '/': self.setinfo(path, chmod_cache_info) # create a walker sub_dir = self.opendir(path) for _path, _ in sub_dir.walk.info(): self.setinfo(path + _path, chmod_cache_info) sub_dir.close() else: self.setinfo(path, chmod_cache_info)
def makedir(self, path, # type: Text permissions=None, # type: Optional[int] recreate=True # type: bool ): # make a directory in the file system. Also, update the cache about the directory. _path = self.norm_path(path) # we always want to overwrite a directory if it already exists. recreate = True if recreate is False else recreate perms = permissions fs_err = None try: super(AbstractFS, self).makedir(_path, permissions=None, recreate=recreate) except fs.errors.FSError as err: fs_err = err finally: if not fs_err: dir_perms = perms if perms else self.default_perms dir_cache = { 'access': { 'permissions': Permissions.create(dir_perms), 'uid': self.default_uid, 'gid': self.default_gid } } logger.debug('Created directory {}'.format(_path)) self.setinfo(_path, info=dir_cache) else: raise fs_err
def chmod(self, path: str, mode: oct, recursive: bool = False) -> None: """Change file/directory mode. :param path: Path to be modified. :param mode: Operating-system mode bitfield. Must be in octal's form. Eg: chmod with (mode=0o755) = Permissions(user='******', group='rx', other='rx') :param recursive: If the path is directory, setting recursive to true would change permissions to sub folders and contained files. :type recursive: bool """ assert isinstance(mode, str) or isinstance(mode, int) if isinstance(mode, str): # convert mode to octal mode = int(mode, 8) chmod_cache_info = { "access": { "permissions": Permissions.create(mode) } } if self.isdir(path) and recursive: if path is not "/": self.setinfo(path, chmod_cache_info) # create a walker sub_dir = self.opendir(path) for _path, _ in sub_dir.walk.info(): self.setinfo(path + _path, chmod_cache_info) sub_dir.close() else: self.setinfo(path, chmod_cache_info)
def makedir( self, path, # type: Text permissions=None, # type: Optional[int] recreate=True, # type: bool ): # make a directory in the file system. Also, update the cache about the directory. _path = self.norm_path(path) # we always want to overwrite a directory if it already exists. recreate = True if recreate is False else recreate perms = permissions fs_err = None try: super(AbstractFS, self).makedir(_path, permissions=None, recreate=recreate) except fs.errors.FSError as err: fs_err = err finally: if not fs_err: dir_perms = perms if perms else self.default_perms dir_cache = { "access": { "permissions": Permissions.create(dir_perms), "uid": self.default_uid, "gid": self.default_gid, } } logger.debug("Created directory {}".format(_path)) self.setinfo(_path, info=dir_cache) else: raise fs_err
def format_list(self, basedir, listing): """ Return an iterator object that yields the entries of given directory emulating the "/bin/ls -lA" UNIX command output. This is how output should appear: -rw-rw-rw- 1 owner group 7045120 Sep 02 3:47 music.mp3 drwxrwxrwx 1 owner group 0 Aug 31 18:50 e-books -rw-rw-rw- 1 owner group 380 Sep 02 3:40 module.py :param basedir: (str) must be protocol relative path :param listing: (list) list of files to needed for output. """ assert isinstance(basedir, str), basedir basedir += '/' if basedir[-1:] != '/' else basedir now = time.time() for basename in listing: file = self.norm_path( basedir + basename) # for e.g. basedir = '/' and basename = test.png. # So file is '/test.png' try: st = self.stat(file) except (fs.errors.FSError, FilesystemError): raise permission = filemode(Permissions.create(st['st_mode']).mode) if self.isdir(file): permission = permission.replace('?', 'd') elif self.isfile(file): permission = permission.replace('?', '-') elif self.islink(file): permission = permission.replace('?', 'l') nlinks = st['st_nlink'] size = st['st_size'] # file-size uname = self.getinfo(path=file, namespaces=['access']).user # |-> pwd.getpwuid(st['st_uid']).pw_name would fetch the user_name of the actual owner of these files. gname = self.getinfo(path=file, namespaces=['access']).group # |-> grp.getgrgid(st['st_gid']).gr_name would fetch the user_name of the actual of these files. mtime = time.gmtime( fs.time.datetime_to_epoch( self.getinfo(file, namespaces=['details']).modified)) if (now - st['st_mtime']) > (180 * 24 * 60 * 60): fmtstr = "%d %Y" else: fmtstr = "%d %H:%M" mtimestr = "%s %s" % (months_map[mtime.tm_mon], time.strftime(fmtstr, mtime)) if (st['st_mode'] & 61440) == stat.S_IFLNK: # if the file is a symlink, resolve it, e.g. "symlink -> realfile" basename = basename + " -> " + self.readlink(file) # formatting is matched with proftpd ls output line = "%s %3s %-8s %-8s %8s %s %s\r\n" % ( permission, nlinks, uname, gname, size, mtimestr, basename) yield line
def test_create(self): self.assertEqual(Permissions.create(None).mode, 0o777) self.assertEqual(Permissions.create(0o755).mode, 0o755) self.assertEqual(Permissions.create(["u_r", "u_w", "u_x"]).mode, 0o700) self.assertEqual(Permissions.create(Permissions(user="******")).mode, 0o700) with self.assertRaises(ValueError): Permissions.create("foo")
def test_create(self): self.assertEqual(Permissions.create(None).mode, 0o777) self.assertEqual(Permissions.create(0o755).mode, 0o755) self.assertEqual(Permissions.create(['u_r', 'u_w', 'u_x']).mode, 0o700) self.assertEqual( Permissions.create(Permissions(user='******')).mode, 0o700) with self.assertRaises(ValueError): Permissions.create('foo')
def format_list(self, basedir, listing): """ Return an iterator object that yields the entries of given directory emulating the "/bin/ls -lA" UNIX command output. This is how output should appear: -rw-rw-rw- 1 owner group 7045120 Sep 02 3:47 music.mp3 drwxrwxrwx 1 owner group 0 Aug 31 18:50 e-books -rw-rw-rw- 1 owner group 380 Sep 02 3:40 module.py :param basedir: (str) must be protocol relative path :param listing: (list) list of files to needed for output. """ assert isinstance(basedir, str), basedir basedir += '/' if basedir[-1:] != '/' else basedir now = time.time() for basename in listing: file = self.norm_path(basedir + basename) # for e.g. basedir = '/' and basename = test.png. # So file is '/test.png' try: st = self.stat(file) except (fs.errors.FSError, FilesystemError): raise permission = filemode(Permissions.create(st['st_mode']).mode) if self.isdir(file): permission = permission.replace('?', 'd') elif self.isfile(file): permission = permission.replace('?', '-') elif self.islink(file): permission = permission.replace('?', 'l') nlinks = st['st_nlink'] size = st['st_size'] # file-size uname = self.getinfo(path=file, namespaces=['access']).user # |-> pwd.getpwuid(st['st_uid']).pw_name would fetch the user_name of the actual owner of these files. gname = self.getinfo(path=file, namespaces=['access']).group # |-> grp.getgrgid(st['st_gid']).gr_name would fetch the user_name of the actual of these files. mtime = time.gmtime(fs.time.datetime_to_epoch(self.getinfo(file, namespaces=['details']).modified)) if (now - st['st_mtime']) > (180 * 24 * 60 * 60): fmtstr = "%d %Y" else: fmtstr = "%d %H:%M" mtimestr = "%s %s" % (months_map[mtime.tm_mon], time.strftime(fmtstr, mtime)) if (st['st_mode'] & 61440) == stat.S_IFLNK: # if the file is a symlink, resolve it, e.g. "symlink -> realfile" basename = basename + " -> " + self.readlink(file) # formatting is matched with proftpd ls output line = "%s %3s %-8s %-8s %8s %s %s\r\n" % (permission, nlinks, uname, gname, size, mtimestr, basename) yield line