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

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

Issue 13470005: Refactor the devserver to make it easier to control caching (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cduvall, rebase 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 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 json 5 import json
6 import logging 6 import logging
7 import os 7 import os
8 8
9 import appengine_blobstore as blobstore 9 import appengine_blobstore as blobstore
10 from appengine_wrappers import urlfetch 10 from appengine_wrappers import urlfetch
11 import object_store
12 from file_system import FileSystem, StatInfo 11 from file_system import FileSystem, StatInfo
12 from future import Future
13 from object_store_creator import ObjectStoreCreator
13 from StringIO import StringIO 14 from StringIO import StringIO
14 from future import Future
15 from zipfile import ZipFile, BadZipfile 15 from zipfile import ZipFile, BadZipfile
16 16
17 ZIP_KEY = 'zipball' 17 ZIP_KEY = 'zipball'
18 USERNAME = None 18 USERNAME = None
19 PASSWORD = None 19 PASSWORD = None
20 20
21 def _MakeKey(version): 21 def _MakeBlobstoreKey(version):
22 return ZIP_KEY + '.' + str(version) 22 return ZIP_KEY + '.' + str(version)
23 23
24 class _AsyncFetchFutureZip(object): 24 class _AsyncFetchFutureZip(object):
25 def __init__(self, fetcher, blobstore, key_to_set, key_to_delete=None): 25 def __init__(self, fetcher, blobstore, key_to_set, key_to_delete=None):
26 self._fetcher = fetcher 26 self._fetcher = fetcher
27 self._fetch = fetcher.FetchAsync(ZIP_KEY, 27 self._fetch = fetcher.FetchAsync(ZIP_KEY,
28 username=USERNAME, 28 username=USERNAME,
29 password=PASSWORD) 29 password=PASSWORD)
30 self._blobstore = blobstore 30 self._blobstore = blobstore
31 self._key_to_set = key_to_set 31 self._key_to_set = key_to_set
32 self._key_to_delete = key_to_delete 32 self._key_to_delete = key_to_delete
33 33
34 def Get(self): 34 def Get(self):
35 try: 35 try:
36 result = self._fetch.Get() 36 result = self._fetch.Get()
37 # Check if Github authentication failed. 37 # Check if Github authentication failed.
38 if result.status_code == 401: 38 if result.status_code == 401:
39 logging.error('Github authentication failed for %s, falling back to ' 39 logging.error('Github authentication failed for %s, falling back to '
40 'unauthenticated.' % USERNAME) 40 'unauthenticated.' % USERNAME)
41 blob = self._fetcher.Fetch(ZIP_KEY).content 41 blob = self._fetcher.Fetch(ZIP_KEY).content
42 else: 42 else:
43 blob = result.content 43 blob = result.content
44 except urlfetch.DownloadError as e: 44 except urlfetch.DownloadError as e:
45 logging.error('Bad github zip file: %s' % e) 45 logging.error('Bad github zip file: %s' % e)
46 return None 46 return None
47 if self._key_to_delete is not None: 47 if self._key_to_delete is not None:
48 self._blobstore.Delete(_MakeKey(self._key_to_delete), 48 self._blobstore.Delete(_MakeBlobstoreKey(self._key_to_delete),
49 blobstore.BLOBSTORE_GITHUB) 49 blobstore.BLOBSTORE_GITHUB)
50 try: 50 try:
51 return_zip = ZipFile(StringIO(blob)) 51 return_zip = ZipFile(StringIO(blob))
52 except BadZipfile as e: 52 except BadZipfile as e:
53 logging.error('Bad github zip file: %s' % e) 53 logging.error('Bad github zip file: %s' % e)
54 return None 54 return None
55 55
56 self._blobstore.Set(_MakeKey(self._key_to_set), 56 self._blobstore.Set(_MakeBlobstoreKey(self._key_to_set),
57 blob, 57 blob,
58 blobstore.BLOBSTORE_GITHUB) 58 blobstore.BLOBSTORE_GITHUB)
59 return return_zip 59 return return_zip
60 60
61 class GithubFileSystem(FileSystem): 61 class GithubFileSystem(FileSystem):
62 """FileSystem implementation which fetches resources from github. 62 """FileSystem implementation which fetches resources from github.
63 """ 63 """
64 def __init__(self, fetcher, object_store, blobstore): 64 def __init__(self, fetcher, blobstore):
65 self._fetcher = fetcher 65 self._fetcher = fetcher
66 self._object_store = object_store 66 self._stat_object_store = ObjectStoreCreator(GithubFileSystem).Create()
67 self._blobstore = blobstore 67 self._blobstore = blobstore
68 self._version = None 68 self._version = None
69 self._GetZip(self.Stat(ZIP_KEY).version) 69 self._GetZip(self.Stat(ZIP_KEY).version)
70 70
71 def _GetZip(self, version): 71 def _GetZip(self, version):
72 blob = self._blobstore.Get(_MakeKey(version), blobstore.BLOBSTORE_GITHUB) 72 blob = self._blobstore.Get(_MakeBlobstoreKey(version),
73 blobstore.BLOBSTORE_GITHUB)
73 if blob is not None: 74 if blob is not None:
74 try: 75 try:
75 self._zip_file = Future(value=ZipFile(StringIO(blob))) 76 self._zip_file = Future(value=ZipFile(StringIO(blob)))
76 except BadZipfile as e: 77 except BadZipfile as e:
77 self._blobstore.Delete(_MakeKey(version), blobstore.BLOBSTORE_GITHUB) 78 self._blobstore.Delete(_MakeBlobstoreKey(version),
79 blobstore.BLOBSTORE_GITHUB)
78 logging.error('Bad github zip file: %s' % e) 80 logging.error('Bad github zip file: %s' % e)
79 self._zip_file = Future(value=None) 81 self._zip_file = Future(value=None)
80 else: 82 else:
81 self._zip_file = Future( 83 self._zip_file = Future(
82 delegate=_AsyncFetchFutureZip(self._fetcher, 84 delegate=_AsyncFetchFutureZip(self._fetcher,
83 self._blobstore, 85 self._blobstore,
84 version, 86 version,
85 key_to_delete=self._version)) 87 key_to_delete=self._version))
86 self._version = version 88 self._version = version
87 89
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 for path in paths: 125 for path in paths:
124 if path.endswith('/'): 126 if path.endswith('/'):
125 result[path] = self._ListDir(path) 127 result[path] = self._ListDir(path)
126 else: 128 else:
127 result[path] = self._ReadFile(path) 129 result[path] = self._ReadFile(path)
128 return Future(value=result) 130 return Future(value=result)
129 131
130 def _DefaultStat(self, path): 132 def _DefaultStat(self, path):
131 version = 0 133 version = 0
132 # Cache for a minute so we don't try to keep fetching bad data. 134 # Cache for a minute so we don't try to keep fetching bad data.
133 self._object_store.Set(path, version, object_store.GITHUB_STAT, time=60) 135 self._stat_object_store.Set(path, version, time=60)
134 return StatInfo(version) 136 return StatInfo(version)
135 137
136 def Stat(self, path): 138 def Stat(self, path):
137 version = self._object_store.Get(path, object_store.GITHUB_STAT).Get() 139 version = self._stat_object_store.Get(path).Get()
138 if version is not None: 140 if version is not None:
139 return StatInfo(version) 141 return StatInfo(version)
140 try: 142 try:
141 result = self._fetcher.Fetch('commits/HEAD', 143 result = self._fetcher.Fetch('commits/HEAD',
142 username=USERNAME, 144 username=USERNAME,
143 password=PASSWORD) 145 password=PASSWORD)
144 except urlfetch.DownloadError as e: 146 except urlfetch.DownloadError as e:
145 logging.error('GithubFileSystem Stat: %s' % e) 147 logging.error('GithubFileSystem Stat: %s' % e)
146 return self._DefaultStat(path) 148 return self._DefaultStat(path)
147 # Check if Github authentication failed. 149 # Check if Github authentication failed.
148 if result.status_code == 401: 150 if result.status_code == 401:
149 logging.error('Github authentication failed for %s, falling back to ' 151 logging.error('Github authentication failed for %s, falling back to '
150 'unauthenticated.' % USERNAME) 152 'unauthenticated.' % USERNAME)
151 try: 153 try:
152 result = self._fetcher.Fetch('commits/HEAD') 154 result = self._fetcher.Fetch('commits/HEAD')
153 except urlfetch.DownloadError as e: 155 except urlfetch.DownloadError as e:
154 logging.error('GithubFileSystem Stat: %s' % e) 156 logging.error('GithubFileSystem Stat: %s' % e)
155 return self._DefaultStat(path) 157 return self._DefaultStat(path)
156 version = (json.loads(result.content).get('commit', {}) 158 version = (json.loads(result.content).get('commit', {})
157 .get('tree', {}) 159 .get('tree', {})
158 .get('sha', None)) 160 .get('sha', None))
159 # Check if the JSON was valid, and set to 0 if not. 161 # Check if the JSON was valid, and set to 0 if not.
160 if version is not None: 162 if version is not None:
161 self._object_store.Set(path, version, object_store.GITHUB_STAT) 163 self._stat_object_store.Set(path, version)
162 else: 164 else:
163 logging.warning('Problem fetching commit hash from github.') 165 logging.warning('Problem fetching commit hash from github.')
164 return self._DefaultStat(path) 166 return self._DefaultStat(path)
165 return StatInfo(version) 167 return StatInfo(version)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698