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)
Example #2
0
 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
Example #4
0
    def list_bundles(self):
        """Displays a list of all the resource bundles."""
        bundles = list(ResourceBundle.all().order('-created'))
        rows = []
        for bundle in bundles:
            bundle_name = bundle.key().name()
            bundle_name_html = html(bundle_name)
            is_default = bundle_name == self.env.default_resource_bundle
            is_in_preview = bundle_name == self.env.resource_bundle
            if is_default:
                bundle_name_html = '<b>%s</b> (default)' % bundle_name_html
            elif is_in_preview:
                bundle_name_html += ' (in preview)'
            rows.append(
                '''
<tr class="%(class)s">
  <td><a class="bundle" href="%(link)s">%(bundle_name_html)s</a></td>
  <td>%(created)s</td>
  <td><a href="%(preview)s"><input type="button" value="Preview"></a></td>
  <td><input type="radio" name="resource_bundle_default" value="%(bundle_name)s"
      %(default_checked)s></td>
</tr>''' % {
                    'class':
                    is_in_preview and 'active' or '',
                    'link':
                    self.get_admin_url(bundle_name),
                    'bundle_name':
                    bundle_name,
                    'bundle_name_html':
                    bundle_name_html,
                    'default_checked':
                    is_default and 'checked' or '',
                    'created':
                    format_datetime(bundle.created),
                    'preview':
                    self.get_admin_url(bundle_name, operation='set_preview')
                })

        self.write(
            '''
<form method="post">
  <input type="hidden" name="operation" value="set_default">
  <table cellpadding=0 cellspacing=0>
    <tr><th>Bundle name</th><th>Created</th>
    <th><a href="%(reset)s"><input type="button" value="Reset to default"
        ></a></th>
    <th><input type="submit" value="Set to default"></th></tr>
    %(rows)s
  </table>
</form>
<div class="add">
  <form method="post">
    <input type="hidden" name="operation" value="add_bundle">
    <input name="resource_bundle" size="18" placeholder="bundle name">
    <input type="submit" value="Add bundle">
  </form>
</div>''' % {
                'reset': self.get_admin_url(operation='set_preview'),
                'rows': ''.join(rows)
            })
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 list_bundles(self):
        """Displays a list of all the resource bundles."""
        bundles = list(ResourceBundle.all().order('-created'))
        rows = []
        for bundle in bundles:
            bundle_name = bundle.key().name()
            bundle_name_html = html(bundle_name)
            is_default = bundle_name == self.env.default_resource_bundle
            is_in_preview = bundle_name == self.env.resource_bundle
            if is_default:
                bundle_name_html = '<b>%s</b> (default)' % bundle_name_html
            elif is_in_preview:
                bundle_name_html += ' (in preview)'
            rows.append('''
<tr class="%(class)s">
  <td><a class="bundle" href="%(link)s">%(bundle_name_html)s</a></td>
  <td>%(created)s</td>
  <td><a href="%(preview)s"><input type="button" value="Preview"></a></td>
  <td><input type="radio" name="resource_bundle_default" value="%(bundle_name)s"
      %(default_checked)s></td>
</tr>''' % {
    'class': is_in_preview and 'active' or '',
    'link': self.get_admin_url(bundle_name),
    'bundle_name': bundle_name,
    'bundle_name_html': bundle_name_html,
    'default_checked': is_default and 'checked' or '',
    'created': format_datetime(bundle.created),
    'preview': self.get_admin_url(bundle_name, operation='set_preview')})

        self.write('''
<form method="post">
  <input type="hidden" name="operation" value="set_default">
  <table cellpadding=0 cellspacing=0>
    <tr><th>Bundle name</th><th>Created</th>
    <th><a href="%(reset)s"><input type="button" value="Reset to default"
        ></a></th>
    <th><input type="submit" value="Set to default"></th></tr>
    %(rows)s
  </table>
</form>
<div class="add">
  <form method="post">
    <input type="hidden" name="operation" value="add_bundle">
    <input name="resource_bundle" size="18" placeholder="bundle name">
    <input type="submit" value="Add bundle">
  </form>
</div>''' % {'reset': self.get_admin_url(operation='set_preview'),
             'rows': ''.join(rows)})
    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 test_admin_resources(self):
        # Verify that the bundle listing loads.
        doc = self.go_as_admin('/global/admin/resources')

        # Add a new bundle (redirects to the new bundle's resource listing).
        doc = self.s.submit(doc.cssselect('form')[-1], resource_bundle='xyz')
        assert doc.cssselect_one('a.sel').text == 'Bundle: xyz'
        bundle = ResourceBundle.get_by_key_name('xyz')
        assert bundle

        # Add a resource (redirects to the resource's edit page).
        doc = self.s.submit(doc.cssselect('form')[0], resource_name='abc')
        assert doc.cssselect_one('a.sel').text == 'Resource: abc'

        # The new Resource shouldn't exist in the datastore until it is saved.
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Enter some content for the resource.
        doc = self.s.submit(doc.cssselect('form')[0], content='pqr')
        assert Resource.get_by_key_name('abc', parent=bundle).content == 'pqr'

        # Use the breadcrumb navigation bar to go back to the resource listing.
        doc = self.s.follow('Bundle: xyz')

        # Add a localized variant of the resource.
        row = doc.xpath_one('//tr[td[normalize-space(.)="abc"]]')
        doc = self.s.submit(row.cssselect('form')[0], resource_lang='pl')
        assert doc.cssselect_one('a.sel').text == 'pl: Polish'

        # Enter some content for the localized resource.
        doc = self.s.submit(doc.cssselect('form')[0], content='jk')
        assert Resource.get_by_key_name('abc:pl',
                                        parent=bundle).content == 'jk'

        # Confirm that both the generic and localized resource are listed.
        doc = self.s.follow('Bundle: xyz')
        resource_texts = [a.text for a in doc.cssselect('a.resource')]
        assert 'abc' in resource_texts
        assert 'pl' in resource_texts

        # Copy all the resources to a new bundle.
        doc = self.s.submit(doc.cssselect('form')[-1],
                            resource_bundle='zzz',
                            resource_bundle_original='xyz')
        parent = ResourceBundle.get_by_key_name('zzz')
        assert Resource.get_by_key_name('abc', parent=parent).content == 'pqr'
        assert Resource.get_by_key_name('abc:pl',
                                        parent=parent).content == 'jk'

        # Verify that we can't add a resource to the default bundle.
        bundle = ResourceBundle.get_by_key_name('1')
        assert (bundle)
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.follow('1 (default)')
        self.s.submit(doc.cssselect('form')[0], resource_name='abc')
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Verify that we can't edit a resource in the default bundle.
        self.s.back()
        doc = self.s.follow('base.html.template')
        self.s.submit(doc.cssselect('form')[0], content='xyz')
        assert not Resource.get_by_key_name('base.html.template',
                                            parent=bundle)

        # Verify that we can't copy resources into the default bundle.
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.follow('xyz')
        doc = self.s.submit(doc.cssselect('form')[-1],
                            resource_bundle='1',
                            resource_bundle_original='xyz')
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Switch the default bundle version.
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.submit(doc.cssselect('form')[0],
                            resource_bundle_default='xyz')
        assert 'xyz (default)' in doc.text
        # Undo.
        doc = self.s.submit(doc.cssselect('form')[0],
                            resource_bundle_default='1')
        assert '1 (default)' in doc.text
    def list_resources(self, bundle_name, editable):
        """Displays a list of the resources in a bundle."""
        bundle = ResourceBundle.get_by_key_name(bundle_name)
        editable_class = editable and 'editable' or 'readonly'

        langs_by_name = {}  # Group language variants of each resource together.
        for filename in Resource.list_files():
            name, lang = (filename.rsplit(':', 1) + [None])[:2]
            langs_by_name.setdefault(name, {})[lang] = 'file'
        for resource_name in bundle.list_resources():
            name, lang = (resource_name.rsplit(':', 1) + [None])[:2]
            langs_by_name.setdefault(name, {})[lang] = 'resource'

        rows = []  # Each row shows one Resource and its localized variants.
        for name in sorted(langs_by_name):
            sources_by_lang = langs_by_name[name]
            altered = 'resource' in sources_by_lang.values()
            generic = '<a class="%s" href="%s">%s</a>' % (
                sources_by_lang.pop(None, 'missing'),
                self.get_admin_url(bundle_name, name), html(name))
            variants = ['<a class="%s" href="%s">%s</a>' % (
                sources_by_lang[lang],
                self.get_admin_url(bundle_name, name, lang), html(lang))
                for lang in sorted(sources_by_lang)]
            rows.append('''
<tr class="%(altered)s">
  <td>%(generic)s</td>
  <td>%(variants)s
    <form method="post" class="%(class)s">
      <input type="hidden" name="operation" value="add_resource">
      <input type="hidden" name="resource_name" value="%(name)s">
      <input name="resource_lang" size=3 class="hide-when-readonly"
          placeholder="lang">
      <input type="submit" value="Add" class="hide-when-readonly">
    </form>
  </td>
</tr>''' % {'altered': altered and 'altered' or 'unaltered',
            'generic': generic,
            'variants': ', '.join(variants),
            'class': editable_class,
            'name': name})

        self.write('''
<table cellpadding=0 cellspacing=0>
<tr><th>
  Resource name
  <span id="show-unaltered">
    <input id="show-unaltered-checkbox" type="checkbox"
        onchange="show_unaltered(this.checked)">
    <label for="show-unaltered-checkbox">Show unaltered files</label>
  </span>
</th><th>Localized variants</th></tr>
<tr class="add"><td>
  <form method="post" class="%(class)s">
    <input type="hidden" name="operation" value="add_resource">
    <input name="resource_name" size="36" class="hide-when-readonly"
        placeholder="resource filename">
    <input type="submit" value="Add" class="hide-when-readonly">
    <div class="warning hide-when-editable">
      This bundle cannot be edited while it is set as default.
    </div>
  </form>
</td><td></td></tr>
%(rows)s
</table>
<script>
function show_unaltered(show) {
  var rows = document.getElementsByClassName('unaltered');
  for (var r = 0; r < rows.length; r++) {
    rows[r].style.display = show ? '' : 'none';
  }
}
show_unaltered(false);
</script>
<form method="post" action="%(action)s">
  <input type="hidden" name="operation" value="add_bundle">
  <input type="hidden" name="resource_bundle_original" value="%(bundle_name)s">
  <table cellpadding=0 cellspacing=0>
    <tr><td>
      Copy all these resources to another bundle:
      <input name="resource_bundle" size="18"
          placeholder="bundle name">
      <input type="submit" value="Copy">
    </td></tr>
  </table>
</form>''' % {'class': editable_class,
              'rows': ''.join(rows),
              'action': self.get_admin_url(),
              'bundle_name': bundle_name})
Example #10
0
    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()
Example #11
0
    def test_admin_resources(self):
        # Verify that the bundle listing loads.
        doc = self.go_as_admin('/global/admin/resources')

        # Add a new bundle (redirects to the new bundle's resource listing).
        doc = self.s.submit(doc.last('form'), resource_bundle='xyz')
        assert doc.first('a', class_='sel', content='Bundle: xyz')
        bundle = ResourceBundle.get_by_key_name('xyz')
        assert(bundle)

        # Add a resource (redirects to the resource's edit page).
        doc = self.s.submit(doc.first('form'), resource_name='abc')
        assert doc.first('a', class_='sel', content='Resource: abc')

        # The new Resource shouldn't exist in the datastore until it is saved.
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Enter some content for the resource.
        doc = self.s.submit(doc.first('form'), content='pqr')
        assert Resource.get_by_key_name('abc', parent=bundle).content == 'pqr'

        # Use the breadcrumb navigation bar to go back to the resource listing.
        doc = self.s.follow('Bundle: xyz')

        # Add a localized variant of the resource.
        row = doc.first('td', content='abc').enclosing('tr')
        doc = self.s.submit(row.first('form'), resource_lang='pl')
        assert doc.first('a', class_='sel', content='pl: Polish')

        # Enter some content for the localized resource.
        doc = self.s.submit(doc.first('form'), content='jk')
        assert Resource.get_by_key_name('abc:pl', parent=bundle).content == 'jk'

        # Confirm that both the generic and localized resource are listed.
        doc = self.s.follow('Bundle: xyz')
        assert doc.first('a', class_='resource', content='abc')
        assert doc.first('a', class_='resource', content='pl')

        # Copy all the resources to a new bundle.
        doc = self.s.submit(doc.last('form'), resource_bundle='zzz',
                            resource_bundle_original='xyz')
        parent = ResourceBundle.get_by_key_name('zzz')
        assert Resource.get_by_key_name('abc', parent=parent).content == 'pqr'
        assert Resource.get_by_key_name('abc:pl', parent=parent).content == 'jk'

        # Verify that we can't add a resource to the default bundle.
        bundle = ResourceBundle.get_by_key_name('1')
        assert(bundle)
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.follow('1 (default)')
        self.s.submit(doc.first('form'), resource_name='abc')
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Verify that we can't edit a resource in the default bundle.
        self.s.back()
        doc = self.s.follow('base.html.template')
        self.s.submit(doc.first('form'), content='xyz')
        assert not Resource.get_by_key_name('base.html.template', parent=bundle)

        # Verify that we can't copy resources into the default bundle.
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.follow('xyz')
        doc = self.s.submit(doc.last('form'), resource_bundle='1',
                            resource_bundle_original='xyz')
        assert not Resource.get_by_key_name('abc', parent=bundle)

        # Switch the default bundle version.
        doc = self.go_as_admin('/global/admin/resources')
        doc = self.s.submit(doc.first('form'), resource_bundle_default='xyz')
        assert 'xyz (default)' in doc.text
        # Undo.
        doc = self.s.submit(doc.first('form'), resource_bundle_default='1')
        assert '1 (default)' in doc.text
Example #12
0
    def list_resources(self, bundle_name, editable):
        """Displays a list of the resources in a bundle."""
        bundle = ResourceBundle.get_by_key_name(bundle_name)
        editable_class = editable and 'editable' or 'readonly'

        langs_by_name = {
        }  # Group language variants of each resource together.
        for filename in Resource.list_files():
            name, lang = (filename.rsplit(':', 1) + [None])[:2]
            langs_by_name.setdefault(name, {})[lang] = 'file'
        for resource_name in bundle.list_resources():
            name, lang = (resource_name.rsplit(':', 1) + [None])[:2]
            langs_by_name.setdefault(name, {})[lang] = 'resource'

        rows = []  # Each row shows one Resource and its localized variants.
        for name in sorted(langs_by_name):
            sources_by_lang = langs_by_name[name]
            altered = 'resource' in sources_by_lang.values()
            generic = '<a class="%s" href="%s">%s</a>' % (sources_by_lang.pop(
                None, 'missing'), self.get_admin_url(bundle_name,
                                                     name), html(name))
            variants = [
                '<a class="%s" href="%s">%s</a>' %
                (sources_by_lang[lang],
                 self.get_admin_url(bundle_name, name, lang), html(lang))
                for lang in sorted(sources_by_lang)
            ]
            rows.append(
                '''
<tr class="%(altered)s">
  <td>%(generic)s</td>
  <td>%(variants)s
    <form method="post" class="%(class)s">
      <input type="hidden" name="operation" value="add_resource">
      <input type="hidden" name="resource_name" value="%(name)s">
      <input name="resource_lang" size=3 class="hide-when-readonly"
          placeholder="lang">
      <input type="submit" value="Add" class="hide-when-readonly">
    </form>
  </td>
</tr>''' % {
                    'altered': altered and 'altered' or 'unaltered',
                    'generic': generic,
                    'variants': ', '.join(variants),
                    'class': editable_class,
                    'name': name
                })

        self.write(
            '''
<table cellpadding=0 cellspacing=0>
<tr><th>
  Resource name
  <span id="show-unaltered">
    <input id="show-unaltered-checkbox" type="checkbox"
        onchange="show_unaltered(this.checked)">
    <label for="show-unaltered-checkbox">Show unaltered files</label>
  </span>
</th><th>Localized variants</th></tr>
<tr class="add"><td>
  <form method="post" class="%(class)s">
    <input type="hidden" name="operation" value="add_resource">
    <input name="resource_name" size="36" class="hide-when-readonly"
        placeholder="resource filename">
    <input type="submit" value="Add" class="hide-when-readonly">
    <div class="warning hide-when-editable">
      This bundle cannot be edited while it is set as default.
    </div>
  </form>
</td><td></td></tr>
%(rows)s
</table>
<script>
function show_unaltered(show) {
  var rows = document.getElementsByClassName('unaltered');
  for (var r = 0; r < rows.length; r++) {
    rows[r].style.display = show ? '' : 'none';
  }
}
show_unaltered(false);
</script>
<form method="post" action="%(action)s">
  <input type="hidden" name="operation" value="add_bundle">
  <input type="hidden" name="resource_bundle_original" value="%(bundle_name)s">
  <table cellpadding=0 cellspacing=0>
    <tr><td>
      Copy all these resources to another bundle:
      <input name="resource_bundle" size="18"
          placeholder="bundle name">
      <input type="submit" value="Copy">
    </td></tr>
  </table>
</form>''' % {
                'class': editable_class,
                'rows': ''.join(rows),
                'action': self.get_admin_url(),
                'bundle_name': bundle_name
            })
Example #13
0
    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()
Example #14
0
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()