Exemplo n.º 1
0
    def __init__(self,
                 app,
                 url_prefix="/admin",
                 title="flask-dashed",
                 main_dashboard=None,
                 endpoint='admin'):

        if not main_dashboard:
            from .dashboard import DefaultDashboard
            main_dashboard = DefaultDashboard

        self.blueprint = Blueprint(endpoint,
                                   __name__,
                                   static_folder='static',
                                   template_folder='templates')
        self.app = app
        self.url_prefix = url_prefix
        self.endpoint = endpoint
        self.title = title
        self.secure_functions = OrderedMultiDict()
        # Checks security for current path
        self.blueprint.before_request(
            lambda: self.check_path_security(request.path))

        self.app.register_blueprint(self.blueprint, url_prefix=url_prefix)
        self.root_nodes = []

        self._add_node(main_dashboard, '/', 'main-dashboard', 'dashboard')
        # Registers recursive_getattr filter
        self.app.jinja_env.filters['recursive_getattr'] = recursive_getattr
Exemplo n.º 2
0
 def __init__(self, app, url_prefix='/dashboard', title='dashboard', endpoint='dash'):
     self.app = app
     self.blueprint = Blueprint(endpoint,
                                __name__,
                                static_folder='static',
                                template_folder='templates',)
     self.url_prefix = url_prefix
     self.title = title
     self._register_model = OrderedMultiDict()
     self._panels = OrderedMultiDict()
Exemplo n.º 3
0
def test_ordered_multidict_encoding():
    """"Make sure URLs are properly encoded from OrderedMultiDicts"""
    d = OrderedMultiDict()
    d.add('foo', 1)
    d.add('foo', 2)
    d.add('foo', 3)
    d.add('bar', 0)
    d.add('foo', 4)
    assert url_encode(d) == 'foo=1&foo=2&foo=3&bar=0&foo=4'
Exemplo n.º 4
0
 def __new__(cls, *args, **kwargs):
     if not cls.model:
         raise Exception('ModelAdminModule must provide `model` attribute')
     if not cls.list_fields:
         cls.list_fields = OrderedMultiDict()
         for column in cls.model.__table__._columns:
             cls.list_fields[column.name] = {
                 'label': column.name,
                 'column': getattr(cls.model, column.name)
             }
     if not cls.form_class:
         cls.form_class = model_form(cls.model, cls.db_session)
     return super(ModelAdminModule, cls).__new__(cls, *args, **kwargs)
Exemplo n.º 5
0
class UserModule(ModelAdminModule):
    model = User
    db_session = db_session
    profile_alias = aliased(Profile)

    list_fields = OrderedMultiDict((
        ('id', {
            'label': 'id',
            'column': User.id
        }),
        ('username', {
            'label': 'username',
            'column': User.username
        }),
        ('profile.name', {
            'label': 'name',
            'column': profile_alias.name
        }),
        ('profile.location', {
            'label': 'location',
            'column': profile_alias.location
        }),
    ))

    list_title = 'user list'

    searchable_fields = ['username', 'profile.name', 'profile.location']

    order_by = ('id', 'desc')

    list_query_factory = model.query\
           .outerjoin(profile_alias, 'profile')\
           .options(contains_eager('profile', alias=profile_alias))\

    form_class = UserForm

    def create_object(self):
        user = self.model()
        user.profile = Profile()
        return user
Exemplo n.º 6
0
    def __init__(self, app, url_prefix="/admin", title="flask-dashed", main_dashboard=None, endpoint="admin"):

        if not main_dashboard:
            from dashboard import DefaultDashboard

            main_dashboard = DefaultDashboard

        self.blueprint = Blueprint(endpoint, __name__, static_folder="static", template_folder="templates")
        self.app = app
        self.url_prefix = url_prefix
        self.endpoint = endpoint
        self.title = title
        self.secure_functions = OrderedMultiDict()
        # Checks security for current path
        self.blueprint.before_request(lambda: self.check_path_security(request.path))

        self.app.register_blueprint(self.blueprint, url_prefix=url_prefix)
        self.root_nodes = []

        self._add_node(main_dashboard, "/", "main-dashboard", "dashboard")
        # Registers recursive_getattr filter
        self.app.jinja_env.filters["recursive_getattr"] = recursive_getattr
Exemplo n.º 7
0
    class BookModule(ModelAdminModule):
        """Sample module with explicit eager loaded query.
        """
        model = Book
        db_session = db.session
        author_alias = aliased(Author)

        list_fields = OrderedMultiDict((
            ('id', {
                'label': 'id',
                'column': Book.id
            }),
            ('title', {
                'label': 'book title',
                'column': Book.title
            }),
            ('year', {
                'label': 'year',
                'column': Book.year
            }),
            ('author.name', {
                'label': 'author name',
                'column': author_alias.name
            }),
        ))
        list_title = 'books list'

        searchable_fields = ['title', 'author.name']

        order_by = ('id', 'asc')

        list_query_factory = model.query\
               .outerjoin(author_alias, 'author')\
               .options(contains_eager('author', alias=author_alias))\

        form_class = BookForm
Exemplo n.º 8
0
def custom_form_factory(form, field_types=None, field_slugs=None,
                        excluded_field_types=None,
                        registration_fields=False):
    fields = (CustomField.query.filter_by(meeting_id=g.meeting.id)
              .order_by(CustomField.sort))

    if field_types:
        fields = fields.filter(CustomField.field_type.in_(field_types))

    if field_slugs:
        fields = fields.filter(CustomField.slug.in_(field_slugs))

    if excluded_field_types:
        fields = fields.filter(
            ~CustomField.field_type.in_(excluded_field_types))

    if registration_fields:
        fields = fields.for_registration()

    if getattr(form, 'CUSTOM_FIELDS_TYPE', None):
        fields = fields.filter_by(custom_field_type=form.CUSTOM_FIELDS_TYPE)

    form_attrs = {
        '_custom_fields': OrderedMultiDict({c.slug: c for c in fields}),
    }

    for f in fields:
        attrs = {'label': unicode(CustomFieldLabel(f.label)),
                 'validators': [],
                 'render_kw': {},
                 'description': f.hint}

        data = _CUSTOM_FIELDS_MAP[f.field_type.code]

        # overwrite data if _CUSTOM_FIELDS_MAP attribute is present on form
        form_fields_map = getattr(form, '_CUSTOM_FIELDS_MAP', None)
        if form_fields_map:
            try:
                data = form_fields_map[f.field_type.code]
            except KeyError:
                pass

        if f.required:
            attrs['validators'].append(DataRequired())
        attrs['validators'].extend(data.get('validators', []))

        if f.max_length:
            attrs['validators'].append(Length(max=f.max_length))

        if f.field_type.code == CustomField.SELECT:
            query = CustomFieldChoice.query.filter_by(custom_field=f)
            attrs['choices'] = [(unicode(c.value), __(c.value.english))
                                for c in query]
            if not f.required:
                attrs['choices'] = [('', '---')] + attrs['choices']
            if f.slug == 'title':
                attrs['choices'] = [choice for choice in attrs['choices']
                                    if choice[0] in app.config['TITLE_CHOICES']]
            attrs['coerce'] = unicode

        if f.field_type.code == CustomField.LANGUAGE:
            attrs['choices'] = [i for i in Participant.LANGUAGE_CHOICES
                                if i[0].lower() in app.config['TRANSLATIONS']]
            if not f.required:
                attrs['choices'] = [('', '---')] + attrs['choices']

            attrs['coerce'] = unicode

        if f.field_type.code == CustomField.CATEGORY:
            query = Category.get_categories_for_meeting(
                form.CUSTOM_FIELDS_TYPE)
            if registration_fields:
                query = query.filter_by(visible_on_registration_form=True)
            attrs['choices'] = [(c.id, c) for c in query]
            attrs['coerce'] = int

        if f.field_type.code in (CustomField.MULTI_CHECKBOX, CustomField.RADIO):
            query = CustomFieldChoice.query.filter_by(custom_field=f)
            attrs['choices'] = [(unicode(c.value), c.value) for c in query]
            attrs['coerce'] = unicode

        if f.field_type.code == CustomField.IMAGE and f.photo_size and f.photo_size.code:
            attrs['render_kw']["data-photoSize"] = f.photo_size.code
            for coord in ("x1", "y1", "x2", "y2"):
                form_attrs['%s_%s_' % (f.slug, coord)] = HiddenField(default=0)

        # set field to form
        # _set_rules_for_custom_fields(f, attrs)
        field = data['field'](**attrs)
        setattr(field, 'field_type', f.field_type.code)
        form_attrs[f.slug] = field

    form_attrs['rules'] = Rule.get_rules_for_fields(fields)
    return type(form)(form.__name__, (form,), form_attrs)
Exemplo n.º 9
0
class Dash(object):
    """docstring for Dash"""

    def __init__(self, app, url_prefix='/dashboard', title='dashboard', endpoint='dash'):
        self.app = app
        self.blueprint = Blueprint(endpoint,
                                   __name__,
                                   static_folder='static',
                                   template_folder='templates',)
        self.url_prefix = url_prefix
        self.title = title
        self._register_model = OrderedMultiDict()
        self._panels = OrderedMultiDict()

    def register_model(self, model, db_session, list_fields=None, model_class=DashModelView,):
        if not hasattr(model, '__modelclass__'):
            model = model_class(model, db_session,self.blueprint.name)

        if list_fields:
            model.list_fields = list_fields
        self._register_model[model] = model

    def register_panel(self, title, panel):
        panel = panel(self, title)
        self._panels[title] = panel



    def get_panels(self):
        return sorted(self._panels.values(), key=lambda x: x.title)




    def get_url_name(self,model,name):
        if self._register_model.has_key(model):
            model = self._register_model[model]
        return '%s.%s_%s' % (self.blueprint.name,model.model_name, name,)

    def index(self):
        return 'ss'

    def get_urls(self):
        return (
            ('/', self.index),
        )

    def register_jinja_filter(self):
        self.app.jinja_env.filters['get_field_attr'] = get_field_attr

    def register_blueprint(self, **kwargs):
        self.app.register_blueprint(
            self.blueprint, url_prefix=self.url_prefix, **kwargs)

    def configure_routes(self):
        for url, func in self.get_urls():
            self.blueprint.route(url, methods=['GET', 'POST'])(func)

        for model in self._register_model.values():
            model_name = model.model_name()
            for url, func in model.get_urls():
                full_url = '/%s%s' % (model_name.lower(), url)
                self.blueprint.add_url_rule(
                    full_url,
                    "%s_%s" % (model_name.lower(), func.__name__),
                    func,
                    methods=['GET', 'POST'],
                )

        for panel in self._panels.values():
            for url, func in panel.get_urls():
                full_url = '/%s%s' % (panel.title, url)
                self.blueprint.add_url_rule(
                    full_url,
                    "panel_%s_%s" % (panel.title, func.__name__),
                    func,
                )

    def setup(self):
        self.configure_routes()
        self.register_blueprint()
        self.register_jinja_filter()
Exemplo n.º 10
0
class Admin(object):
    """Class that provides a way to add admin interface to Flask applications.

    :param app: The Flask application
    :param url_prefix: The url prefix
    :param main_dashboard: The main dashboard object
    :param endpoint: The endpoint
    """
    def __init__(self, app, url_prefix="/admin", title="flask-dashed",
            main_dashboard=None, endpoint='admin'):

        if not main_dashboard:
            from dashboard import DefaultDashboard
            main_dashboard = DefaultDashboard

        self.blueprint = Blueprint(endpoint, __name__,
            static_folder='static', template_folder='templates')
        self.app = app
        self.url_prefix = url_prefix
        self.endpoint = endpoint
        self.title = title
        self.secure_functions = OrderedMultiDict()
        # Checks security for current path
        self.blueprint.before_request(
            lambda: self.check_path_security(request.path))

        self.app.register_blueprint(self.blueprint, url_prefix=url_prefix)
        self.root_nodes = []

        self._add_node(main_dashboard, '/', 'main-dashboard', 'dashboard')
        # Registers recursive_getattr filter
        self.app.jinja_env.filters['recursive_getattr'] = recursive_getattr

    def register_node(self, url_prefix, endpoint, short_title, title=None,
            parent=None, node_class=AdminNode):
        """Registers admin node.

        :param url_prefix: The url prefix
        :param endpoint: The endpoint
        :param short_title: The short title
        :param title: The long title
        :param parent: The parent node path
        :param node_class: The class for node objects
        """
        return self._add_node(node_class, url_prefix, endpoint, short_title,
            title=title, parent=parent)

    def register_module(self, module_class, url_prefix, endpoint, short_title,
            title=None, parent=None):
        """Registers new module to current admin.
        """
        return self._add_node(module_class, url_prefix, endpoint, short_title,
            title=title, parent=parent)

    def _add_node(self, node_class, url_prefix, endpoint, short_title,
        title=None, parent=None):
        """Registers new node object to current admin object.
        """
        title = short_title if not title else title
        if parent and not issubclass(parent.__class__, AdminNode):
            raise Exception('`parent` class must be AdminNode subclass')
        new_node = node_class(self, url_prefix, endpoint, short_title,
            title=title, parent=parent)
        if parent:
            parent.children.append(new_node)
        else:
            self.root_nodes.append(new_node)
        return new_node

    @property
    def main_dashboard(self):
        return self.root_nodes[0]

    def add_path_security(self, path, function, http_code=403):
        """Registers security function for given path.

        :param path: The endpoint to secure
        :param function: The security function
        :param http_code: The response http code
        """
        self.secure_functions.add(path, (function, http_code))

    def check_path_security(self, path):
        """Checks security for specific and path.

        :param path: The path to check
        """
        for key in self.secure_functions.iterkeys():
            if path.startswith("%s%s" % (self.url_prefix, key)):
                for function, http_code in self.secure_functions.getlist(key):
                    if not function():
                        return abort(http_code)
Exemplo n.º 11
0
 def __init__(self, *args, **kwargs):
     super(AdminModule, self).__init__(*args, **kwargs)
     self.rules = OrderedMultiDict()
     self._register_rules()
Exemplo n.º 12
0
class AdminModule(AdminNode):
    """Class that provides a way to create simple admin module.

    :param admin: The parent admin object
    :param url_prefix: The url prefix
    :param enpoint: The endpoint
    :param short_title: the short module title use on navigation
        & breadcrumbs
    :param title: The long title
    :param parent: The parent node
    """
    def __init__(self, *args, **kwargs):
        super(AdminModule, self).__init__(*args, **kwargs)
        self.rules = OrderedMultiDict()
        self._register_rules()

    def add_url_rule(self, rule, endpoint, view_func, **options):
        """Adds a routing rule to the application from relative endpoint.
        `view_class` is copied as we need to dynamically apply decorators.

        :param rule: The rule
        :param endpoint: The endpoint
        :param view_func: The view
        """
        class ViewClass(view_func.view_class):
            pass

        ViewClass.__name__ = "%s_%s" % (self.endpoint, endpoint)
        ViewClass.__module__ = view_func.__module__
        view_func.view_class = ViewClass
        full_endpoint = "%s.%s_%s" % (self.admin.endpoint,
            self.endpoint, endpoint)
        self.admin.app.add_url_rule("%s%s%s" % (self.admin.url_prefix,
            self.url_path, rule), full_endpoint, view_func, **options)
        self.rules.setlist(endpoint, [(rule, endpoint, view_func)])

    def _register_rules(self):
        """Registers all module rules after initialization.
        """
        if not hasattr(self, 'default_rules'):
            raise NotImplementedError('Admin module class must provide'
                + ' default_rules')
        for rule, endpoint, view_func in self.default_rules:
            self.add_url_rule(rule, endpoint, view_func)

    @property
    def url(self):
        """Returns first registered (main) rule as url.
        """
        try:
            return url_for("%s.%s_%s" % (self.admin.endpoint,
                self.endpoint, self.rules.lists()[0][0]))
                # Cause OrderedMultiDict.keys() doesn't preserve order...
        except IndexError:
            raise Exception('`AdminModule` must provide at list one rule.')

    def secure_endpoint(self, endpoint,  http_code=403):
        """Gives a way to secure specific url path.

        :param endpoint: The endpoint to protect
        :param http_code: The response http code when False
        """
        def decorator(f):
            self._secure_enpoint(endpoint, f, http_code)
            return f
        return decorator

    def _secure_enpoint(self, endpoint, secure_function, http_code):
        """Secure enpoint view function via `secure` decorator.

        :param enpoint: The endpoint to secure
        :param secure_function: The function to check
        :param http_code: The response http code when False.
        """
        rule, endpoint, view_func = self.rules.get(endpoint)
        view_func.view_class.dispatch_request =\
            secure(endpoint, secure_function, http_code)(
                view_func.view_class.dispatch_request)
Exemplo n.º 13
0
class Admin(object):
    """Class that provides a way to add admin interface to Flask applications.

    :param app: The Flask application
    :param url_prefix: The url prefix
    :param main_dashboard: The main dashboard object
    :param endpoint: The endpoint
    """
    def __init__(self, app, url_prefix="/admin", title="flask-dashed",
            main_dashboard=None, endpoint='admin'):

        if not main_dashboard:
            from dashboard import DefaultDashboard
            main_dashboard = DefaultDashboard

        self.blueprint = Blueprint(endpoint, __name__,
            static_folder='static', template_folder='templates')
        self.app = app
        self.url_prefix = url_prefix
        self.endpoint = endpoint
        self.title = title
        self.secure_functions = OrderedMultiDict()
        # Checks security for current path
        self.blueprint.before_request(
            lambda: self.check_path_security(request.path))

        self.app.register_blueprint(self.blueprint, url_prefix=url_prefix)
        self.root_nodes = []

        self._add_node(main_dashboard, '/', 'main-dashboard', 'dashboard')
        # Registers recursive_getattr filter
        self.app.jinja_env.filters['recursive_getattr'] = recursive_getattr

    def register_node(self, url_prefix, endpoint, short_title, title=None,
            parent=None, node_class=AdminNode):
        """Registers admin node.

        :param url_prefix: The url prefix
        :param endpoint: The endpoint
        :param short_title: The short title
        :param title: The long title
        :param parent: The parent node path
        :param node_class: The class for node objects
        """
        return self._add_node(node_class, url_prefix, endpoint, short_title,
            title=title, parent=parent)

    def register_module(self, module_class, url_prefix, endpoint, short_title,
            title=None, parent=None):
        """Registers new module to current admin.
        """
        return self._add_node(module_class, url_prefix, endpoint, short_title,
            title=title, parent=parent)

    def _add_node(self, node_class, url_prefix, endpoint, short_title,
        title=None, parent=None):
        """Registers new node object to current admin object.
        """
        title = short_title if not title else title
        if parent and not issubclass(parent.__class__, AdminNode):
            raise Exception('`parent` class must be AdminNode subclass')
        new_node = node_class(self, url_prefix, endpoint, short_title,
            title=title, parent=parent)
        if parent:
            parent.children.append(new_node)
        else:
            self.root_nodes.append(new_node)
        return new_node

    @property
    def main_dashboard(self):
        return self.root_nodes[0]

    def add_path_security(self, path, function, http_code=403):
        """Registers security function for given path.

        :param path: The endpoint to secure
        :param function: The security function
        :param http_code: The response http code
        """
        self.secure_functions.add(path, (function, http_code))

    def check_path_security(self, path):
        """Checks security for specific and path.

        :param path: The path to check
        """
        for key in self.secure_functions.iterkeys():
            if path.startswith("%s%s" % (self.url_prefix, key)):
                for function, http_code in self.secure_functions.getlist(key):
                    if not function():
                        return abort(http_code)
Exemplo n.º 14
0
 def __init__(self, *args, **kwargs):
     super(AdminModule, self).__init__(*args, **kwargs)
     self.rules = OrderedMultiDict()
     self._register_rules()
Exemplo n.º 15
0
class AdminModule(AdminNode):
    """Class that provides a way to create simple admin module.

    :param admin: The parent admin object
    :param url_prefix: The url prefix
    :param enpoint: The endpoint
    :param short_title: the short module title use on navigation
        & breadcrumbs
    :param title: The long title
    :param parent: The parent node
    """
    def __init__(self, *args, **kwargs):
        super(AdminModule, self).__init__(*args, **kwargs)
        self.rules = OrderedMultiDict()
        self._register_rules()

    def add_url_rule(self, rule, endpoint, view_func, **options):
        """Adds a routing rule to the application from relative endpoint.
        `view_class` is copied as we need to dynamically apply decorators.

        :param rule: The rule
        :param endpoint: The endpoint
        :param view_func: The view
        """
        class ViewClass(view_func.view_class):
            pass

        ViewClass.__name__ = "%s_%s" % (self.endpoint, endpoint)
        ViewClass.__module__ = view_func.__module__
        view_func.view_class = ViewClass
        full_endpoint = "%s.%s_%s" % (self.admin.endpoint,
            self.endpoint, endpoint)
        self.admin.app.add_url_rule("%s%s%s" % (self.admin.url_prefix,
            self.url_path, rule), full_endpoint, view_func, **options)
        self.rules.setlist(endpoint, [(rule, endpoint, view_func)])

    def _register_rules(self):
        """Registers all module rules after initialization.
        """
        if not hasattr(self, 'default_rules'):
            raise NotImplementedError('Admin module class must provide'
                + ' default_rules')
        for rule, endpoint, view_func in self.default_rules:
            self.add_url_rule(rule, endpoint, view_func)

    @property
    def url(self):
        """Returns first registered (main) rule as url.
        """
        try:
            return url_for("%s.%s_%s" % (self.admin.endpoint,
                self.endpoint, self.rules.lists()[0][0]))
                # Cause OrderedMultiDict.keys() doesn't preserve order...
        except IndexError:
            raise Exception('`AdminModule` must provide at list one rule.')

    def secure_endpoint(self, endpoint,  http_code=403):
        """Gives a way to secure specific url path.

        :param endpoint: The endpoint to protect
        :param http_code: The response http code when False
        """
        def decorator(f):
            self._secure_enpoint(endpoint, f, http_code)
            return f
        return decorator

    def _secure_enpoint(self, endpoint, secure_function, http_code):
        """Secure enpoint view function via `secure` decorator.

        :param enpoint: The endpoint to secure
        :param secure_function: The function to check
        :param http_code: The response http code when False.
        """
        rule, endpoint, view_func = self.rules.get(endpoint)
        view_func.view_class.dispatch_request =\
            secure(endpoint, secure_function, http_code)(
                view_func.view_class.dispatch_request)
Exemplo n.º 16
0
 def get_columns(self):
     columns = OrderedMultiDict()
     for column in self.model.__table__.columns:
         columns[column.name] = getattr(self.model, column.name)
     self.column_names = columns.keys()
     return columns