Index: chrome/common/extensions/docs/server2/subversion_file_system.py |
diff --git a/chrome/common/extensions/docs/server2/subversion_file_system.py b/chrome/common/extensions/docs/server2/subversion_file_system.py |
index a27d788ddfb66e7e47402911586c56741d5d2f05..54ed3833c42460805f37f5718ce159c6717a21c9 100644 |
--- a/chrome/common/extensions/docs/server2/subversion_file_system.py |
+++ b/chrome/common/extensions/docs/server2/subversion_file_system.py |
@@ -4,6 +4,7 @@ |
import re |
import xml.dom.minidom as xml |
+from xml.parsers.expat import ExpatError |
import file_system |
from future import Future |
@@ -11,18 +12,69 @@ from future import Future |
class SubversionFileSystem(file_system.FileSystem): |
"""Class to fetch resources from src.chromium.org. |
""" |
- def __init__(self, fetcher): |
+ def __init__(self, fetcher, stat_fetcher): |
self._fetcher = fetcher |
+ self._stat_fetcher = stat_fetcher |
def Read(self, paths, binary=False): |
return Future(delegate=_AsyncFetchFuture(paths, self._fetcher, binary)) |
+ def _ParseHTML(self, html): |
+ """Unfortunately, the viewvc page has a stray </div> tag, so this takes care |
+ of all mismatched tags. |
+ """ |
+ try: |
+ return xml.parseString(html) |
+ except ExpatError as e: |
+ new_html = [] |
+ for lineno, line in enumerate(html.split('\n')): |
+ if e.lineno != lineno + 1: |
+ new_html.append(line) |
+ return self._ParseHTML('\n'.join(new_html)) |
+ |
+ def _CreateStatInfo(self, html): |
+ dom = self._ParseHTML(html) |
+ # Brace yourself, this is about to get ugly. The page returned from viewvc |
+ # was not the prettiest. |
+ tds = dom.getElementsByTagName('td') |
+ a_list = [] |
+ found = False |
+ dir_revision = None |
+ for td in tds: |
+ if found: |
+ dir_revision = td.getElementsByTagName('a')[0].firstChild.nodeValue |
+ found = False |
+ a_list.extend(td.getElementsByTagName('a')) |
+ if (td.firstChild is not None and |
+ td.firstChild.nodeValue == 'Directory revision:'): |
+ found = True |
+ child_revisions = {} |
+ for i, a in enumerate(a_list): |
+ try: |
+ next_a = a_list[i + 1] |
+ except IndexError: |
+ break |
not at google - send to devlin
2012/08/13 23:02:14
Exceptions aren't a good way of signaling control
not at google - send to devlin
2012/08/14 04:00:08
and by that I mean >= not <
cduvall
2012/08/14 18:15:00
Done.
|
+ name = a.getAttribute('name') |
+ if name: |
+ rev = next_a.getElementsByTagName('strong')[0] |
+ if 'file' in next_a.getAttribute('title'): |
+ child_revisions[name] = rev.firstChild.nodeValue |
+ else: |
+ child_revisions[name + '/'] = rev.firstChild.nodeValue |
+ return self.StatInfo(dir_revision, child_revisions) |
+ |
def Stat(self, path): |
directory = path.rsplit('/', 1)[0] |
- result = self._fetcher.Fetch(directory + '/') |
+ result = self._stat_fetcher.Fetch(directory + '/') |
if result.status_code == 404: |
raise file_system.FileNotFoundError(path) |
- return self.StatInfo(int(re.search('([0-9]+)', result.content).group(0))) |
+ stat_info = self._CreateStatInfo(result.content) |
+ if not path.endswith('/'): |
+ filename = path.rsplit('/', 1)[-1] |
+ if filename not in stat_info.child_versions: |
+ raise file_system.FileNotFoundError(path) |
+ stat_info.version = stat_info.child_versions[filename] |
+ return stat_info |
class _AsyncFetchFuture(object): |
def __init__(self, paths, fetcher, binary): |