Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / server2 / appengine_wrappers.py
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
3 # found in the LICENSE file.
4
5 def IsDeadlineExceededError(error):
6   '''A general way of determining whether |error| is a DeadlineExceededError,
7   since there are 3 different types thrown by AppEngine and we might as well
8   handle them all the same way. For more info see:
9   https://developers.google.com/appengine/articles/deadlineexceedederrors
10   '''
11   return type(error).__name__ == 'DeadlineExceededError'
12
13
14 def IsDownloadError(error):
15   return type(error).__name__ == 'DownloadError'
16
17
18 # This will attempt to import the actual App Engine modules, and if it fails,
19 # they will be replaced with fake modules. This is useful during testing.
20 try:
21   import google.appengine.api.app_identity as app_identity
22   import google.appengine.api.files as files
23   import google.appengine.api.logservice as logservice
24   import google.appengine.api.memcache as memcache
25   import google.appengine.api.taskqueue as taskqueue
26   import google.appengine.api.urlfetch as urlfetch
27   import google.appengine.ext.blobstore as blobstore
28   from google.appengine.ext.blobstore.blobstore import BlobReferenceProperty
29   import google.appengine.ext.db as db
30   import webapp2
31 except ImportError:
32   import re
33   from StringIO import StringIO
34
35   FAKE_URL_FETCHER_CONFIGURATION = None
36
37   def ConfigureFakeUrlFetch(configuration):
38     """|configuration| is a dictionary mapping strings to fake urlfetch classes.
39     A fake urlfetch class just needs to have a fetch method. The keys of the
40     dictionary are treated as regex, and they are matched with the URL to
41     determine which fake urlfetch is used.
42     """
43     global FAKE_URL_FETCHER_CONFIGURATION
44     FAKE_URL_FETCHER_CONFIGURATION = dict(
45         (re.compile(k), v) for k, v in configuration.iteritems())
46
47   def _GetConfiguration(key):
48     if not FAKE_URL_FETCHER_CONFIGURATION:
49       raise ValueError('No fake fetch paths have been configured. '
50                        'See ConfigureFakeUrlFetch in appengine_wrappers.py.')
51     for k, v in FAKE_URL_FETCHER_CONFIGURATION.iteritems():
52       if k.match(key):
53         return v
54     raise ValueError('No configuration found for %s' % key)
55
56   class _RPC(object):
57     def __init__(self, result=None):
58       self.result = result
59
60     def get_result(self):
61       return self.result
62
63     def wait(self):
64       pass
65
66   class FakeAppIdentity(object):
67     """A fake app_identity module that returns no access tokens."""
68     def get_access_token(self, scope):
69       return (None, None)
70   app_identity = FakeAppIdentity()
71
72   class FakeUrlFetch(object):
73     """A fake urlfetch module that uses the current
74     |FAKE_URL_FETCHER_CONFIGURATION| to map urls to fake fetchers.
75     """
76     class DownloadError(Exception):
77       pass
78
79     class _Response(object):
80       def __init__(self, content):
81         self.content = content
82         self.headers = {'Content-Type': 'none'}
83         self.status_code = 200
84
85     def fetch(self, url, **kwargs):
86       url = url.split('?', 1)[0]
87       response = self._Response(_GetConfiguration(url).fetch(url))
88       if response.content is None:
89         response.status_code = 404
90       return response
91
92     def create_rpc(self, **kwargs):
93       return _RPC()
94
95     def make_fetch_call(self, rpc, url, **kwargs):
96       rpc.result = self.fetch(url)
97   urlfetch = FakeUrlFetch()
98
99   _BLOBS = {}
100   class FakeBlobstore(object):
101     class BlobNotFoundError(Exception):
102       pass
103
104     class BlobReader(object):
105       def __init__(self, blob_key):
106         self._data = _BLOBS[blob_key].getvalue()
107
108       def read(self):
109         return self._data
110
111   blobstore = FakeBlobstore()
112
113   class FakeFileInterface(object):
114     """This class allows a StringIO object to be used in a with block like a
115     file.
116     """
117     def __init__(self, io):
118       self._io = io
119
120     def __exit__(self, *args):
121       pass
122
123     def write(self, data):
124       self._io.write(data)
125
126     def __enter__(self, *args):
127       return self._io
128
129   class FakeFiles(object):
130     _next_blobstore_key = 0
131     class blobstore(object):
132       @staticmethod
133       def create():
134         FakeFiles._next_blobstore_key += 1
135         return FakeFiles._next_blobstore_key
136
137       @staticmethod
138       def get_blob_key(filename):
139         return filename
140
141     def open(self, filename, mode):
142       _BLOBS[filename] = StringIO()
143       return FakeFileInterface(_BLOBS[filename])
144
145     def GetBlobKeys(self):
146       return _BLOBS.keys()
147
148     def finalize(self, filename):
149       pass
150
151   files = FakeFiles()
152
153   class Logservice(object):
154     AUTOFLUSH_ENABLED = True
155
156     def flush(self):
157       pass
158
159   logservice = Logservice()
160
161   class InMemoryMemcache(object):
162     """An in-memory memcache implementation.
163     """
164     def __init__(self):
165       self._namespaces = {}
166
167     class Client(object):
168       def set_multi_async(self, mapping, namespace='', time=0):
169         for k, v in mapping.iteritems():
170           memcache.set(k, v, namespace=namespace, time=time)
171
172       def get_multi_async(self, keys, namespace='', time=0):
173         return _RPC(result=dict(
174           (k, memcache.get(k, namespace=namespace, time=time)) for k in keys))
175
176     def set(self, key, value, namespace='', time=0):
177       self._GetNamespace(namespace)[key] = value
178
179     def get(self, key, namespace='', time=0):
180       return self._GetNamespace(namespace).get(key)
181
182     def delete(self, key, namespace=''):
183       self._GetNamespace(namespace).pop(key, None)
184
185     def delete_multi(self, keys, namespace=''):
186       for k in keys:
187         self.delete(k, namespace=namespace)
188
189     def _GetNamespace(self, namespace):
190       if namespace not in self._namespaces:
191         self._namespaces[namespace] = {}
192       return self._namespaces[namespace]
193
194   memcache = InMemoryMemcache()
195
196   class webapp2(object):
197     class RequestHandler(object):
198       """A fake webapp2.RequestHandler class for Handler to extend.
199       """
200       def __init__(self, request, response):
201         self.request = request
202         self.response = response
203         self.response.status = 200
204
205       def redirect(self, path, permanent=False):
206         self.response.status = 301 if permanent else 302
207         self.response.headers['Location'] = path
208
209   class _Db_Result(object):
210     def __init__(self, data):
211       self._data = data
212
213     class _Result(object):
214       def __init__(self, value):
215         self.value = value
216
217     def get(self):
218       return self._Result(self._data)
219
220   class db(object):
221     _store = {}
222
223     class StringProperty(object):
224       pass
225
226     class BlobProperty(object):
227       pass
228
229     class Key(object):
230       def __init__(self, key):
231         self._key = key
232
233       @staticmethod
234       def from_path(model_name, path):
235         return db.Key('%s/%s' % (model_name, path))
236
237       def __eq__(self, obj):
238         return self.__class__ == obj.__class__ and self._key == obj._key
239
240       def __hash__(self):
241         return hash(self._key)
242
243       def __str__(self):
244         return str(self._key)
245
246     class Model(object):
247       key = None
248
249       def __init__(self, **optargs):
250         cls = self.__class__
251         for k, v in optargs.iteritems():
252           assert hasattr(cls, k), '%s does not define property %s' % (
253               cls.__name__, k)
254           setattr(self, k, v)
255
256       @staticmethod
257       def gql(query, key):
258         return _Db_Result(db._store.get(key))
259
260       def put(self):
261         db._store[self.key_] = self.value
262
263     @staticmethod
264     def get_async(key):
265       return _RPC(result=db._store.get(key))
266
267     @staticmethod
268     def delete_async(key):
269       db._store.pop(key, None)
270       return _RPC()
271
272     @staticmethod
273     def put_async(value):
274       db._store[value.key] = value
275       return _RPC()
276
277   class BlobReferenceProperty(object):
278     pass
279
280   # Executes any queued tasks synchronously as they are queued.
281   _task_runner = None
282
283   def SetTaskRunnerForTest(task_runner):
284     global _task_runner
285     _task_runner = task_runner
286
287   class SynchronousTaskQueue(object):
288     class Task(object):
289       def __init__(self, url=None, params={}):
290         self.url_ = url
291         self.params_ = params
292
293       def GetUrl(self):
294         return self.url_
295
296       def GetCommit(self):
297         return self.params_.get('commit')
298
299     class Queue(object):
300       def __init__(self, name='default'):
301         pass
302
303       def add(self, task):
304         global _task_runner
305         if _task_runner:
306           _task_runner(task.GetUrl(), task.GetCommit())
307         return _RPC()
308
309       def purge(self):
310         return _RPC()
311
312   taskqueue = SynchronousTaskQueue()