Chromium Code Reviews| Index: chrome/common/extensions/docs/server2/patched_file_system.py |
| =================================================================== |
| --- chrome/common/extensions/docs/server2/patched_file_system.py (revision 0) |
| +++ chrome/common/extensions/docs/server2/patched_file_system.py (revision 0) |
| @@ -0,0 +1,77 @@ |
| +# Copyright 2013 The Chromium Authors. All rights reserved. |
| +# Use of this source code is governed by a BSD-style license that can be |
| +# found in the LICENSE file. |
| + |
| +from file_system import FileSystem, StatInfo, FileNotFoundError |
| +from future import Future |
| +import logging |
| + |
| +class _AsyncFetchFuture(object): |
| + def __init__(self, paths, binary, svn_future, patched_future): |
| + self._svn_future = svn_future |
| + self._patched_future = patched_future |
| + |
| + def Get(self): |
| + value = self._svn_future.Get() |
| + value.update(self._patched_future.Get()) |
| + return value |
| + |
| +class PatchedFileSystem(FileSystem): |
| + """ Class to fetch resources with a patch applied. |
| + """ |
| + def __init__(self, patched_files, svn_file_system, patch_file_system): |
| + self._patched_files = patched_files |
| + self._svn_file_system = svn_file_system |
| + self._patch_file_system = patch_file_system |
| + |
| + def Read(self, paths, binary=False): |
| + # TODO(fj): What about directory listing? |
|
方觉(Fang Jue)
2013/04/29 12:46:23
I found that directory listing is used in APIListD
not at google - send to devlin
2013/04/29 16:38:49
Do you mean normally? As in the server right now,
方觉(Fang Jue)
2013/04/30 01:07:11
It's specific to the patched file system. When fet
|
| + patched_paths = list(set(paths) & set(self._patched_files)) |
| + unpatched_paths = list(set(paths) - set(self._patched_files)) |
| + return Future(delegate=_AsyncFetchFuture( |
| + paths, |
| + binary, |
| + self._svn_file_system.Read(unpatched_paths, binary), |
| + self._patch_file_system.Read(patched_paths, binary))) |
| + |
| + def _FindChildren(self, path): |
| + children = [] |
| + for p in self._patched_files: |
| + if p.startswith(path): |
| + child = p.split(path, 1)[1] |
| + if '/' in child: |
| + child = child.split('/', 1)[0] + '/' |
| + children.append(child) |
| + return children |
| + |
| + # Create dummy stat info for added files in a patch. |
| + def _TryCreateStatInfo(self, path): |
| + if path.endswith('/'): |
| + children = self._FindChildren(path) |
| + if len(children) == 0: |
| + return None |
| + return StatInfo('0', {child: '0' for child in children}) |
| + elif path in self._patched_files: |
| + return StatInfo('0', {}) |
| + else: |
| + return None |
| + |
| + # We assume that a patchset, once created, will never change. For any new |
| + # files, returned version will be '0'. Different patchesets will have |
| + # separate caches so they won't interfere with each other even if versions |
| + # are all '0'. |
|
not at google - send to devlin
2013/04/29 16:38:49
I was thinking about this more and we shouldn't be
方觉(Fang Jue)
2013/04/30 14:25:08
Done.
|
| + def Stat(self, path): |
| + try: |
| + stat_info = self._svn_file_system.Stat(path) |
| + if stat_info.child_versions: |
| + # New files can be added to the directory in the patch |
| + added_children = (set(self._FindChildren(path)) - |
| + set(stat_info.child_versions.keys())) |
| + stat_info.child_versions.update( |
| + {child: '0' for child in added_children}) |
| + except FileNotFoundError as e: |
| + # Try to create a dummy stat if a new file/directory is added. |
| + stat_info = self._TryCreateStatInfo(path) |
| + if stat_info is None: |
| + raise e |
| + return stat_info |
| Property changes on: chrome/common/extensions/docs/server2/patched_file_system.py |
| ___________________________________________________________________ |
| Added: svn:eol-style |
| + LF |