Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8303)

Unified Diff: chrome/common/extensions/docs/server2/patched_file_system.py

Issue 14125010: Docserver: Add support for viewing docs with a codereview patch applied (Closed) Base URL: https://src.chromium.org/svn/trunk/src/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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,154 @@
+# 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 copy import deepcopy
+import logging
+
+from file_system import FileSystem, StatInfo, FileNotFoundError
+from future import Future
+
+class _AsyncFetchFuture(object):
+ def __init__(self,
+ svn_files_future,
+ patched_files_future,
+ svn_dirs_future,
+ dir_paths,
+ patched_file_system,
+ patcher):
+ self._svn_files_future = svn_files_future
+ self._patched_files_future = patched_files_future
+ self._svn_dirs_future = svn_dirs_future
+ self._dir_paths = dir_paths
+ self._patched_file_system = patched_file_system
+ self._patcher = patcher
not at google - send to devlin 2013/05/03 19:12:22 don't seem to be using this
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
+
+ def Get(self):
+ files = self._svn_files_future.Get()
+ files.update(self._patched_files_future.Get())
+ dirs = self._svn_dirs_future.Get()
+ files.update({path: self._PatchDirectoryListing(path,
+ dirs[path])
not at google - send to devlin 2013/05/03 19:12:22 why is this on a line by itself?
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
+ for path in self._dir_paths})
+ return files
+
+ def _PatchDirectoryListing(self, path, original_listing):
+ added, deleted, modified = (
+ self._patched_file_system._GetDirectoryListingFromPatch(path))
+ return list(set(original_listing) | set(added) - set(deleted))
+
+class Patcher(object):
+ def GetPatchedFiles(self):
+ ''' Returns (added_files, deleted_files, modified_files).
+ '''
+ raise NotImplementedError()
+
+ def GetVersion(self):
+ ''' Returns patch version. Returns None when nothing is patched by the
+ pathcer.
+ '''
+ raise NotImplementedError()
+
+ def Apply(self, paths, file_system, binary):
+ ''' Apply the patch to added/modified files. Returns Future with patched
+ data. Throws FileNotFoundError if |paths| contains deleted files.
+ '''
+ raise NotImplementedError()
not at google - send to devlin 2013/05/03 19:12:22 pls put this in a different file.
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
+
+class PatchedFileSystem(FileSystem):
+ ''' Class to fetch resources with a patch applied.
+ '''
+ def __init__(self, svn_file_system, patcher):
not at google - send to devlin 2013/05/03 19:12:22 I'm going to start calling svn_file_system 'host_f
方觉(Fang Jue) 2013/05/04 02:05:41 Done.
+ self._svn_file_system = svn_file_system
+ self._patcher = patcher
+
+ def Read(self, paths, binary=False):
+ patched_files = set()
+ for files in self._patcher.GetPatchedFiles():
+ patched_files |= set(files)
+ dir_paths = {path for path in paths if path.endswith('/')}
+ file_paths = set(paths) - dir_paths
+ patched_paths = file_paths & patched_files
+ unpatched_paths = file_paths - patched_files
+ return Future(delegate=_AsyncFetchFuture(
+ self._svn_file_system.Read(unpatched_paths, binary),
+ self._patcher.Apply(patched_paths, self._svn_file_system, binary),
+ self._svn_file_system.Read(dir_paths, binary),
+ dir_paths,
+ self,
+ self._patcher))
+
+ def _GetDirectoryListingFromPatch(self, path):
+ assert path.endswith('/')
+ def _FindChildrenInPath(files, path):
+ result = []
+ for f in files:
+ if f.startswith(path):
+ child_path = f[len(path):]
+ if '/' in child_path:
+ child_name = child_path[0:child_path.find('/') + 1]
+ else:
+ child_name = child_path
+ result.append(child_name)
+ return result
+
+ return (tuple(_FindChildrenInPath(files, path)
+ for files in self._patcher.GetPatchedFiles()))
+
+ def _PatchStat(self, stat_info, version, added, deleted, modified):
+ assert len(added) + len(deleted) + len(modified) > 0
+
+ # Deep copy before patching to make sure it doesn't interfere with values
+ # cached in memory.
+ stat_info = deepcopy(stat_info)
not at google - send to devlin 2013/05/03 19:12:22 yep, thanks
+
+ stat_info.version = version
+ if stat_info.child_versions is not None:
+ for child in added + modified:
+ stat_info.child_versions[child] = version
+ for child in deleted:
+ if stat_info.child_versions.get(child):
+ del stat_info.child_versions[child]
+
+ return stat_info
+
+ def Stat(self, path):
+ version = self._patcher.GetVersion()
+ if version is None:
+ return self._svn_file_system.Stat(path)
+ version = 'patched_%s' % version
+
+ directory, filename = path.rsplit('/', 1)
+ added, deleted, modified = self._GetDirectoryListingFromPatch(
+ directory + '/')
+
+ if len(added) > 0:
+ # There are new files added. It's possible (if |directory| is new) that
+ # self._svn_file_system.Stat will throw an exception.
+ try:
+ stat_info = self._PatchStat(self._svn_file_system.Stat(directory + '/'),
+ version,
+ added,
+ deleted,
+ modified)
+ except FileNotFoundError:
+ stat_info = StatInfo(version, {child: version
+ for child in added + modified})
+ elif len(deleted) + len(modified) > 0:
+ # No files were added.
+ stat_info = self._PatchStat(self._svn_file_system.Stat(path),
+ version,
+ added,
+ deleted,
+ modified)
+ else:
+ # No changes are made in this directory.
+ return self._svn_file_system.Stat(path)
+
+ if stat_info.child_versions is not None:
+ if filename:
+ if filename in stat_info.child_versions:
+ stat_info.version = stat_info.child_versions[filename]
+ else:
+ raise FileNotFoundError('%s was not in child versions' % filename)
+ return stat_info
Property changes on: chrome/common/extensions/docs/server2/patched_file_system.py
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698