11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Copyright 2013 The Chromium Authors. All rights reserved. 21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)# found in the LICENSE file. 41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)import posixpath 61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from docs_server_utils import StringIdentity 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)from file_system import FileSystem 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochfrom future import Future 101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class ChrootFileSystem(FileSystem): 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '''ChrootFileSystem(fs, path) exposes a FileSystem whose root is |path| inside 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) |fs|, so ChrootFileSystem(fs, 'hello').Read(['world']) is equivalent to 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fs.Read(['hello/world']) with the 'hello' prefix stripped from the result. 161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ''' 171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def __init__(self, file_system, root): 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '''Parameters: 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) |file_system| The FileSystem instance to transpose paths of. 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) |root| The path to transpose all Read/Stat calls by. 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ''' 231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._file_system = file_system 241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self._root = root.strip('/') 251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 26e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch def Read(self, paths, skip_not_found=False): 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) # Maintain reverse mapping so the result can be mapped to the original 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) # paths given (the result from |file_system| will include |root| in the 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) # result, which would be wrong). 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) prefixed_paths = {} 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def prefix(path): 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) prefixed = posixpath.join(self._root, path) 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) prefixed_paths[prefixed] = path 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return prefixed 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) def next(results): 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return dict((prefixed_paths[path], content) 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for path, content in results.iteritems()) 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return self._file_system.Read(tuple(prefix(path) for path in paths), 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) skip_not_found-skip_not_found).Then(next) 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Refresh(self): 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self._file_system.Refresh() 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def Stat(self, path): 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return self._file_system.Stat(posixpath.join(self._root, path)) 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) def GetIdentity(self): 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return StringIdentity( 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) '%s/%s' % (self._file_system.GetIdentity(), self._root)) 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __repr__(self): 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 'ChrootFileSystem(%s, %s)' % ( 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._root, repr(self._file_system)) 54