def action_add(self): ret = '<h2>Add content</h2>' content_view = self.section.handler.request.get('content_view') if self.section.handler.request.get('content_view') else '' namespace = self.section.handler.request.get('namespace').replace('/', '-').replace(' ', '-').replace('.', '-').lower() if self.section.handler.request.get('namespace') else '' if namespace: existing_content = content.get_by_namespace(namespace) existing_content_type = existing_content.__class__.__name__ if existing_content else None # TODO: Ensure that the below actually exist rank = int(self.section.path_params[0]) content_type, view = content_view.split('.') if self.section.handler.request.get('submit') and not content_view: ret += '<div class="status error">Content is required</div>' elif self.section.handler.request.get('submit') and not namespace: ret += '<div class="status error">Namespace is required</div>' elif self.section.handler.request.get('submit') and existing_content_type: if existing_content_type != content_type: ret += '<div class="status error">Selected namespace already exists for a different type of content</div>' else: if existing_content.section_path and not permission.is_admin(existing_content.section_path): ret += '<div class="status error">Selected namespace already exists for content that you are not permitted to manage</div>' elif self.section.handler.request.get('confirm'): self.content_types.insert(rank, existing_content.__class__.__name__) self.content_paths.insert(rank, existing_content.section_path if existing_content.section_path else '') self.content_namespaces.insert(rank, namespace) self.content_views.insert(rank, view) self.update() ret += str(existing_content) raise Exception('Redirect', self.section.action_redirect_path) else: ret += '<div class="status progress">Selected namespace already exists, continue to add a view to this existing content</div>' f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'hidden', 'content_view', content_view)) f.add_control(control(self.section, 'hidden', 'namespace', namespace)) f.add_control(control(self.section, 'hidden', 'confirm', '1')) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) ret += unicode(f) return ret elif self.section.handler.request.get('submit'): content.get_else_create(self.section.path, content_type, namespace, self.namespace) self.content_types.insert(rank, content_type) self.content_paths.insert(rank, self.section_path if self.section_path else '') self.content_namespaces.insert(rank, namespace) self.content_views.insert(rank, view) self.update() raise Exception('Redirect', self.section.action_redirect_path) content_views = [['', '']] for content_type in content.get_all_content_types(): m = importlib.import_module('framework.content.' + content_type.lower()) views = [] for v in getattr(m, content_type.title())().views: if v[2]: views.append([content_type + '.' + v[0], v[1]]) if views: content_views.append([content_type, views]) f = form(self.section, self.section.full_path) f.add_control(selectcontrol(self.section, 'content_view', content_views, content_view, 'Content type')) f.add_control(control(self.section, 'text', 'namespace', namespace, 'Namespace')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) ret += unicode(f) return ret
def action_edit(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') message = '' theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): new_namespace = self.section.handler.request.get('namespace') if not new_namespace: message = '<div class="status error">Namespace is required</div>' elif new_namespace != theme.namespace and new_namespace in self.theme_namespaces: message = '<div class="status error">%s is already a custom theme namespace</div>' % new_namespace elif new_namespace != theme.namespace and is_local_theme_namespace( new_namespace): message = '<div class="status error">"%s" is a local theme namespace</div>' % new_namespace elif new_namespace != theme.namespace: for t in theme.body_template_names: section.rename_theme_namespace_template( theme.namespace + '/' + t, new_namespace + '/' + t) self.theme_namespaces[self.theme_namespaces.index( theme.namespace)] = new_namespace self.update() theme.namespace = new_namespace theme.put() cache.flush_all( ) # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control( control(self.section, 'text', 'namespace', theme.namespace)) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Edit namespace</h2>%s' % (message, unicode(f))
def get_form(section, title, body): f = form(section, section.full_path) f.add_control(control(section, 'text', 'title', title, 'Title', 60)) f.add_control( textareacontrol(section, 'body', body, 'Body', 100, 10, html=True)) f.add_control(control(section, 'submit', 'submit')) return unicode(f)
def view_themes_previewer(self, params=None): if not configuration.theme_preview_enabled(): return '' combined_themes = get_local_theme_namespaces( ) + get_custom_theme_namespaces() if self.section.handler and self.section.handler.request.get( 'submit_themes_previewer'): selected_theme = self.section.handler.request.get( 'TEMPLATE_OVERRIDE_THEME') elif self.section.theme: selected_theme = self.section.theme else: selected_theme = configuration.default_theme() if not selected_theme: selected_theme = template.DEFAULT_LOCAL_THEME_TEMPLATE f = form(self.section, self.section.full_path) f.add_control( selectcontrol(self.section, 'TEMPLATE_OVERRIDE_THEME', combined_themes, selected_theme)) f.add_control( control(self.section, 'submit', 'submit_themes_previewer', 'Preview theme')) self.section.css.append('themes-previewer.css') return '<div class="content themes-previewer">%s</div>' % unicode(f)
def action_edit(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') message = '' theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): new_namespace = self.section.handler.request.get('namespace') if not new_namespace: message = '<div class="status error">Namespace is required</div>' elif new_namespace != theme.namespace and new_namespace in self.theme_namespaces: message = '<div class="status error">%s is already a custom theme namespace</div>' % new_namespace elif new_namespace != theme.namespace and is_local_theme_namespace(new_namespace): message = '<div class="status error">"%s" is a local theme namespace</div>' % new_namespace elif new_namespace != theme.namespace: for t in theme.body_template_names: section.rename_theme_namespace_template(theme.namespace + '/' + t, new_namespace + '/' + t) self.theme_namespaces[self.theme_namespaces.index(theme.namespace)] = new_namespace self.update() theme.namespace = new_namespace theme.put() cache.flush_all() # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'namespace', theme.namespace)) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Edit namespace</h2>%s' % (message, unicode(f))
def action_edit(self): if self.section.handler.request.get('submit'): self.SITE_HEADER = self.section.handler.request.get('SITE_HEADER') self.SITE_SUB_HEADER = self.section.handler.request.get('SITE_SUB_HEADER') self.DEFAULT_THEME = self.section.handler.request.get('DEFAULT_THEME') self.GOOGLE_ANALYTICS_UA = self.section.handler.request.get('GOOGLE_ANALYTICS_UA') self.ROBOTS_TXT = self.section.handler.request.get('ROBOTS_TXT') if self.section.handler.request.get('FAVICON_ICO'): data = db.Blob(self.section.handler.request.get('FAVICON_ICO')) if self.FAVICON_ICO: self.FAVICON_ICO.data = data else: self.FAVICON_ICO = File(filename='favicon.ico', content_type='image/x-icon', data=data) self.FAVICON_ICO.put() self.ENABLE_THEME_PREVIEW = self.section.handler.request.get('ENABLE_THEME_PREVIEW') != '' self.DEBUG_MODE = self.section.handler.request.get('DEBUG_MODE') != '' cache.delete(CACHE_KEY) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'SITE_HEADER', self.SITE_HEADER, 'Site header', 50)) f.add_control(control(self.section, 'text', 'SITE_SUB_HEADER', self.SITE_SUB_HEADER, 'Site sub-header', 50)) combined_themes = get_local_theme_namespaces() + get_custom_theme_namespaces() f.add_control(selectcontrol(self.section, 'DEFAULT_THEME', combined_themes, self.DEFAULT_THEME if self.DEFAULT_THEME else DEFAULT_LOCAL_THEME_TEMPLATE, 'Default theme')) f.add_control(control(self.section, 'text', 'GOOGLE_ANALYTICS_UA', self.GOOGLE_ANALYTICS_UA, 'Google analytics UA')) f.add_control(control(self.section, 'file', 'FAVICON_ICO', label='favicon.ico')) f.add_control(textareacontrol(self.section, 'ROBOTS_TXT', self.ROBOTS_TXT, 'robots.txt', 90, 5)) f.add_control(checkboxcontrol(self.section, 'ENABLE_THEME_PREVIEW', self.ENABLE_THEME_PREVIEW, 'Enable theme preview')) f.add_control(checkboxcontrol(self.section, 'DEBUG_MODE', self.DEBUG_MODE, 'Debug mode')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Edit configuration</h2>%s' % unicode(f)
def action_delete(self): rank = int(self.section.path_params[0]) item = content.get( self.content_types[rank], self.content_paths[rank] if self.content_paths[rank] else None, self.content_namespaces[rank]) is_original_content = item and item.container_namespace == self.namespace and item.section_path == self.section_path and self.content_namespaces.count( item.namespace) == 1 if item: item = item.init(self.section) if self.section.handler.request.get('submit'): if is_original_content: item.remove() self.content_types.pop(rank) self.content_paths.pop(rank) self.content_namespaces.pop(rank) self.content_views.pop(rank) self.update() raise Exception('Redirect', self.section.action_redirect_path) if is_original_content: message = '<div class="status warning">Are you sure you wish to delete content "%s" and all associated data?</div>' % self.content_namespaces[ rank] else: message = '<div class="status warning">Are you sure you wish to delete this view for content "%s"?</div>' % self.content_namespaces[ rank] f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<h2>Delete content</h2>%s%s' % (message, unicode(f))
def action_edit(self): if self.section.handler.request.get('submit'): self.SITE_HEADER = self.section.handler.request.get('SITE_HEADER') self.SITE_SUB_HEADER = self.section.handler.request.get( 'SITE_SUB_HEADER') self.DEFAULT_THEME = self.section.handler.request.get( 'DEFAULT_THEME') self.GOOGLE_ANALYTICS_UA = self.section.handler.request.get( 'GOOGLE_ANALYTICS_UA') self.ROBOTS_TXT = self.section.handler.request.get('ROBOTS_TXT') if self.section.handler.request.get('FAVICON_ICO'): if self.FAVICON_ICO: BlobInfo.get(self.FAVICON_ICO).delete() data = self.section.handler.request.get('FAVICON_ICO') handle = files.blobstore.create( mime_type='image/x-icon', _blobinfo_uploaded_filename='favicon.ico') with files.open(handle, 'a') as f: f.write(data) files.finalize(handle) self.FAVICON_ICO = files.blobstore.get_blob_key(handle) self.ENABLE_THEME_PREVIEW = self.section.handler.request.get( 'ENABLE_THEME_PREVIEW') != '' self.DEBUG_MODE = self.section.handler.request.get( 'DEBUG_MODE') != '' cache.delete(CACHE_KEY) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control( control(self.section, 'text', 'SITE_HEADER', self.SITE_HEADER, 'Site header', 50)) f.add_control( control(self.section, 'text', 'SITE_SUB_HEADER', self.SITE_SUB_HEADER, 'Site sub-header', 50)) combined_themes = get_local_theme_namespaces( ) + get_custom_theme_namespaces() f.add_control( selectcontrol( self.section, 'DEFAULT_THEME', combined_themes, self.DEFAULT_THEME if self.DEFAULT_THEME else DEFAULT_LOCAL_THEME_TEMPLATE, 'Default theme')) f.add_control( control(self.section, 'text', 'GOOGLE_ANALYTICS_UA', self.GOOGLE_ANALYTICS_UA, 'Google analytics UA')) f.add_control( control(self.section, 'file', 'FAVICON_ICO', label='favicon.ico')) f.add_control( textareacontrol(self.section, 'ROBOTS_TXT', self.ROBOTS_TXT, 'robots.txt', 90, 5)) f.add_control( checkboxcontrol(self.section, 'ENABLE_THEME_PREVIEW', self.ENABLE_THEME_PREVIEW, 'Enable theme preview')) f.add_control( checkboxcontrol(self.section, 'DEBUG_MODE', self.DEBUG_MODE, 'Debug mode')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Edit configuration</h2>%s' % unicode(f)
def action_delete(self): if self.section.handler.request.get('submit'): try: section.delete_section(self.section) except Exception as inst: return '<div class="status error">%s</div>' % unicode(inst[0]) else: raise Exception('Redirect', '/') f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Delete section "%s" and all containing original content?</div>%s' % (self.section.path, unicode(f))
def delete_text_resource(self, theme, filename, filenames, contents): if self.section.handler.request.get('submit'): index = filenames.index(filename) del filenames[index] del contents[index] theme.put() cache.flush_all() # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete "%s"?</div>%s' % (filename, unicode(f))
def action_delete(self): rank = int(self.section.path_params[0]) if self.section.path_params else 0 if rank > len(self.titles) - 1 or rank < 0: raise Exception("BadRequest", "Text item out of range") if self.section.handler.request.get("submit"): self.titles.pop(rank) self.bodies.pop(rank) self.update() raise Exception("Redirect", self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, "submit", "submit", "Confirm")) return '<div class="status warning">Are you sure you wish to delete item %d?</div>%s' % (rank + 1, unicode(f))
def delete_text_resource(self, theme, filename, filenames, contents): if self.section.handler.request.get('submit'): index = filenames.index(filename) del filenames[index] del contents[index] theme.put() cache.flush_all( ) # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete "%s"?</div>%s' % ( filename, unicode(f))
def action_delete(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): self.theme_keys.remove(str(theme.key())) self.theme_namespaces.remove(theme.namespace) theme.delete() self.update() cache.flush_all() # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete theme "%s" and all associated resources?</div>%s' % (theme.namespace, unicode(f))
def action_delete(self): rank = int( self.section.path_params[0]) if self.section.path_params else 0 if rank > len(self.titles) - 1 or rank < 0: raise Exception('BadRequest', 'Text item out of range') if self.section.handler.request.get('submit'): self.titles.pop(rank) self.bodies.pop(rank) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete item %d?</div>%s' % ( rank + 1, unicode(f))
def action_upload(self): message = '' if self.section.handler.request.get('submit'): try: self.import_compressed_theme_data(self.section.handler.request.get('data')) except Exception as inst: error = '<div class="status error">%s</div>' message = inst[0] if not isinstance(inst[0], types.ListType) else '<br>'.join(inst[0]) message = error % message else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Zip file')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Upload themes</h2>%s' % (message, unicode(f))
def action_browse(self): message = '' if self.section.handler.request.get('submit'): try: data = urllib2.urlopen(self.section.handler.request.get('url')).read() self.import_compressed_theme_data(data) except Exception as inst: error = '<div class="status error">%s</div>' message = inst[0] if not isinstance(inst[0], types.ListType) else '<br>'.join(inst[0]) message = error % message else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'url', '', 'URL', 80)) f.add_control(control(self.section, 'submit', 'submit', 'Install')) return message + template.snippet('themes-browse', { 'content': self, 'form': unicode(f) })
def edit_text_resource(self, theme, filename, filenames, contents, validate_body_template=False): if filename: index = filenames.index(filename) content = contents[index] else: index = len(filenames) if filenames else 0 content = '' message = '' if self.section.handler.request.get('submit'): new_filename = self.section.handler.request.get( 'filename').replace('/', '') content = self.section.handler.request.get('content') if not new_filename: message = '<div class="status error">Filename is required</div>' elif filename != new_filename and new_filename in filenames: message = '<div class="status error">Filename already exists</div>' else: try: if validate_body_template: content = validated_body_template(content) except Exception as inst: message = '<div class="status error">%s</div>' % inst[0] else: if filename: filenames[index] = new_filename contents[index] = content else: filenames.append(new_filename) contents.append(content) theme.put() cache.flush_all( ) # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control( control(self.section, 'text', 'filename', filename, 'Filename')) f.add_control( textareacontrol(self.section, 'content', content, 'Content', 90, 50)) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h1>Add</h1>%s' % (message, unicode(f))
def action_upload(self): message = '' if self.section.handler.request.get('submit'): try: self.import_compressed_theme_data( self.section.handler.request.get('data')) except Exception as inst: error = '<div class="status error">%s</div>' message = inst[0] if not isinstance( inst[0], types.ListType) else '<br>'.join(inst[0]) message = error % message else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Zip file')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Upload themes</h2>%s' % (message, unicode(f))
def action_add(self): ret = '<h2>Add file</h2>' if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST['data'].filename.replace(' ', '_') if not self.get_file(filename): content_type = self.section.handler.request.POST['data'].type data = db.Blob(self.section.handler.request.get('data')) key = File(filename=filename, data=data, content_type=content_type, section_path=self.section.path).put() self.file_keys.append(str(key)) self.filenames.append(filename) self.update() raise Exception('Redirect', self.section.action_redirect_path) ret += '<div class="status error">A file with the same name already exists for this section</div>' f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Data')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return ret + unicode(f)
def view_themes_previewer(self, params=None): if not configuration.theme_preview_enabled(): return '' combined_themes = get_local_theme_namespaces() + get_custom_theme_namespaces() if self.section.handler and self.section.handler.request.get('submit_themes_previewer'): selected_theme = self.section.handler.request.get('TEMPLATE_OVERRIDE_THEME') elif self.section.theme: selected_theme = self.section.theme else: selected_theme = configuration.default_theme() if not selected_theme: selected_theme = template.DEFAULT_LOCAL_THEME_TEMPLATE f = form(self.section, self.section.full_path) f.add_control(selectcontrol(self.section, 'TEMPLATE_OVERRIDE_THEME', combined_themes, selected_theme)) f.add_control(control(self.section, 'submit', 'submit_themes_previewer', 'Preview theme')) self.section.css.append('themes-previewer.css') return '<div class="content themes-previewer">%s</div>' % unicode(f)
def get_form(s, path, parent_path, name=None, title=None, keywords=None, description=None, theme=None, is_private=False, is_default=False, redirect_to=None, new_window=False): f = form(s, s.full_path) f.add_control(control(s, 'text', 'path', path, 'Path')) f.add_control(control(s, 'text', 'parent_path', parent_path if parent_path else '', 'Parent path')) f.add_control(control(s, 'text', 'name', name if name else '', 'Name', 30)) f.add_control(control(s, 'text', 'title', title if title else '', 'Title', 60)) f.add_control(textareacontrol(s, 'keywords', keywords if keywords else '', 'Keywords', 60, 5)) f.add_control(textareacontrol(s, 'description', description if description else '', 'Description', 60, 5)) combined_themes = get_local_theme_namespaces() + get_custom_theme_namespaces() default_theme = configuration.default_theme() if not default_theme: default_theme = template.DEFAULT_LOCAL_THEME_TEMPLATE f.add_control(selectcontrol(s, 'theme', combined_themes, theme if theme else default_theme, 'Theme')) f.add_control(checkboxcontrol(s, 'is_private', is_private, 'Is private')) if not is_default: f.add_control(checkboxcontrol(s, 'is_default', is_default, 'Is default')) f.add_control(control(s, 'text', 'redirect_to', redirect_to if redirect_to else '', 'Redirect to', 60)) f.add_control(checkboxcontrol(s, 'new_window', new_window, 'New window')) f.add_control(control(s, 'submit', 'submit')) return unicode(f)
def action_delete(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') filename = self.section.path_params[0] if self.section.handler.request.get('submit'): data = self.get_file(filename) if not data: raise Exception('NotFound') index = self.filenames.index(filename) cache.delete(CACHE_KEY_PREPEND + self.file_keys[index]) data.delete() del self.file_keys[index] del self.filenames[index] self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete file "%s" from "%s"?</div>%s' % (filename, self.section.path, unicode(f))
def action_add_image(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST['data'].filename content_type = self.section.handler.request.POST['data'].type data = db.Blob(self.section.handler.request.get('data')) key = File(filename=filename, data=data, content_type=content_type, section_path=self.section.path).put() theme.image_filenames.append(filename) theme.image_keys.append(str(key)) theme.put() cache.delete(CACHE_KEY_PREPEND + str(theme.key())) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Image')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Add image</h2>%s' % unicode(f)
def action_delete(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') filename = self.section.path_params[0] if self.section.handler.request.get('submit'): data = self.get_file(filename) if not data: raise Exception('NotFound') index = self.filenames.index(filename) cache.delete(CACHE_KEY_PREPEND + str(self.file_keys[index])) data.delete() del self.file_keys[index] del self.filenames[index] self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete file "%s" from "%s"?</div>%s' % ( filename, self.section.path, unicode(f))
def action_reorder(self): siblings = section.get_siblings(self.section.path) if not len(siblings) > 1: raise Exception('BadRequest') if self.section.handler.request.get('submit'): new_rank = int(self.section.handler.request.get('rank')) if self.section.rank != new_rank: section.update_section_rank(self.section, new_rank) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) items = [[0, 'At the top']] adder = 1 for item, _ in siblings: if self.section.rank != item['rank']: items.append([item['rank'] + adder, 'After ' + item['path']]) else: adder = 0 f.add_control(selectcontrol(self.section, 'rank', items, self.section.rank, 'Position')) f.add_control(control(self.section, 'submit', 'submit')) return '<h2>Reorder section "%s"</h2>%s' % (self.section.path, unicode(f))
def action_delete(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): for key in theme.image_keys: cache.delete(CACHE_KEY_PREPEND + str(key)) BlobInfo.get(key).delete() self.theme_keys.remove(theme.key) self.theme_namespaces.remove(theme.namespace) theme.key.delete() self.update() cache.flush_all( ) # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete theme "%s" and all associated resources?</div>%s' % ( theme.namespace, unicode(f))
def action_reorder(self): if not len(self.content_namespaces) > 1: raise Exception('BadRequest', 'Cannot reorder content without multiple content contained') rank = int(self.section.path_params[0]) if self.section.handler.request.get('submit'): new_rank = int(self.section.handler.request.get('new_rank')) self.content_types.insert(new_rank, self.content_types.pop(rank)) self.content_paths.insert(new_rank, self.content_paths.pop(rank)) self.content_namespaces.insert(new_rank, self.content_namespaces.pop(rank)) self.content_views.insert(new_rank, self.content_views.pop(rank)) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) ranks = [] for i in range(len(self.content_namespaces)): ranks.append([i, i]) f.add_control(selectcontrol(self.section, 'new_rank', ranks, rank, 'Rank')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Reorder content</h2>%s' % unicode(f)
def action_reorder(self): rank = int(self.section.path_params[0]) if self.section.path_params else 0 if rank > len(self.titles) - 1 or rank < 0: raise Exception('BadRequest', 'Text item out of range') if self.section.handler.request.get('submit'): new_rank = int(self.section.handler.request.get('new_rank')) if new_rank > len(self.titles) - 1 or rank < 0: raise Exception('BadRequest', 'Reorder rank out of range') self.titles.insert(new_rank, self.titles.pop(rank)) self.bodies.insert(new_rank, self.bodies.pop(rank)) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) ranks = [] for i in range(len(self.titles)): ranks.append([i, i]) f.add_control(selectcontrol(self.section, 'new_rank', ranks, rank, 'Rank')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Reorder text</h2>' + unicode(f)
def action_reorder(self): rank = int(self.section.path_params[0]) if self.section.path_params else 0 if rank > len(self.titles) - 1 or rank < 0: raise Exception("BadRequest", "Text item out of range") if self.section.handler.request.get("submit"): new_rank = int(self.section.handler.request.get("new_rank")) if new_rank > len(self.titles) - 1 or rank < 0: raise Exception("BadRequest", "Reorder rank out of range") self.titles.insert(new_rank, self.titles.pop(rank)) self.bodies.insert(new_rank, self.bodies.pop(rank)) self.update() raise Exception("Redirect", self.section.action_redirect_path) f = form(self.section, self.section.full_path) ranks = [] for i in range(len(self.titles)): ranks.append([i, i]) f.add_control(selectcontrol(self.section, "new_rank", ranks, rank, "Rank")) f.add_control(control(self.section, "submit", "submit", "Submit")) return "<h2>Reorder text</h2>" + unicode(f)
def action_add(self): message = '' if self.section.handler.request.get('submit'): namespace = self.section.handler.request.get('namespace').replace('/', '') if not namespace: message = '<div class="status error">Namespace is required</div>' elif namespace in self.theme_namespaces: message = '<div class="status error">Namespace "%s" already exists</div>' % namespace elif is_local_theme_namespace(namespace): message = '<div class="status error">Namespace "%s" is already a local theme namespace</div>' % namespace else: key = Theme(namespace=namespace).put() self.theme_keys.append(key) self.theme_namespaces.append(namespace) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'namespace', '', 'Namespace')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Add theme</h2>%s' % (message, unicode(f))
def action_add(self): ret = '<h2>Add file</h2>' if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST['data'].filename.replace(' ', '_') if not self.get_file(filename): content_type = self.section.handler.request.POST['data'].type data = self.section.handler.request.get('data') handle = files.blobstore.create(mime_type=content_type, _blobinfo_uploaded_filename=filename) with files.open(handle, 'a') as f: f.write(data) files.finalize(handle) key = files.blobstore.get_blob_key(handle) self.file_keys.append(key) self.filenames.append(filename) self.update() raise Exception('Redirect', self.section.action_redirect_path) ret += '<div class="status error">A file with the same name already exists for this section</div>' f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Data')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return ret + unicode(f)
def action_delete_image(self): if not self.section.path_params or len(self.section.path_params) != 2: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) filename = self.section.path_params[1] if filename not in theme.image_filenames: raise Exception('NotFound') if self.section.handler.request.get('submit'): index = theme.image_filenames.index(filename) data = BlobInfo.get(theme.image_keys[index]) cache.delete(CACHE_KEY_PREPEND + str(theme.image_keys[index])) data.delete() del theme.image_keys[index] del theme.image_filenames[index] theme.put() cache.delete(CACHE_KEY_PREPEND + str(theme.key)) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete "%s"?</div>%s' % (filename, unicode(f))
def action_reorder(self): rank = int( self.section.path_params[0]) if self.section.path_params else 0 if rank > len(self.titles) - 1 or rank < 0: raise Exception('BadRequest', 'Text item out of range') if self.section.handler.request.get('submit'): new_rank = int(self.section.handler.request.get('new_rank')) if new_rank > len(self.titles) - 1 or rank < 0: raise Exception('BadRequest', 'Reorder rank out of range') self.titles.insert(new_rank, self.titles.pop(rank)) self.bodies.insert(new_rank, self.bodies.pop(rank)) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) ranks = [] for i in range(len(self.titles)): ranks.append([i, i]) f.add_control( selectcontrol(self.section, 'new_rank', ranks, rank, 'Rank')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Reorder text</h2>' + unicode(f)
def action_delete_image(self): if not self.section.path_params or len(self.section.path_params) != 2: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) filename = self.section.path_params[1] if filename not in theme.image_filenames: raise Exception('NotFound') if self.section.handler.request.get('submit'): index = theme.image_filenames.index(filename) data = BlobInfo.get(theme.image_keys[index]) cache.delete(CACHE_KEY_PREPEND + str(theme.image_keys[index])) data.delete() del theme.image_keys[index] del theme.image_filenames[index] theme.put() cache.delete(CACHE_KEY_PREPEND + str(theme.key)) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<div class="status warning">Are you sure you wish to delete "%s"?</div>%s' % ( filename, unicode(f))
def action_browse(self): message = '' if self.section.handler.request.get('submit'): try: data = urllib2.urlopen( self.section.handler.request.get('url')).read() self.import_compressed_theme_data(data) except Exception as inst: error = '<div class="status error">%s</div>' message = inst[0] if not isinstance( inst[0], types.ListType) else '<br>'.join(inst[0]) message = error % message else: raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'url', '', 'URL', 80)) f.add_control(control(self.section, 'submit', 'submit', 'Install')) return message + template.snippet('themes-browse', { 'content': self, 'form': unicode(f) })
def action_add_image(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST['data'].filename content_type = self.section.handler.request.POST['data'].type data = self.section.handler.request.get('data') handle = files.blobstore.create(mime_type=content_type, _blobinfo_uploaded_filename=filename) with files.open(handle, 'a') as f: f.write(data) files.finalize(handle) key = files.blobstore.get_blob_key(handle) theme.image_filenames.append(filename) theme.image_keys.append(key) theme.put() cache.delete(CACHE_KEY_PREPEND + str(theme.key)) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Image')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Add image</h2>%s' % unicode(f)
def action_add(self): message = '' if self.section.handler.request.get('submit'): namespace = self.section.handler.request.get('namespace').replace( '/', '') if not namespace: message = '<div class="status error">Namespace is required</div>' elif namespace in self.theme_namespaces: message = '<div class="status error">Namespace "%s" already exists</div>' % namespace elif is_local_theme_namespace(namespace): message = '<div class="status error">Namespace "%s" is already a local theme namespace</div>' % namespace else: key = Theme(namespace=namespace).put() self.theme_keys.append(key) self.theme_namespaces.append(namespace) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control( control(self.section, 'text', 'namespace', '', 'Namespace')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h2>Add theme</h2>%s' % (message, unicode(f))
def action_delete(self): rank = int(self.section.path_params[0]) item = content.get(self.content_types[rank], self.content_paths[rank] if self.content_paths[rank] else None, self.content_namespaces[rank]) is_original_content = item and item.container_namespace == self.namespace and item.section_path == self.section_path and self.content_namespaces.count(item.namespace) == 1 if item: item = item.init(self.section) if self.section.handler.request.get('submit'): if is_original_content: item.remove() self.content_types.pop(rank) self.content_paths.pop(rank) self.content_namespaces.pop(rank) self.content_views.pop(rank) self.update() raise Exception('Redirect', self.section.action_redirect_path) if is_original_content: message = '<div class="status warning">Are you sure you wish to delete content "%s" and all associated data?</div>' % self.content_namespaces[rank] else: message = '<div class="status warning">Are you sure you wish to delete this view for content "%s"?</div>' % self.content_namespaces[rank] f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'submit', 'submit', 'Confirm')) return '<h2>Delete content</h2>%s%s' % (message, unicode(f))
def action_add_image(self): if not self.section.path_params or len(self.section.path_params) != 1: raise Exception('NotFound') theme = self.get_theme(self.section.path_params[0]) if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST['data'].filename content_type = self.section.handler.request.POST['data'].type data = self.section.handler.request.get('data') handle = files.blobstore.create( mime_type=content_type, _blobinfo_uploaded_filename=filename) with files.open(handle, 'a') as f: f.write(data) files.finalize(handle) key = files.blobstore.get_blob_key(handle) theme.image_filenames.append(filename) theme.image_keys.append(key) theme.put() cache.delete(CACHE_KEY_PREPEND + str(theme.key)) raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Image')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Add image</h2>%s' % unicode(f)
def action_reorder(self): if not len(self.content_namespaces) > 1: raise Exception( 'BadRequest', 'Cannot reorder content without multiple content contained') rank = int(self.section.path_params[0]) if self.section.handler.request.get('submit'): new_rank = int(self.section.handler.request.get('new_rank')) self.content_types.insert(new_rank, self.content_types.pop(rank)) self.content_paths.insert(new_rank, self.content_paths.pop(rank)) self.content_namespaces.insert(new_rank, self.content_namespaces.pop(rank)) self.content_views.insert(new_rank, self.content_views.pop(rank)) self.update() raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) ranks = [] for i in range(len(self.content_namespaces)): ranks.append([i, i]) f.add_control( selectcontrol(self.section, 'new_rank', ranks, rank, 'Rank')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '<h2>Reorder content</h2>%s' % unicode(f)
def edit_text_resource(self, theme, filename, filenames, contents, validate_body_template=False): if filename: index = filenames.index(filename) content = contents[index] else: index = len(filenames) if filenames else 0 content = '' message = '' if self.section.handler.request.get('submit'): new_filename = self.section.handler.request.get('filename').replace('/', '') content = self.section.handler.request.get('content') if not new_filename: message = '<div class="status error">Filename is required</div>' elif filename != new_filename and new_filename in filenames: message = '<div class="status error">Filename already exists</div>' else: try: if validate_body_template: content = validated_body_template(content) except Exception as inst: message = '<div class="status error">%s</div>' % inst[0] else: if filename: filenames[index] = new_filename contents[index] = content else: filenames.append(new_filename) contents.append(content) theme.put() cache.flush_all() # Flush all cached resources for this theme which is important for sections where it is active raise Exception('Redirect', self.section.action_redirect_path) f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'text', 'filename', filename, 'Filename')) f.add_control(textareacontrol(self.section, 'content', content, 'Content', 90, 50)) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return '%s<h1>Add</h1>%s' % (message, unicode(f))
def action_add(self): ret = '<h2>Add file</h2>' if self.section.handler.request.get('submit'): filename = self.section.handler.request.POST[ 'data'].filename.replace(' ', '_') if not self.get_file(filename): content_type = self.section.handler.request.POST['data'].type data = self.section.handler.request.get('data') handle = files.blobstore.create( mime_type=content_type, _blobinfo_uploaded_filename=filename) with files.open(handle, 'a') as f: f.write(data) files.finalize(handle) key = files.blobstore.get_blob_key(handle) self.file_keys.append(key) self.filenames.append(filename) self.update() raise Exception('Redirect', self.section.action_redirect_path) ret += '<div class="status error">A file with the same name already exists for this section</div>' f = form(self.section, self.section.full_path) f.add_control(control(self.section, 'file', 'data', label='Data')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) return ret + unicode(f)
def action_add(self): ret = '<h2>Add content</h2>' content_view = self.section.handler.request.get( 'content_view') if self.section.handler.request.get( 'content_view') else '' namespace = self.section.handler.request.get('namespace').replace( '/', '-').replace(' ', '-').replace('.', '-').lower( ) if self.section.handler.request.get('namespace') else '' if namespace: existing_content = content.get_by_namespace(namespace) existing_content_type = existing_content.__class__.__name__ if existing_content else None # TODO: Ensure that the below actually exist rank = int(self.section.path_params[0]) content_type, view = content_view.split('.') if self.section.handler.request.get('submit') and not content_view: ret += '<div class="status error">Content is required</div>' elif self.section.handler.request.get('submit') and not namespace: ret += '<div class="status error">Namespace is required</div>' elif self.section.handler.request.get( 'submit') and existing_content_type: if existing_content_type != content_type: ret += '<div class="status error">Selected namespace already exists for a different type of content</div>' else: if existing_content.section_path and not permission.is_admin( existing_content.section_path): ret += '<div class="status error">Selected namespace already exists for content that you are not permitted to manage</div>' elif self.section.handler.request.get('confirm'): self.content_types.insert( rank, existing_content.__class__.__name__) self.content_paths.insert( rank, existing_content.section_path if existing_content.section_path else '') self.content_namespaces.insert(rank, namespace) self.content_views.insert(rank, view) self.update() ret += str(existing_content) raise Exception('Redirect', self.section.action_redirect_path) else: ret += '<div class="status progress">Selected namespace already exists, continue to add a view to this existing content</div>' f = form(self.section, self.section.full_path) f.add_control( control(self.section, 'hidden', 'content_view', content_view)) f.add_control( control(self.section, 'hidden', 'namespace', namespace)) f.add_control( control(self.section, 'hidden', 'confirm', '1')) f.add_control( control(self.section, 'submit', 'submit', 'Confirm')) ret += unicode(f) return ret elif self.section.handler.request.get('submit'): content.get_else_create(self.section.path, content_type, namespace, self.namespace) self.content_types.insert(rank, content_type) self.content_paths.insert( rank, self.section_path if self.section_path else '') self.content_namespaces.insert(rank, namespace) self.content_views.insert(rank, view) self.update() raise Exception('Redirect', self.section.action_redirect_path) content_views = [['', '']] for content_type in content.get_all_content_types(): m = importlib.import_module('framework.content.' + content_type.lower()) views = [] for v in getattr(m, content_type.title())().views: if v[2]: views.append([content_type + '.' + v[0], v[1]]) if views: content_views.append([content_type, views]) f = form(self.section, self.section.full_path) f.add_control( selectcontrol(self.section, 'content_view', content_views, content_view, 'Content type')) f.add_control( control(self.section, 'text', 'namespace', namespace, 'Namespace')) f.add_control(control(self.section, 'submit', 'submit', 'Submit')) ret += unicode(f) return ret
def get_form(section, title, body): f = form(section, section.full_path) f.add_control(control(section, "text", "title", title, "Title", 60)) f.add_control(textareacontrol(section, "body", body, "Body", 100, 10, html=True)) f.add_control(control(section, "submit", "submit")) return unicode(f)
def get_form(section, title, body): f = form(section, section.full_path) f.add_control(control(section, 'text', 'title', title, 'Title', 60)) f.add_control(textareacontrol(section, 'body', body, 'Body', 100, 10, html=True)) f.add_control(control(section, 'submit', 'submit')) return unicode(f)