def generate_file(f, blog): ''' Returns the page text and the pathname for a file to generate. Used with build_file but can be used for other things as well. ''' if f.page is None: if f.xref.template.template_type == template_type.index: tags = template_tags(blog_id=blog.id) else: archive_pages = generate_archive_context_from_fileinfo( f.xref.archive_xref, blog.published_pages(), f) tags = template_tags(blog_id=blog.id, archive=archive_pages, archive_context=f) else: tags = template_tags(page_id=f.page.id) page_text = generate_page_text(f, tags) pathname = blog.path + "/" + f.file_path return (page_text, pathname)
def blog_create(site_id): user = auth.is_logged_in(request) site = Site.load(site_id) permission = auth.is_site_admin(user, site) new_blog = Blog( name="", description="", url="", path="") tags = template_tags(site_id=site.id, user=user) tags.blog = new_blog from core.libs import pytz themes = Theme.select() return template('ui/ui_blog_settings', section_title="Create new blog", # search_context=(search_context['sites'], None), menu=generate_menu('site_create_blog', site), nav_default='all', timezones=pytz.all_timezones, themes=themes, ** tags.__dict__ )
def media_edit(blog_id, media_id, status=None): ''' UI for editing a given media entry ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) is_member = auth.is_blog_member(user, blog) media = Media.load(media_id, blog) permission = auth.is_media_owner(user, media) from core.ui import kv kv_ui_data = kv.ui(media.kv_list()) tags = template_tags( blog=blog, media=media, status=status, user=user, ) tags.sidebar = sidebar.render_sidebar(panel_set='edit_media', status_badge=status_badge, kv_object='Media', kv_objectid=media.id, kv_ui=kv_ui_data) return media_edit_output(tags)
def page_media_upload(page_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) overwrite = [] for n in request.files: x = request.files.get(n) media_path = _join(page.blog.path, page.blog.media_path_generated) file_path = _join(media_path, x.filename) if _exists(file_path): from core.error import FileExistsError raise FileExistsError( "File '{}' already exists on the server.".format( utils.html_escape(x.filename))) else: Media.register_media(x.filename, file_path, user, page=page) if not _exists(media_path): makedirs(media_path) x.save(file_path) tags = template_tags(page=page) return template('edit/page_media_list.tpl', **tags.__dict__)
def delete_category(blog_id, category_id, confirm='N'): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_admin(user, blog) category = Category.load(category_id, blog_id=blog.id) auth.check_category_editing_lock(blog) tags = template_tags(blog=blog, user=user) from core.utils import Status if request.forms.getunicode('confirm') == user.logout_nonce: message = 'Category {} successfully deleted'.format(category.for_log) url = '{}/blog/{}/categories'.format(BASE_URL, blog.id) action = 'Return to the category listing' reparent_categories = Category.update( parent_category=category.parent_category).where( Category.parent_category == category) reparent_categories.execute() delete_category = PageCategory.delete().where( PageCategory.category == category.id) delete_category.execute() category.delete_instance() tags.status = Status(type='success', message=message, action=action, url=url, close=False) else: message = ( 'You are about to delete category <b>{}</b> from blog <b>{}</b>.'. format(category.for_display, blog.for_display)) yes = { 'label': 'Yes, delete this category', 'id': 'delete', 'name': 'confirm', 'value': user.logout_nonce } no = { 'label': 'No, return to category properties', 'url': '{}/blog/{}/category/{}'.format(BASE_URL, blog.id, category.id) } tags.status = Status(message=message, type='warning', close=False, yes=yes, no=no) tags.category = category return report(tags, 'blog_delete_category', category)
def build_indexes_fileinfos(templates): ''' Rebuilds a fileinfo entry for a given main index. This will need to be run every time we create a new index type, or change a mapping. (Most of these should have a 1:1 mapping) A control message should not be needed, since these are 1:1 This will port the code currently found in build_blog_fileinfo, much as the above function did. ''' n = 0 for template in templates: n += 1 index_mappings = TemplateMapping.select().where( TemplateMapping.template == template) blog = index_mappings[0].template.blog tags = template_tags(blog_id=blog.id) for i in index_mappings: path_string = tpl(tpl_oneline(i.path_string), **tags.__dict__) if path_string == '': continue master_path_string = path_string add_page_fileinfo(None, i, master_path_string, blog.url + "/" + master_path_string, blog.path + '/' + master_path_string) return n
def blog_publish(blog_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) queue_length = Queue.job_counts(blog=blog) if queue_length > 0: start_message = template('queue/queue_run_include', queue=Queue.jobs(blog), percentage_complete=0, blog=blog, break_path='{}/blog/{}/publish/break'.format( BASE_URL, blog.id)) Queue.start(blog, queue_length) else: start_message = "Queue empty." tags = template_tags(blog_id=blog.id, user=user) # return template( 'queue/queue_run_ui', start=queue_length, start_message=start_message, action_url="../../blog/{}/publish/progress/{}".format( blog.id, queue_length), title='Publishing queue progress', # search_context=(search_context['blog_queue'], blog), menu=generate_menu('blog_queue', blog), **tags.__dict__)
def media_edit(blog_id, media_id, status=None): ''' UI for editing a given media entry ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) is_member = auth.is_blog_member(user, blog) media = Media.load(media_id, blog) permission = auth.is_media_owner(user, media) from core.ui import kv kv_ui_data = kv.ui(media.kv_list()) tags = template_tags(blog=blog, media=media, status=status, user=user, ) tags.sidebar = sidebar.render_sidebar( panel_set='edit_media', status_badge=status_badge, kv_object='Media', kv_objectid=media.id, kv_ui=kv_ui_data) return media_edit_output(tags)
def main_ui(): ''' Top level UI This will eventually become a full-blown user dashboard. Right now it just returns a list of sites in the system. All users for the system can see this dashboard. ''' user = auth.is_logged_in(request) # TODO: replace with actual user-centric setting try: from settings import MAX_RECENT_PAGES except ImportError: MAX_RECENT_PAGES = 10 recent_pages = Page.select().where(Page.user == user).order_by( Page.modified_date.desc()).limit(MAX_RECENT_PAGES) your_blogs = user.blogs() tpl = template('ui/ui_dashboard', search_context=(search_contexts['sites'], None), menu=generate_menu('system_menu', None), recent_pages=recent_pages, your_blogs=your_blogs, **template_tags(user=user).__dict__) return tpl
def blog_delete_preview(blog_id, preview_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_admin(user, blog) f = lambda:None f.blog = blog if preview_id == 'all': previews_to_delete = blog.fileinfos.where(FileInfo.preview_path.is_null(False)) message = 'All previews for blog {} deleted.'.format(blog.for_display) f.msg = 'Delete all' else: previews_to_delete = blog.fileinfos.where(FileInfo.id == preview_id) message = 'Preview for fileinfo {} deleted.'.format(preview_id) f.msg = 'Delete preview {}'.format(preview_id) for n in previews_to_delete: if n.page is not None: n.page.delete_preview() else: n.template_mapping.template.delete_preview() tags = template_tags(blog_id=blog.id, user=user) from core.utils import Status tags.status = Status( type='success', message=message, close=False, ) return report(tags, 'blog_delete_preview', f)
def login_verify(): ''' Verifies user login, provides session cookie if successful ''' _forms = request.forms email = _forms.get('email') password = _forms.get('password') if login_verify_core(email, password) is True: if request.query.action: utils.safe_redirect(request.query.action) else: redirect(BASE_URL) else: tags = template_tags() tags.status = utils.Status( type='danger', no_sure=True, message="Email or password not found.") return template('ui/ui_login', **tags.__dict__)
def main_ui(): ''' Top level UI This will eventually become a full-blown user dashboard. Right now it just returns a list of sites in the system. All users for the system can see this dashboard. ''' user = auth.is_logged_in(request) # TODO: replace with actual user-centric setting try: from settings import MAX_RECENT_PAGES except ImportError: MAX_RECENT_PAGES = 10 recent_pages = Page.select().where( Page.user == user).order_by( Page.modified_date.desc()).limit(MAX_RECENT_PAGES) your_blogs = user.blogs() tpl = template('ui/ui_dashboard', search_context=(search_contexts['sites'], None), menu=generate_menu('system_menu', None), recent_pages=recent_pages, your_blogs=your_blogs, **template_tags(user=user).__dict__ ) return tpl
def blog_publish(blog_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) queue_length = Queue.job_counts(blog=blog) if queue_length > 0: start_message = template('queue/queue_run_include', queue=Queue.jobs(blog), percentage_complete=0, blog=blog, break_path='{}/blog/{}/publish/break'.format(BASE_URL, blog.id) ) Queue.start(blog, queue_length) else: start_message = "Queue empty." tags = template_tags(blog_id=blog.id, user=user) # return template('queue/queue_run_ui', start=queue_length, start_message=start_message, action_url="../../blog/{}/publish/progress/{}".format(blog.id, queue_length), title='Publishing queue progress', # search_context=(search_context['blog_queue'], blog), menu=generate_menu('blog_queue', blog), **tags.__dict__)
def page_media_upload(page_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) overwrite = [] for n in request.files: x = request.files.get(n) media_path = _join(page.blog.path, page.blog.media_path_generated) file_path = _join(media_path, x.filename) if _exists(file_path): from core.error import FileExistsError raise FileExistsError("File '{}' already exists on the server.".format( utils.html_escape(x.filename))) else: Media.register_media(x.filename, file_path, user, page=page) if not _exists(media_path): makedirs(media_path) x.save(file_path) tags = template_tags(page=page) return template('edit/page_media_list.tpl', **tags.__dict__)
def build_pages_fileinfos(pages): ''' Creates fileinfo entries for the template mappings associated with an iterable list of Page objects. ''' n = 0 for page in pages: n += 1 template_mappings = page.template_mappings if template_mappings.count() == 0: raise TemplateMapping.DoesNotExist( 'No template mappings found for this page.') tags = template_tags(page_id=page.id) for t in template_mappings: path_string = generate_date_mapping(page.publication_date.date(), tags, t.path_string) if path_string == '': continue master_path_string = path_string + "." + page.blog.base_extension add_page_fileinfo(page, t, master_path_string, page.blog.url + "/" + master_path_string, page.blog.path + '/' + master_path_string, str(page.publication_date)) return n
def media_edit_save(blog_id, media_id): ''' Save changes to a media entry. ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) is_member = auth.is_blog_member(user, blog) media = Media.load(media_id) permission = auth.is_media_owner(user, media) friendly_name = request.forms.getunicode('media_friendly_name') changes = False if friendly_name != media.friendly_name: changes = True media.friendly_name = friendly_name import datetime if changes is True: media.modified_date = datetime.datetime.utcnow() media.save() status = utils.Status( type='success', message='Changes to media <b>{}</b> saved successfully.'.format( media.for_display) ) else: status = utils.Status( type='warning', no_sure=True, message='No discernible changes submitted for media <b>{}</b>.'.format( media.id, media.for_display) ) logger.info("Media {} edited by user {}.".format( media.for_log, user.for_log)) from core.ui import kv kv_ui_data = kv.ui(media.kv_list()) tags = template_tags(blog=blog, media=media, status=status, user=user) tags.sidebar = sidebar.render_sidebar( panel_set='edit_media', status_badge=status_badge, kv_object='Media', kv_objectid=media.id, kv_ui=kv_ui_data) return media_edit_output(tags)
def blog_new_page(blog_id): ''' Displays UI for newly created (unsaved) page ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_member(user, blog) tags = template_tags(blog=blog, user=user) tags.page = Page() referer = request.headers.get('Referer') if referer is None: referer = BASE_URL + "/blog/" + str(blog.id) blog_new_page = tags.page for n in new_page_submission_fields: blog_new_page.__setattr__(n, "") if n in request.query: blog_new_page.__setattr__(n, request.query.getunicode(n)) import datetime blog_new_page.blog = blog blog_new_page.user = user blog_new_page.publication_date = datetime.datetime.utcnow() blog_new_page.basename = '' from core.cms import save_action_list from core.ui import kv kv_ui_data = kv.ui(blog_new_page.kv_list()) try: html_editor_settings = Template.get( Template.blog == blog, Template.title == 'HTML Editor Init', Template.template_type == template_type.system).body except Template.DoesNotExist: from core.static import html_editor_settings return template( 'edit/page', menu=generate_menu('create_page', blog), parent_path=referer, # search_context=(search_context['blog'], blog), html_editor_settings=html_editor_settings, sidebar=sidebar.render_sidebar(panel_set='edit_page', status_badge=status_badge, save_action=save_action, save_action_list=save_action_list, kv_ui=kv_ui_data, kv_object='Page', kv_objectid=None, **tags.__dict__), **tags.__dict__)
def build_archives_fileinfos(pages): ''' Takes a page (maybe a collection of same) and produces fileinfos for the date-based archive entries for each ''' counter = 0 mapping_list = {} for page in pages: tags = template_tags(page_id=page.id) if page.archive_mappings.count() == 0: raise TemplateMapping.DoesNotExist( 'No template mappings found for the archives for this page.') for m in page.archive_mappings: path_string = generate_date_mapping(page.publication_date, tags, m.path_string) if path_string == '': continue if path_string in mapping_list: continue # tag_context = generate_archive_context_from_page(m.archive_xref, page.blog, page) mapping_list[path_string] = (( None, m, path_string, page.blog.url + "/" + path_string, page.blog.path + '/' + path_string, ), (page)) for n in mapping_list: counter += 1 new_fileinfo = add_page_fileinfo(*mapping_list[n][0]) archive_context = [] m = mapping_list[n][0][1] for r in m.archive_xref: archive_context.append(archive_functions[r]["format"]( archive_functions[r]["mapping"](mapping_list[n][1]))) for t, r in zip(archive_context, m.archive_xref): new_fileinfo_context = FileInfoContext.get_or_create( fileinfo=new_fileinfo, object=r, ref=t) new_fileinfo.mapping_sort = archive_context new_fileinfo.save() # @return mapping_list return counter
def new_category(blog_id): from core.models import db with db.atomic() as txn: user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_editor(user, blog) category_list = [n for n in blog.categories] category = Category(id=0, title='', blog=blog) top_level_category = Category( id=None, title='[Top-level category]', parent=None ) category_list.insert(0, top_level_category) tags = template_tags( blog=blog, user=user) if request.method == "POST": with db.atomic() as txn: category_title = request.forms.getunicode('category_title') try: parent_category = int(request.forms.getunicode('category_parent')) except ValueError: parent_category = None with db.atomic() as txn: category = Category(blog=blog, title=category_title, parent_category=parent_category ) category.save() redirect('{}/blog/{}/category/{}'.format( BASE_URL, blog.id, category.id)) tpl = template('edit/category', category=category, category_list=category_list, menu=generate_menu('blog_new_category', category), search_context=(search_contexts['sites'], None), **tags.__dict__) return tpl
def login(): ''' User login interface ''' tpl = template('ui/ui_login', **template_tags().__dict__) logger.info("Login page requested from IP {}.".format(request.remote_addr)) response.delete_cookie("login", path="/") return tpl
def generate_page_tags(f, blog): ''' Returns the page text and the pathname for a file to generate. Used with build_file but can be used for other things as well. :param f: The fileinfo object to use. :param blog: The blog object to use as the context for the fileinfo. ''' if f.page is None: if f.xref.template.template_type == template_type.index: tags = template_tags(blog=blog, template=f.xref.template, fileinfo=f) else: archive_pages = generate_archive_context_from_fileinfo( f.xref.archive_xref, blog.pages.published, f) # The context object we use tags = template_tags(blog=blog, template=f.xref.template, archive=archive_pages, archive_context=f, fileinfo=f) else: tags = template_tags(page=f.page, template=f.xref.template, fileinfo=f) if tags.archive is not None: if tags.archive.pages.count() == 0: raise NoArchiveForFileInfo('No archives for page {} using fileinfo {}'.format( f.page, f)) return tags
def page_edit(page_id): ''' UI for editing a page in a blog ''' user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) status = None referer = request.headers.get('Referer') if (referer is None or page.modified_date is None or re.match(re.escape(BASE_URL + "/blog/" + str(page.blog.id)), referer) is None): referer = BASE_URL + "/blog/" + str(page.blog.id) if page.modified_date is None: status = utils.Status( type='info', message="Page <b>{}</b> created.".format(page.for_log)) page.modified_date = datetime.datetime.utcnow() page.save(user) tags = template_tags(page=page, user=user, status=status) from core.ui import kv kv_ui_data = kv.ui(page.kv_list()) tpl = template('edit/page', menu=generate_menu('edit_page', page), parent_path=referer, # search_context=(search_context['blog'], page.blog), html_editor_settings=html_editor_settings(page.blog), sidebar=sidebar.render_sidebar( panel_set='edit_page', status_badge=status_badge, save_action_list=save_action_list, save_action=save_action, kv_ui=kv_ui_data, kv_object='Page', kv_objectid=page.id, **tags.__dict__), msg_float=False, **tags.__dict__) logger.info("Page {} opened for editing by {}.".format( page.for_log, user.for_log)) return tpl
def blog_apply_theme(blog_id, theme_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) reason = auth.check_template_lock(blog) theme = Theme.load(theme_id) tags = template_tags(blog=blog, user=user) from core.utils import Status if request.forms.getunicode('confirm') == user.logout_nonce: from core.models import db with db.atomic() as txn: blog.apply_theme(theme, user) status = Status( type='success', close=False, message=''' Theme <b>{}</b> was successfully applied to blog <b>{}</b>.</p> It is recommended that you <a href="{}">republish this blog.</a> '''.format(theme.for_display, blog.for_display, '{}/blog/{}/republish'.format( BASE_URL, blog.id)) ) else: status = Status( type='warning', close=False, message=''' You are about to apply theme <b>{}</b> to blog <b>{}</b>.</p> <p>This will OVERWRITE AND REMOVE ALL EXISTING TEMPLATES on this blog!</p> '''.format(theme.for_display, blog.for_display), url='{}/blog/{}/themes'.format( BASE_URL, blog.id), yes={'id':'delete', 'name':'confirm', 'label':'Yes, I want to apply this theme', 'value':user.logout_nonce}, no={'label':'No, don\'t apply this theme', 'url':'{}/blog/{}/themes'.format( BASE_URL, blog.id)} ) tags.status = status if reason is None else reason return report(tags, 'blog_apply_theme', [blog, theme])
def blog_settings(blog_id, nav_setting): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_admin(user, blog) auth.check_settings_lock(blog) tags = template_tags(blog_id=blog.id, user=user) tags.nav_default = nav_setting return blog_settings_output(tags)
def media_edit_save(blog_id, media_id): ''' Save changes to a media entry. ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) is_member = auth.is_blog_member(user, blog) media = Media.load(media_id) permission = auth.is_media_owner(user, media) friendly_name = request.forms.getunicode('media_friendly_name') changes = False if friendly_name != media.friendly_name: changes = True media.friendly_name = friendly_name import datetime if changes is True: media.modified_date = datetime.datetime.utcnow() media.save() status = utils.Status( type='success', message='Changes to media <b>{}</b> saved successfully.'.format( media.for_display)) else: status = utils.Status( type='warning', no_sure=True, message='No discernible changes submitted for media <b>{}</b>.'. format(media.id, media.for_display)) logger.info("Media {} edited by user {}.".format(media.for_log, user.for_log)) from core.ui import kv kv_ui_data = kv.ui(media.kv_list()) tags = template_tags(blog=blog, media=media, status=status, user=user) tags.sidebar = sidebar.render_sidebar(panel_set='edit_media', status_badge=status_badge, kv_object='Media', kv_objectid=media.id, kv_ui=kv_ui_data) return media_edit_output(tags)
def plugin_settings(plugin_id, errormsg=None): user = auth.is_logged_in(request) permission = auth.is_sys_admin(user) plugin = Plugin.get(Plugin.id == plugin_id) tags = template_tags(user=user) tpl = template('system/plugin', plugin_ui=plugin.ui(), search_context=(search_contexts['sites'], None), menu=generate_menu('system_plugin_data', plugin), **tags.__dict__) return tpl
def blog_apply_theme(blog_id, theme_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) reason = auth.check_template_lock(blog) theme = Theme.load(theme_id) tags = template_tags(blog=blog, user=user) from core.utils import Status if request.forms.getunicode('confirm') == user.logout_nonce: from core.models import db with db.atomic() as txn: blog.apply_theme(theme, user) status = Status(type='success', close=False, message=''' Theme <b>{}</b> was successfully applied to blog <b>{}</b>.</p> It is recommended that you <a href="{}">republish this blog.</a> '''.format(theme.for_display, blog.for_display, '{}/blog/{}/republish'.format(BASE_URL, blog.id))) else: status = Status(type='warning', close=False, message=''' You are about to apply theme <b>{}</b> to blog <b>{}</b>.</p> <p>This will OVERWRITE AND REMOVE ALL EXISTING TEMPLATES on this blog!</p> '''.format(theme.for_display, blog.for_display), url='{}/blog/{}/themes'.format(BASE_URL, blog.id), yes={ 'id': 'delete', 'name': 'confirm', 'label': 'Yes, I want to apply this theme', 'value': user.logout_nonce }, no={ 'label': 'No, don\'t apply this theme', 'url': '{}/blog/{}/themes'.format(BASE_URL, blog.id) }) tags.status = status if reason is None else reason return report(tags, 'blog_apply_theme', [blog, theme])
def page_edit(page_id): ''' UI for editing a page in a blog ''' user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) status = None referer = request.headers.get('Referer') if (referer is None or page.modified_date is None or re.match(re.escape(BASE_URL + "/blog/" + str(page.blog.id)), referer) is None): referer = BASE_URL + "/blog/" + str(page.blog.id) if page.modified_date is None: status = utils.Status(type='info', message="Page <b>{}</b> created.".format( page.for_log)) page.modified_date = datetime.datetime.utcnow() page.save(user) tags = template_tags(page=page, user=user, status=status) from core.ui import kv kv_ui_data = kv.ui(page.kv_list()) tpl = template( 'edit/page', menu=generate_menu('edit_page', page), parent_path=referer, # search_context=(search_context['blog'], page.blog), html_editor_settings=html_editor_settings(page.blog), sidebar=sidebar.render_sidebar(panel_set='edit_page', status_badge=status_badge, save_action_list=save_action_list, save_action=save_action, kv_ui=kv_ui_data, kv_object='Page', kv_objectid=page.id, **tags.__dict__), msg_float=False, **tags.__dict__) logger.info("Page {} opened for editing by {}.".format( page.for_log, user.for_log)) return tpl
def page_media_delete(page_id, media_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) media = Media.load(media_id) media_reference = MediaAssociation.get(MediaAssociation.page == page, MediaAssociation.media == media) media_reference.delete_instance(recursive=True, delete_nullable=True) tags = template_tags(page=page) return template('edit/page_media_list.tpl', **tags.__dict__)
def template_set_default(template_id): ''' UI for setting a given template as the default for an archive type ''' user = auth.is_logged_in(request) tpl = Template.load(template_id) blog = Blog.load(tpl.blog.id) permission = auth.is_blog_designer(user, blog) auth.check_template_lock(blog) tags = template_tags(template=tpl, user=user) from core.utils import Status import settings if request.forms.getunicode('confirm') == user.logout_nonce: # check for form submission # setting should be done by way of class object # theme? blog? template? # blog.set_default_archive_template(template,{archive_type.index...}) status = Status( type='success', close=False, message= 'Template <b>{}</b> was successfully refreshed from theme <b>{}</b>.' .format(tpl.for_display, tpl.theme.for_display), action='Return to template', url='{}/template/{}/edit'.format(settings.BASE_URL, tpl.id)) tags.status = status else: pass from core.models import archive_defaults return template('edit/template-set-default', icons=icons, search_context=(search_contexts['blog'], tags.blog), menu=generate_menu('blog_edit_template', tags.template), sidebar=sidebar.render_sidebar( panel_set='edit_template', publishing_mode=publishing_mode, types=template_type, **tags.__dict__), archive_defaults=archive_defaults, **tags.__dict__)
def template_delete(template_id): ''' UI for deleting a template ''' user = auth.is_logged_in(request) tpl = Template.load(template_id) blog = Blog.load(tpl.blog) permission = auth.is_blog_designer(user, blog) from core.utils import Status import settings tags = template_tags(template_id=tpl.id, user=user) if request.forms.getunicode('confirm') == user.logout_nonce: # _template.delete(tpl) tpl.delete_instance() status = Status(type='success', close=False, message='Template {} was successfully deleted.'.format( tpl.for_log), action='Return to template list', url='{}/blog/{}/templates'.format( settings.BASE_URL, blog.id)) else: status = Status( type='warning', close=False, message= 'You are attempting to delete template <b>{}</b> from blog <b>{}</b>.' .format(tpl.for_display, blog.for_display), no={ 'url': '{}/template/{}/edit'.format(settings.BASE_URL, tpl.id), 'label': 'No, I don\'t want to delete this template' }, yes={ 'id': 'delete', 'name': 'confirm', 'label': 'Yes, I want to delete this template', 'value': user.logout_nonce }) tags.status = status return report(tags, 'blog_delete_template', tpl)
def plugin_settings(plugin_id, errormsg=None): user = auth.is_logged_in(request) permission = auth.is_sys_admin(user) plugin = Plugin.get(Plugin.id == plugin_id) tags = template_tags( user=user) tpl = template('system/plugin', plugin_ui=plugin.ui(), search_context=(search_contexts['sites'], None), menu=generate_menu('system_plugin_data', plugin), **tags.__dict__) return tpl
def page_media_add(page_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) media_list = Media.select().where(Media.blog == page.blog) tags = template_tags(page=page, user=user) return template('modal/modal_images.tpl', media_list=media_list, title="Select media", buttons='', **tags.__dict__)
def new_category(blog_id): from core.models import db with db.atomic() as txn: user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_editor(user, blog) category_list = [n for n in blog.categories] category = Category(id=0, title='', blog=blog) top_level_category = Category(id=None, title='[Top-level category]', parent=None) category_list.insert(0, top_level_category) tags = template_tags(blog=blog, user=user) if request.method == "POST": with db.atomic() as txn: category_title = request.forms.getunicode('category_title') try: parent_category = int( request.forms.getunicode('category_parent')) except ValueError: parent_category = None with db.atomic() as txn: category = Category(blog=blog, title=category_title, parent_category=parent_category) category.save() redirect('{}/blog/{}/category/{}'.format(BASE_URL, blog.id, category.id)) tpl = template('edit/category', category=category, category_list=category_list, menu=generate_menu('blog_new_category', category), search_context=(search_contexts['sites'], None), **tags.__dict__) return tpl
def page_revisions(page_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) tags = template_tags(page=page) try: tpl = template('modal/modal_revisions', title='Revisions for page #{}'.format(page.id), buttons='', **tags.__dict__) except: raise return tpl
def system_theme_data(theme_id): user = auth.is_logged_in(request) permission = auth.is_sys_admin(user) from core.models import Theme theme = Theme.load(theme_id) tags = template_tags(user=user) tags.report = ['Theme title: {}'.format(theme.title), 'Theme description: {}'.format(theme.description), 'Theme directory: {}'.format(theme.json), '<hr>', '<a href="{}/download">Download an archive of this theme</a>'.format(theme.id) ] return report(tags, 'system_theme_data', theme)
def blog_queue(blog_id, status=None): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) tags = template_tags(blog_id=blog.id, user=user, status=status) return listing(request, blog, tags.queue, 'queue', 'blog_menu', user=user, tags_data={'blog': blog}, errormsg=tags.status)
def blog_queue(blog_id, status=None): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) tags = template_tags(blog_id=blog.id, user=user, status=status) return listing(request, blog, tags.queue, 'queue', 'blog_menu', user=user, tags_data={'blog':blog}, errormsg=tags.status )
def page_revision_restore(page_id, revision_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) page_revision = PageRevision.select().where(PageRevision.id == revision_id).get() status = utils.Status( type='success', message='Page <b>{}</b> has been restored from backup dated {}.'.format(page.for_log, page_revision.modified_date) ) tags = template_tags(page=page, user=user, status=status) page_revision.id = page.id tags.page = page_revision referer = BASE_URL + "/blog/" + str(page.blog.id) # from core.cms import save_action_list # from core.ui_kv import kv_ui from core.ui import kv kv_ui_data = kv.ui(page.kv_list()) # TODO: save action from this doesn't trigger queue run tpl = template('edit/page', status_badge=status_badge, save_action=save_action, menu=generate_menu('edit_page', page), search_context=(search_contexts['blog'], page.blog), html_editor_settings=html_editor_settings(page.blog), sidebar=sidebar.render_sidebar( panel_set='edit_page', status_badge=status_badge, save_action=save_action, save_action_list=save_action_list, kv_ui=kv_ui_data, kv_object='Page', kv_objectid=page.id, **tags.__dict__ ), **tags.__dict__) return tpl
def build_pages_fileinfos(pages, template_mappings=None): ''' Creates fileinfo entries for the template mappings associated with an iterable list of Page objects. :param pages: List of page objects to build fileinfos for. ''' fileinfos = [] for n, page in enumerate(pages): if template_mappings is None: mappings = page.template_mappings else: mappings = template_mappings if mappings.count() == 0: raise TemplateMapping.DoesNotExist('No template mappings found for this page.') tags = template_tags(page=page) for t in mappings: # path_string = replace_mapping_tags(t.path_string) path_string = generate_date_mapping( page.publication_date_tz.date(), tags, replace_mapping_tags(t.path_string)) # for tag archives, we need to return a list from the date mapping # in the event that we have a tag present that's an iterable like the tag list # e.g., for /%t/%Y, for a given page that has five tags # we return five values, one for each tag, along with the year if path_string == '' or path_string is None: continue # master_path_string = path_string fileinfos.append( add_page_fileinfo(page, t, path_string, page.blog.url + "/" + path_string, page.blog.path + '/' + path_string, str(page.publication_date_tz)) ) return fileinfos
def blog_purge(blog_id): ''' UI for purging/republishing an entire blog Eventually to be reworked ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) tags = template_tags(blog=blog, user=user) tags.report = cms.purge_blog(blog) return report(tags, 'blog_purge', blog)
def kv_response(object_name, object_type, object_identifier, object_id): # from core.ui_kv import kv_ui from core.ui import kv from core.models import template_tags tag_args = {} tag_args[object_identifier] = object_id tags = template_tags(**tag_args) kv_ui_data = kv.ui(tags.__dict__[object_type].kv_list()) tpl = template('sidebar/kv', kv_ui=kv_ui_data, kv_object=object_name, kv_objectid=object_id, **tags.__dict__) return tpl
def page_media_add(page_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) media_list = Media.select().where( Media.blog == page.blog) tags = template_tags(page=page, user=user) return template('modal/modal_images.tpl', media_list=media_list, title="Select media", buttons='', **tags.__dict__)
def page_media_delete(page_id, media_id): user = auth.is_logged_in(request) page = Page.load(page_id) permission = auth.is_page_editor(user, page) media = Media.load(media_id) media_reference = MediaAssociation.get( MediaAssociation.page == page, MediaAssociation.media == media) media_reference.delete_instance(recursive=True, delete_nullable=True) tags = template_tags(page=page) return template('edit/page_media_list.tpl', **tags.__dict__)
def system_theme_data(theme_id): user = auth.is_logged_in(request) permission = auth.is_sys_admin(user) from core.models import Theme theme = Theme.load(theme_id) tags = template_tags(user=user) tags.report = [ 'Theme title: {}'.format(theme.title), 'Theme description: {}'.format(theme.description), 'Theme directory: {}'.format(theme.json), '<hr>', '<a href="{}/download">Download an archive of this theme</a>'.format( theme.id) ] return report(tags, 'system_theme_data', theme)
def build_indexes_fileinfos(templates): ''' Rebuilds a fileinfo entry for a given main index. This will need to be run every time we create a new index type, or change a mapping. (Most of these should have a 1:1 mapping) A control message should not be needed, since these are 1:1 This will port the code currently found in build_blog_fileinfo, much as the above function did. :param templates: A list of templates, typically for main indexes, to rebuild fileinfo entries for. ''' for n, template in enumerate(templates): index_mappings = TemplateMapping.select().where( TemplateMapping.template == template) blog = index_mappings[0].template.blog tags = template_tags(blog_id=blog.id) for i in index_mappings: path_string = replace_mapping_tags(i.path_string) path_string = eval(path_string, tags.__dict__) if path_string == '' or path_string is None: continue # why are we doing this twice? # path_string = replace_mapping_tags(path_string) # raise Exception(path_string) master_path_string = path_string add_page_fileinfo(None, i, master_path_string, blog.url + "/" + master_path_string, blog.path + '/' + master_path_string) try: return n + 1 except Exception: return 0
def queue_page_archive_actions(page): ''' Pushes to the publishing queue all the page archives for a given page object. :param page: The page object whose archives will be pushed to the publishing queue. ''' #=========================================================================== # NOTE: I tried to speed this up by checking the list of fileinfos # related to mappings for the page (if any), and then pushing those # if they exist, but I haven't seen evidence it does anything tangible # for performance. # I need to double-check that old mappings are in fact invalidated # when they are changed. #=========================================================================== archive_templates = page.blog.archive_templates tags = template_tags(page=page) for n in archive_templates: try: if n.publishing_mode != publishing_mode.do_not_publish: fileinfo_mappings = FileInfo.select().where( FileInfo.page == page, FileInfo.template_mapping << n.mappings) if fileinfo_mappings.count() == 0: fileinfo_mappings = build_archives_fileinfos_by_mappings( n, (page, )) if len(fileinfo_mappings) == 0: logger.info( 'No archive fileinfos could be built for page {} with template {}' .format(page.for_log, n.for_log)) else: for fileinfo_mapping in fileinfo_mappings: Queue.push(job_type=job_type.archive, blog=page.blog, site=page.blog.site, priority=7, data_integer=fileinfo_mapping.id) except Exception as e: from core.error import QueueAddError raise QueueAddError( 'Archive template {} for page {} could not be queued: '.format( n, page.for_log, e))
def queue_page_archive_actions(page): ''' Pushes to the publishing queue all the page archives for a given page object. :param page: The page object whose archives will be pushed to the publishing queue. ''' #=========================================================================== # NOTE: I tried to speed this up by checking the list of fileinfos # related to mappings for the page (if any), and then pushing those # if they exist, but I haven't seen evidence it does anything tangible # for performance. # I need to double-check that old mappings are in fact invalidated # when they are changed. #=========================================================================== archive_templates = page.blog.archive_templates tags = template_tags(page=page) for n in archive_templates: try: if n.publishing_mode != publishing_mode.do_not_publish: fileinfo_mappings = FileInfo.select().where(FileInfo.page == page, FileInfo.template_mapping << n.mappings) if fileinfo_mappings.count() == 0: fileinfo_mappings=build_archives_fileinfos_by_mappings(n,(page,)) if len(fileinfo_mappings)==0: logger.info('No archive fileinfos could be built for page {} with template {}'.format( page.for_log, n.for_log)) else: for fileinfo_mapping in fileinfo_mappings: Queue.push(job_type=job_type.archive, blog=page.blog, site=page.blog.site, priority=7, data_integer=fileinfo_mapping.id) except Exception as e: from core.error import QueueAddError raise QueueAddError('Archive template {} for page {} could not be queued: '.format( n, page.for_log, e))
def generate_page_text(f, tags): ''' Generates the text for a given page based on its fileinfo and a given tagset. :param f: The fileinfo object to use. :param tags: The tagset to use. ''' tp = f.template_mapping.template try: tpx = Cache.template_cache[f.template_mapping.template.id] except KeyError: try: pre_tags = Cache.blog_tag_cache[tp.blog.id] except KeyError: pre_tags = template_tags(blog=tp.blog) Cache.blog_tag_cache[tp.blog.id] = pre_tags tpx = MetalTemplate(source=tp.body, tags=pre_tags.__dict__) Cache.template_cache[f.template_mapping.template.id] = tpx try: return tpx.render(**tags.__dict__) except Exception: import traceback, sys tb = sys.exc_info()[2] line_number = traceback.extract_tb(tb)[-1][1] - 1 raise PageTemplateError("Error in template '{}': {} ({}) at line {}".format( tp.for_log, sys.exc_info()[0], sys.exc_info()[1], line_number ))
def blog_create_user(blog_id): ''' Creates a user and gives it certain permissions within the context of a given blog ''' user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_admin(user, blog) tags = template_tags(blog_id=blog.id, user=user) edit_user = Struct() edit_user.name = "" edit_user.email = "" return template('edit/user_settings', section_title="Create new blog user", # search_context=(search_context['sites'], None), edit_user=edit_user, **tags.__dict__ )
def blog_break_queue(blog_id): user = auth.is_logged_in(request) blog = Blog.load(blog_id) permission = auth.is_blog_publisher(user, blog) Queue.stop(blog) tags = template_tags(blog=blog, user=user) return template('queue/queue_run_ui', start=None, action_url='', start_message=''' <p>Queue publishing stopped. Note that queued items are still in the queue, and may still be processed on the next queue run.</p> <p><a href="{}/blog/{}/queue/clear"><button class="btn">Clear the queue</button></a> to remove them entirely.</p> '''.format(BASE_URL, blog_id), title='Publishing queue progress', # search_context=(search_context['blog_queue'], blog), menu=generate_menu('blog_queue', blog), **tags.__dict__)
def system_info(): # alt. implementation, less boilerplate? # user, permission = auth.is_sys_admin() user = auth.is_logged_in(request) permission = auth.is_sys_admin(user) tags = template_tags( user=user) python_list = [] environ_list = [] settings_list = [] # Generate interpreter info import os data = os.environ.__dict__['_data'] for n in data: environ_list.append((n, data[n])) # List all settings variables import settings s_dict = settings.__dict__ for n in s_dict: if n is not '__builtins__': settings_list.append((n, s_dict[n])) # List all plugins tpl = template('ui/ui_system_info', menu=generate_menu('system_info', None), search_context=(search_contexts['sites'], None), environ_list=sorted(environ_list), settings_list=sorted(settings_list), **tags.__dict__) return tpl