Source code for pyramid_pages.resources

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2015 uralbash <root@uralbash.ru>
#
# Distributed under terms of the MIT license.

"""
Base pages resources.
"""
import re

from pyramid.threadlocal import get_current_registry

from . import CONFIG_MODELS, CONFIG_DBSESSION
from .views import PageView


[docs]class BasePageResource(object): """ Base resource tree class for pages. :view: view of resource. :attr: The view machinery defaults to using the ``__call__`` method of the view callable (or the function itself, if the view callable is a function) to obtain a response. The attr value allows you to vary the method attribute used to obtain the response. For example, if your view was a class, and the class has a method named index and you wanted to use this method instead of the class's ``__call__`` method to return the response, you'd say attr="index" in the view configuration for the view. This is most useful when the view definition is a class. :template: template for view of resource. """ view = PageView attr = 'page_with_redirect' template = 'pyramid_pages/index.jinja2' def __init__(self, node, prefix=None, request=None, parent=None, *args, **kwargs): """ Make resource of node for traversal URL dispath. :node: instance of page :pages_config: config for pyramid_pages from your app :resources: list of all resources in config :prefix: URL prefix for current node :parent: if exist it assignet to ``__parent__`` attribute """ self.settings = get_current_registry().settings self.node = node self.dbsession = self.settings[CONFIG_DBSESSION] self.pages_config = self.settings[CONFIG_MODELS] self.resources = resources_of_config(self.pages_config) self.prefix = prefix or self.get_prefix() self.parent = parent
[docs] def get_prefix(self): """ Each resource defined in config for pages as dict. This method returns key from config where located current resource. """ for key, value in self.pages_config.items(): if not hasattr(value, '__iter__'): value = (value, ) for item in value: if type(self.node) == item\ or type(self.node) == getattr(item, 'model', None): return key
[docs] def resource_of_node(self, node, parent=None): return resource_of_node(self.resources, node)( node, parent=parent or self.parent)
@property def __name__(self): """ Returns ``slug`` attribute of node or ``prefix``. """ if self.node and not self.node.slug == '/': return self.node.slug elif self.node and self.node.slug == '/': return '' elif self.prefix: return self.prefix return None @property def name(self): return self.node.name @property def __parent__(self): if self.parent: return self.parent elif hasattr(self.node, 'parent'): parent = self.node.parent return resource_of_node(self.resources, parent)(parent) elif self.node: return self.__class__(None) return None def __getitem__(self, name): for child in self.children: if child.slug == name: return self.resource_of_node(child.node) @property def slug(self): return getattr(self.node, 'slug', None) @property def children(self): for child in self.node.children: yield self.resource_of_node(child) @property def children_qty(self): return len([child for child in self.children if child.node.visible and child.node.in_menu]) def __resource_url__(self, request, info): """ Some hook for prefix and duplication root slash. """ separator = '/{}'.format(self.prefix) if self.prefix else '' # XXX: I feel a dissonance here info['virtual_path'] = re.sub('/+', '/', info['virtual_path']) return info['app_url'] + separator + info['virtual_path'] def __repr__(self): return self.name
[docs]def resource_of_node(resources, node): """ Returns resource of node. """ for resource in resources: model = getattr(resource, 'model', None) if type(node) == model: return resource return BasePageResource
[docs]def resources_of_config(config): """ Returns all resources and models from config. """ return set( # unique values sum([ # join lists to flat list list(value) # if value is iter (ex: list of resources) if hasattr(value, '__iter__') else [value, ] # if value is not iter (ex: model or resource) for value in config.values() ], []) )
[docs]def models_of_config(config): """ Return list of models from all resources in config. """ resources = resources_of_config(config) models = [] for resource in resources: if not hasattr(resource, '__table__') and hasattr(resource, 'model'): models.append(resource.model) else: models.append(resource) return models