def put_resource(self, bundle_name, name, cache_seconds, content): """Puts a Resource in the datastore for testing, and tracks it to be cleaned up in test teardown.""" bundle = ResourceBundle(key_name=bundle_name) key = Resource(parent=bundle, key_name=name, content=content, cache_seconds=float(cache_seconds)).put() self.temp_entity_keys.append(key)
def test_resource_override(self): """Verifies that Resources in the datastore override files on disk.""" # Should render normally. doc = self.go('/haiti/create') assert 'xyz' not in doc.content # This Resource should override the create.html.template file. bundle = ResourceBundle(key_name='1') key1 = Resource(parent=bundle, key_name='create.html.template', content='xyz{{env.repo}}xyz').put() doc = self.go('/haiti/create') assert 'xyzhaitixyz' not in doc.content # old template is still cached # The new template should take effect after 1 second. self.advance_utcnow(seconds=1.1) doc = self.go('/haiti/create') assert 'xyzhaitixyz' in doc.content # A plain .html Resource should override the .html.template Resource. key2 = Resource(parent=bundle, key_name='create.html', content='xyzxyzxyz').put() self.advance_utcnow(seconds=1.1) doc = self.go('/haiti/create') assert 'xyzxyzxyz' in doc.content # After removing both Resources, should fall back to the original file. db.delete([key1, key2]) self.advance_utcnow(seconds=1.1) doc = self.go('/haiti/create') assert 'xyz' not in doc.content
def put_bundle(new_bundle_name, original_bundle_name=None): """Puts a new ResourceBundle, optionally copying from another bundle.""" new_bundle = ResourceBundle(key_name=new_bundle_name) entities = [new_bundle] if original_bundle_name: original_bundle = ResourceBundle.get_by_key_name(original_bundle_name) original_resources = Resource.all().ancestor(original_bundle) entities += [Resource(parent=new_bundle, key_name=resource.key().name(), cache_seconds=resource.cache_seconds, content=resource.content) for resource in original_resources] db.put(entities)
def test_resource_caching(self): """Verifies that Resources are cached properly.""" # There's no file here. self.go('/global/foo.txt') assert self.s.status == 404 self.go('/global/foo.txt?lang=fr') assert self.s.status == 404 # Add a Resource to be served as the static file. bundle = ResourceBundle(key_name='1') Resource(parent=bundle, key_name='static/foo.txt', content='hello').put() doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'hello' # Add a localized Resource. fr_key = Resource(parent=bundle, key_name='static/foo.txt:fr', content='bonjour').put() doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'hello' # original Resource remains cached # The cached version should expire after 1 second. self.advance_utcnow(seconds=1.1) doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'bonjour' # Change the non-localized Resource. Resource(parent=bundle, key_name='static/foo.txt', content='goodbye').put() doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'bonjour' # no effect on the localized Resource # Remove the localized Resource. db.delete(fr_key) doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'bonjour' # localized Resource remains cached # The cached version should expire after 1 second. self.advance_utcnow(seconds=1.1) doc = self.go('/global/foo.txt?lang=fr') assert doc.content_bytes == 'goodbye'
def handle(self, operation): """Handles both GET and POST requests. POST requests include an 'operation' param describing what the user is trying to change.""" bundle_name = self.params.resource_bundle or '' name = self.params.resource_name or '' lang = self.params.resource_lang or '' key_name = name + (lang and ':' + lang) editable = (bundle_name != self.env.default_resource_bundle) if not ResourceBundle.get_by_key_name( self.env.default_resource_bundle): ResourceBundle(key_name=self.env.default_resource_bundle).put() if operation == 'set_preview': # Set the resource_bundle cookie. This causes all pages to render # using the selected bundle (see main.py). We use a cookie so that # it's possible to preview PF as embedded on external sites. self.response.headers['Set-Cookie'] = \ 'resource_bundle=%s; path=/' % bundle_name return self.redirect(self.get_admin_url()) if operation == 'set_default': # Set the default resource bundle. config.set( default_resource_bundle=self.params.resource_bundle_default) return self.redirect(self.get_admin_url()) if operation == 'add_bundle' and editable: # Add a new bundle, optionally copying from an existing bundle. put_bundle(bundle_name, self.params.resource_bundle_original) return self.redirect(self.get_admin_url(bundle_name)) if operation == 'add_resource' and editable: # Go to the edit page for a new resource (don't create until save). return self.redirect(self.get_admin_url(bundle_name, name, lang)) if operation == 'delete_resource' and editable: # Delete a resource. resource = Resource.get(key_name, bundle_name) if resource: resource.delete() return self.redirect(self.get_admin_url(bundle_name)) if operation == 'put_resource' and editable: # Store the content of a resource. if isinstance(self.request.POST.get('file'), cgi.FieldStorage): content = self.request.get('file') # uploaded file content elif 'content' in self.request.POST: # edited text content = self.request.get('content').encode('utf-8') else: # modify cache_seconds but leave content unchanged resource = Resource.get(key_name, bundle_name) content = resource and resource.content or '' put_resource(bundle_name, key_name, content=content, cache_seconds=self.params.cache_seconds) return self.redirect(self.get_admin_url(bundle_name)) if not operation: self.write(PREFACE + self.format_nav_html(bundle_name, name, lang)) if bundle_name and name: self.show_resource(bundle_name, key_name, name, lang, editable) elif bundle_name: self.list_resources(bundle_name, editable) else: self.list_bundles()
def put_resource(bundle_name, key_name, **kwargs): """Puts a Resource in the datastore under the specified ResourceBundle.""" bundle = ResourceBundle(key_name=bundle_name) Resource(parent=bundle, key_name=key_name, **kwargs).put()