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

Side by Side Diff: chrome/common/extensions/docs/server2/subversion_file_system.py

Issue 10828235: Extensions Docs Server: Efficient MemcacheFileSystem (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Tests! Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import re 5 import re
6 import xml.dom.minidom as xml 6 import xml.dom.minidom as xml
7 from xml.parsers.expat import ExpatError
7 8
8 import file_system 9 import file_system
9 from future import Future 10 from future import Future
10 11
11 class SubversionFileSystem(file_system.FileSystem): 12 class SubversionFileSystem(file_system.FileSystem):
12 """Class to fetch resources from src.chromium.org. 13 """Class to fetch resources from src.chromium.org.
13 """ 14 """
14 def __init__(self, fetcher): 15 def __init__(self, fetcher, stat_fetcher):
15 self._fetcher = fetcher 16 self._fetcher = fetcher
17 self._stat_fetcher = stat_fetcher
16 18
17 def Read(self, paths, binary=False): 19 def Read(self, paths, binary=False):
18 return Future(delegate=_AsyncFetchFuture(paths, self._fetcher, binary)) 20 return Future(delegate=_AsyncFetchFuture(paths, self._fetcher, binary))
19 21
22 def _ParseHTML(self, html):
23 """Unfortunately, the viewvc page has a stray </div> tag, so this takes care
24 of all mismatched tags.
25 """
26 try:
27 return xml.parseString(html)
not at google - send to devlin 2012/08/13 05:34:15 Wow, it kinda-works with an XML parser? Amazing.
28 except ExpatError as e:
29 new_html = []
30 for lineno, line in enumerate(html.split('\n')):
31 if e.lineno != lineno + 1:
32 new_html.append(line)
33 return self._ParseHTML('\n'.join(new_html))
not at google - send to devlin 2012/08/13 05:34:15 I love a good list comprehension challenge. retur
cduvall 2012/08/13 19:45:45 I didn't use one of the HTML parsing libraries bec
not at google - send to devlin 2012/08/13 23:02:14 No list comprehension? :(
cduvall 2012/08/14 18:15:00 Oops forgot to change it! Done :)
34
35 def _CreateStatInfo(self, html):
36 dom = self._ParseHTML(html)
37 # Brace yourself, this is about to get ugly. The page returned from viewvc
38 # was not the prettiest.
not at google - send to devlin 2012/08/13 05:34:15 yup
39 tds = dom.getElementsByTagName('td')
40 a_list = []
41 found = False
42 dir_revision = None
43 for td in tds:
44 if found:
45 dir_revision = td.getElementsByTagName('a')[0].firstChild.nodeValue
46 found = False
47 a_list.extend(td.getElementsByTagName('a'))
48 if (td.firstChild is not None and
49 td.firstChild.nodeValue == 'Directory revision:'):
50 found = True
51 child_revisions = {}
52 for i in range(len(a_list)):
not at google - send to devlin 2012/08/13 05:34:15 is there something special about a_list that means
cduvall 2012/08/13 19:45:45 No, no there isn't. That's just me being strange.
53 name = a_list[i].getAttribute('name')
54 if name:
55 rev = a_list[i + 1].getElementsByTagName('strong')[0]
not at google - send to devlin 2012/08/13 05:34:15 so we know for sure that this won't be past the en
cduvall 2012/08/13 19:45:45 If the HTML doesn't change it won't go past the en
56 if 'file' in a_list[i + 1].getAttribute('title'):
57 child_revisions[name] = rev.firstChild.nodeValue
58 else:
59 child_revisions[name + '/'] = rev.firstChild.nodeValue
60 return self.StatInfo(dir_revision, child_revisions)
61
20 def Stat(self, path): 62 def Stat(self, path):
21 directory = path.rsplit('/', 1)[0] 63 directory = path.rsplit('/', 1)[0]
22 result = self._fetcher.Fetch(directory + '/') 64 result = self._stat_fetcher.Fetch(directory + '/')
23 if result.status_code == 404: 65 if result.status_code == 404:
24 raise file_system.FileNotFoundError(path) 66 raise file_system.FileNotFoundError(path)
25 return self.StatInfo(int(re.search('([0-9]+)', result.content).group(0))) 67 stat_info = self._CreateStatInfo(result.content)
68 if not path.endswith('/'):
69 filename = path.rsplit('/', 1)[-1]
70 if filename in stat_info.child_versions:
71 stat_info.version = stat_info.child_versions[filename]
not at google - send to devlin 2012/08/13 05:34:15 throw FileNotFoundException if it isn't?
cduvall 2012/08/13 19:45:45 Done.
72 return stat_info
26 73
27 class _AsyncFetchFuture(object): 74 class _AsyncFetchFuture(object):
28 def __init__(self, paths, fetcher, binary): 75 def __init__(self, paths, fetcher, binary):
29 # A list of tuples of the form (path, Future). 76 # A list of tuples of the form (path, Future).
30 self._fetches = [] 77 self._fetches = []
31 self._value = {} 78 self._value = {}
32 self._error = None 79 self._error = None
33 self._fetches = [(path, fetcher.FetchAsync(path)) for path in paths] 80 self._fetches = [(path, fetcher.FetchAsync(path)) for path in paths]
34 self._binary = binary 81 self._binary = binary
35 82
(...skipping 12 matching lines...) Expand all
48 elif path.endswith('/'): 95 elif path.endswith('/'):
49 self._value[path] = self._ListDir(result.content) 96 self._value[path] = self._ListDir(result.content)
50 elif not self._binary: 97 elif not self._binary:
51 self._value[path] = file_system._ProcessFileData(result.content, path) 98 self._value[path] = file_system._ProcessFileData(result.content, path)
52 else: 99 else:
53 self._value[path] = result.content 100 self._value[path] = result.content
54 if self._error is not None: 101 if self._error is not None:
55 raise self._error 102 raise self._error
56 return self._value 103 return self._value
57 104
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698