1""" 2fs.wrapfs.readonlyfs 3==================== 4 5An FS wrapper class for blocking operations that would modify the FS. 6 7""" 8 9from fs.base import NoDefaultMeta 10from fs.wrapfs import WrapFS 11from fs.errors import UnsupportedError, NoSysPathError 12 13 14class ReadOnlyFS(WrapFS): 15 """ Makes a FS object read only. Any operation that could potentially modify 16 the underlying file system will throw an UnsupportedError 17 18 Note that this isn't a secure sandbox, untrusted code could work around the 19 read-only restrictions by getting the base class. Its main purpose is to 20 provide a degree of safety if you want to protect an FS object from 21 accidental modification. 22 23 """ 24 25 def getmeta(self, meta_name, default=NoDefaultMeta): 26 if meta_name == 'read_only': 27 return True 28 return self.wrapped_fs.getmeta(meta_name, default) 29 30 def hasmeta(self, meta_name): 31 if meta_name == 'read_only': 32 return True 33 return self.wrapped_fs.hasmeta(meta_name) 34 35 def getsyspath(self, path, allow_none=False): 36 """ Doesn't technically modify the filesystem but could be used to work 37 around read-only restrictions. """ 38 if allow_none: 39 return None 40 raise NoSysPathError(path) 41 42 def open(self, path, mode='r', buffering=-1, encoding=None, errors=None, newline=None, line_buffering=False, **kwargs): 43 """ Only permit read access """ 44 if 'w' in mode or 'a' in mode or '+' in mode: 45 raise UnsupportedError('write') 46 return super(ReadOnlyFS, self).open(path, 47 mode=mode, 48 buffering=buffering, 49 encoding=encoding, 50 errors=errors, 51 newline=newline, 52 line_buffering=line_buffering, 53 **kwargs) 54 55 def _no_can_do(self, *args, **kwargs): 56 """ Replacement method for methods that can modify the file system """ 57 raise UnsupportedError('write') 58 59 move = _no_can_do 60 movedir = _no_can_do 61 copy = _no_can_do 62 copydir = _no_can_do 63 makedir = _no_can_do 64 rename = _no_can_do 65 setxattr = _no_can_do 66 delxattr = _no_can_do 67 remove = _no_can_do 68 removedir = _no_can_do 69 settimes = _no_can_do 70 setcontents = _no_can_do 71 createfile = _no_can_do 72