Compare commits
	
		
			4 commits
		
	
	
		
			15ba94fc83
			...
			601dec7777
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 601dec7777 | |||
| d265695cee | |||
| 7136240841 | |||
| a891c01da1 | 
					 23 changed files with 127 additions and 63 deletions
				
			
		| 
						 | 
				
			
			@ -36,8 +36,3 @@ disable=fixme,
 | 
			
		|||
        ungrouped-imports,
 | 
			
		||||
        unidiomatic-typecheck,
 | 
			
		||||
        unnecessary-comprehension,
 | 
			
		||||
        unnecessary-lambda,
 | 
			
		||||
        unnecessary-lambda-assignment,
 | 
			
		||||
        unspecified-encoding,
 | 
			
		||||
        unused-argument,
 | 
			
		||||
        use-a-generator,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ class WebAppProvider(AppProvider):
 | 
			
		|||
    email_modules = ["wuttaweb.emails"]
 | 
			
		||||
    email_templates = ["wuttaweb:email-templates"]
 | 
			
		||||
 | 
			
		||||
    def get_web_handler(self, **kwargs):
 | 
			
		||||
    def get_web_handler(self):
 | 
			
		||||
        """
 | 
			
		||||
        Get the configured "web" handler for the app.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ def make_pyramid_config(settings):
 | 
			
		|||
    return pyramid_config
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def main(global_config, **settings):
 | 
			
		||||
def main(global_config, **settings):  # pylint: disable=unused-argument
 | 
			
		||||
    """
 | 
			
		||||
    Make and return the WSGI application, per given settings.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,7 @@ class WuttaSecurityPolicy:
 | 
			
		|||
    def forget(self, request, **kw):
 | 
			
		||||
        return self.session_helper.forget(request, **kw)
 | 
			
		||||
 | 
			
		||||
    def permits(self, request, context, permission):
 | 
			
		||||
    def permits(self, request, context, permission):  # pylint: disable=unused-argument
 | 
			
		||||
 | 
			
		||||
        # nb. root user can do anything
 | 
			
		||||
        if getattr(request, "is_root", False):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ from wuttjamaican.cli import wutta_typer
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@wutta_typer.command()
 | 
			
		||||
def webapp(
 | 
			
		||||
def webapp(  # pylint: disable=unused-argument
 | 
			
		||||
    ctx: typer.Context,
 | 
			
		||||
    auto_reload: Annotated[
 | 
			
		||||
        bool,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -982,7 +982,7 @@ class Form:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        output = render(template, context)
 | 
			
		||||
        return HTML.literal(output)
 | 
			
		||||
 | 
			
		||||
    def render_vue_field(
 | 
			
		||||
    def render_vue_field(  # pylint: disable=unused-argument
 | 
			
		||||
        self,
 | 
			
		||||
        fieldname,
 | 
			
		||||
        readonly=None,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -352,7 +352,9 @@ class ObjectRef(colander.SchemaType):
 | 
			
		|||
        """
 | 
			
		||||
        return obj.uuid.hex
 | 
			
		||||
 | 
			
		||||
    def deserialize(self, node, cstruct):  # pylint: disable=empty-docstring
 | 
			
		||||
    def deserialize(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, node, cstruct
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        if not cstruct:
 | 
			
		||||
            return colander.null
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -438,7 +438,9 @@ class RoleRefsWidget(WuttaCheckboxChoiceWidget):
 | 
			
		|||
            kw["roles"] = roles
 | 
			
		||||
 | 
			
		||||
            # url
 | 
			
		||||
            url = lambda role: self.request.route_url("roles.view", uuid=role.uuid)
 | 
			
		||||
            def url(role):
 | 
			
		||||
                return self.request.route_url("roles.view", uuid=role.uuid)
 | 
			
		||||
 | 
			
		||||
            kw["url"] = url
 | 
			
		||||
 | 
			
		||||
        # default logic from here
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -835,7 +835,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        This will normalize the list/dict to desired internal format.
 | 
			
		||||
        """
 | 
			
		||||
        if tools and isinstance(tools, list):
 | 
			
		||||
            if not any([isinstance(t, (tuple, list)) for t in tools]):
 | 
			
		||||
            if not any(isinstance(t, (tuple, list)) for t in tools):
 | 
			
		||||
                tools = [(self.app.make_uuid(), t) for t in tools]
 | 
			
		||||
        self.tools = OrderedDict(tools or [])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1058,13 +1058,27 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
                    # TODO: may need this for String etc. as well?
 | 
			
		||||
                    if isinstance(model_property.type, sa.Text):
 | 
			
		||||
                        if foldcase:
 | 
			
		||||
                            kfunc = lambda obj: (obj[key] or "").lower()
 | 
			
		||||
 | 
			
		||||
                            def kfunc_folded(obj):
 | 
			
		||||
                                return (obj[key] or "").lower()
 | 
			
		||||
 | 
			
		||||
                            kfunc = kfunc_folded
 | 
			
		||||
 | 
			
		||||
                        else:
 | 
			
		||||
                            kfunc = lambda obj: obj[key] or ""
 | 
			
		||||
 | 
			
		||||
                            def kfunc_standard(obj):
 | 
			
		||||
                                return obj[key] or ""
 | 
			
		||||
 | 
			
		||||
                            kfunc = kfunc_standard
 | 
			
		||||
 | 
			
		||||
                if not kfunc:
 | 
			
		||||
                    # nb. sorting with this can raise error if data
 | 
			
		||||
                    # contains varying types, e.g. str and None
 | 
			
		||||
                    kfunc = lambda obj: obj[key]
 | 
			
		||||
 | 
			
		||||
                    def kfunc_fallback(obj):
 | 
			
		||||
                        return obj[key]
 | 
			
		||||
 | 
			
		||||
                    kfunc = kfunc_fallback
 | 
			
		||||
 | 
			
		||||
            # then sort the data and return
 | 
			
		||||
            return sorted(data, key=kfunc, reverse=direction == "desc")
 | 
			
		||||
| 
						 | 
				
			
			@ -1738,7 +1752,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
            raise ValueError(f"invalid dest identifier: {dest}")
 | 
			
		||||
 | 
			
		||||
        # func to save a setting value to user session
 | 
			
		||||
        def persist(key, value=lambda k: settings.get(k)):
 | 
			
		||||
        def persist(key, value=settings.get):
 | 
			
		||||
            assert dest == "session"
 | 
			
		||||
            skey = f"grid.{self.key}.{key}"
 | 
			
		||||
            self.request.session[skey] = value(key)
 | 
			
		||||
| 
						 | 
				
			
			@ -1932,7 +1946,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
    # rendering methods
 | 
			
		||||
    ##############################
 | 
			
		||||
 | 
			
		||||
    def render_batch_id(self, obj, key, value):
 | 
			
		||||
    def render_batch_id(self, obj, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for batch ID values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1946,7 +1960,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        batch_id = int(value)
 | 
			
		||||
        return f"{batch_id:08d}"
 | 
			
		||||
 | 
			
		||||
    def render_boolean(self, obj, key, value):
 | 
			
		||||
    def render_boolean(self, obj, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for boolean values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1961,7 +1975,9 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        """
 | 
			
		||||
        return self.app.render_boolean(value)
 | 
			
		||||
 | 
			
		||||
    def render_currency(self, obj, key, value, **kwargs):
 | 
			
		||||
    def render_currency(  # pylint: disable=unused-argument
 | 
			
		||||
        self, obj, key, value, **kwargs
 | 
			
		||||
    ):
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for currency values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1976,7 +1992,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        """
 | 
			
		||||
        return self.app.render_currency(value, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def render_date(self, obj, key, value):
 | 
			
		||||
    def render_date(self, obj, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for :class:`python:datetime.date` values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1992,7 +2008,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        dt = getattr(obj, key)
 | 
			
		||||
        return self.app.render_date(dt)
 | 
			
		||||
 | 
			
		||||
    def render_datetime(self, obj, key, value):
 | 
			
		||||
    def render_datetime(self, obj, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for :class:`python:datetime.datetime` values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2035,7 +2051,9 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
    def render_percent(self, obj, key, value, **kwargs):
 | 
			
		||||
    def render_percent(  # pylint: disable=unused-argument
 | 
			
		||||
        self, obj, key, value, **kwargs
 | 
			
		||||
    ):
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for percentage values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2049,7 +2067,7 @@ class Grid:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        """
 | 
			
		||||
        return self.app.render_percent(value, **kwargs)
 | 
			
		||||
 | 
			
		||||
    def render_quantity(self, obj, key, value):
 | 
			
		||||
    def render_quantity(self, obj, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Column renderer for quantity values.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -380,7 +380,7 @@ class GridFilter:  # pylint: disable=too-many-instance-attributes
 | 
			
		|||
        # invoke filter method
 | 
			
		||||
        return func(data, value)
 | 
			
		||||
 | 
			
		||||
    def filter_is_any(self, data, value):
 | 
			
		||||
    def filter_is_any(self, data, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        This is a no-op which always ignores the value and returns the
 | 
			
		||||
        data as-is.
 | 
			
		||||
| 
						 | 
				
			
			@ -487,13 +487,13 @@ class AlchemyFilter(GridFilter):
 | 
			
		|||
            return query
 | 
			
		||||
        return query.filter(self.model_property <= value)
 | 
			
		||||
 | 
			
		||||
    def filter_is_null(self, query, value):
 | 
			
		||||
    def filter_is_null(self, query, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Filter data with an ``IS NULL`` query.  The value is ignored.
 | 
			
		||||
        """
 | 
			
		||||
        return query.filter(self.model_property == None)
 | 
			
		||||
 | 
			
		||||
    def filter_is_not_null(self, query, value):
 | 
			
		||||
    def filter_is_not_null(self, query, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Filter data with an ``IS NOT NULL`` query.  The value is
 | 
			
		||||
        ignored.
 | 
			
		||||
| 
						 | 
				
			
			@ -623,21 +623,21 @@ class BooleanAlchemyFilter(AlchemyFilter):
 | 
			
		|||
            return bool(value)
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def filter_is_true(self, query, value):
 | 
			
		||||
    def filter_is_true(self, query, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Filter data with an "is true" condition.  The value is
 | 
			
		||||
        ignored.
 | 
			
		||||
        """
 | 
			
		||||
        return query.filter(self.model_property == True)
 | 
			
		||||
 | 
			
		||||
    def filter_is_false(self, query, value):
 | 
			
		||||
    def filter_is_false(self, query, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Filter data with an "is false" condition.  The value is
 | 
			
		||||
        ignored.
 | 
			
		||||
        """
 | 
			
		||||
        return query.filter(self.model_property == False)
 | 
			
		||||
 | 
			
		||||
    def filter_is_false_null(self, query, value):
 | 
			
		||||
    def filter_is_false_null(self, query, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Filter data with "is false or null" condition.  The value is
 | 
			
		||||
        ignored.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ class WebHandler(GenericHandler):
 | 
			
		|||
            return url
 | 
			
		||||
        return self.get_fanstatic_url(request, static.logo)
 | 
			
		||||
 | 
			
		||||
    def get_menu_handler(self, **kwargs):
 | 
			
		||||
    def get_menu_handler(self):
 | 
			
		||||
        """
 | 
			
		||||
        Get the configured :term:`menu handler` for the web app.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ class MenuHandler(GenericHandler):
 | 
			
		|||
    # default menu definitions
 | 
			
		||||
    ##############################
 | 
			
		||||
 | 
			
		||||
    def make_menus(self, request, **kwargs):
 | 
			
		||||
    def make_menus(self, request):
 | 
			
		||||
        """
 | 
			
		||||
        Generate the full set of menus for the app.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ class MenuHandler(GenericHandler):
 | 
			
		|||
            self.make_admin_menu(request),
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    def make_people_menu(self, request, **kwargs):
 | 
			
		||||
    def make_people_menu(self, request):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Generate a typical People menu.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ class MenuHandler(GenericHandler):
 | 
			
		|||
            ],
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    def make_admin_menu(self, request, **kwargs):
 | 
			
		||||
    def make_admin_menu(self, request, **kwargs):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Generate a typical Admin menu.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ class WebTestCase(DataTestCase):
 | 
			
		|||
        event = MagicMock(request=self.request)
 | 
			
		||||
        subscribers.new_request(event)
 | 
			
		||||
 | 
			
		||||
        def user_getter(request, **kwargs):
 | 
			
		||||
        def user_getter(request, **kwargs):  # pylint: disable=unused-argument
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        subscribers.new_request_set_user(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ class View:
 | 
			
		|||
       Reference to the app :term:`config object`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, request, context=None):
 | 
			
		||||
    def __init__(self, request, context=None):  # pylint: disable=unused-argument
 | 
			
		||||
        self.request = request
 | 
			
		||||
        self.config = self.request.wutta_config
 | 
			
		||||
        self.app = self.config.get_app()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -144,7 +144,9 @@ class BatchMasterView(MasterView):
 | 
			
		|||
        # description
 | 
			
		||||
        g.set_link("description")
 | 
			
		||||
 | 
			
		||||
    def render_batch_id(self, batch, key, value):  # pylint: disable=empty-docstring
 | 
			
		||||
    def render_batch_id(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, batch, key, value
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        if value:
 | 
			
		||||
            batch_id = int(value)
 | 
			
		||||
| 
						 | 
				
			
			@ -406,7 +408,9 @@ class BatchMasterView(MasterView):
 | 
			
		|||
 | 
			
		||||
        g.set_renderer("status_code", self.render_row_status)
 | 
			
		||||
 | 
			
		||||
    def render_row_status(self, row, key, value):  # pylint: disable=empty-docstring
 | 
			
		||||
    def render_row_status(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, row, key, value
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        return row.STATUS.get(value, value)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,7 +122,9 @@ class EmailSettingView(MasterView):
 | 
			
		|||
        # to
 | 
			
		||||
        g.set_renderer("to", self.render_to_short)
 | 
			
		||||
 | 
			
		||||
    def render_to_short(self, setting, field, value):  # pylint: disable=empty-docstring
 | 
			
		||||
    def render_to_short(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, setting, field, value
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        recips = value
 | 
			
		||||
        if not recips:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,9 @@ That will in turn include the following modules:
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def defaults(config, **kwargs):
 | 
			
		||||
    mod = lambda spec: kwargs.get(spec, spec)
 | 
			
		||||
 | 
			
		||||
    def mod(spec):
 | 
			
		||||
        return kwargs.get(spec, spec)
 | 
			
		||||
 | 
			
		||||
    config.include(mod("wuttaweb.views.common"))
 | 
			
		||||
    config.include(mod("wuttaweb.views.auth"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -814,7 +814,7 @@ class MasterView(View):
 | 
			
		|||
        return self.render_progress(progress)
 | 
			
		||||
 | 
			
		||||
    def delete_bulk_thread(  # pylint: disable=empty-docstring
 | 
			
		||||
        self, query, success_url=None, progress=None
 | 
			
		||||
        self, query, progress=None
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        model_title_plural = self.get_model_title_plural()
 | 
			
		||||
| 
						 | 
				
			
			@ -859,7 +859,7 @@ class MasterView(View):
 | 
			
		|||
        """
 | 
			
		||||
        model_title_plural = self.get_model_title_plural()
 | 
			
		||||
 | 
			
		||||
        def delete(obj, i):
 | 
			
		||||
        def delete(obj, i):  # pylint: disable=unused-argument
 | 
			
		||||
            if self.is_deletable(obj):
 | 
			
		||||
                self.delete_instance(obj)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1440,7 +1440,7 @@ class MasterView(View):
 | 
			
		|||
    # grid rendering methods
 | 
			
		||||
    ##############################
 | 
			
		||||
 | 
			
		||||
    def grid_render_bool(self, record, key, value):
 | 
			
		||||
    def grid_render_bool(self, record, key, value):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Custom grid value renderer for "boolean" fields.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1537,7 +1537,9 @@ class MasterView(View):
 | 
			
		|||
 | 
			
		||||
        return value
 | 
			
		||||
 | 
			
		||||
    def grid_render_notes(self, record, key, value, maxlen=100):
 | 
			
		||||
    def grid_render_notes(  # pylint: disable=unused-argument
 | 
			
		||||
        self, record, key, value, maxlen=100
 | 
			
		||||
    ):
 | 
			
		||||
        """
 | 
			
		||||
        Custom grid value renderer for "notes" fields.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1694,7 +1696,7 @@ class MasterView(View):
 | 
			
		|||
 | 
			
		||||
        return button
 | 
			
		||||
 | 
			
		||||
    def get_xref_buttons(self, obj):
 | 
			
		||||
    def get_xref_buttons(self, obj):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Should return a list of "cross-reference" buttons to be shown
 | 
			
		||||
        when viewing the given object.
 | 
			
		||||
| 
						 | 
				
			
			@ -2078,7 +2080,9 @@ class MasterView(View):
 | 
			
		|||
            return self.grid_columns
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_grid_data(self, columns=None, session=None):
 | 
			
		||||
    def get_grid_data(  # pylint: disable=unused-argument
 | 
			
		||||
        self, columns=None, session=None
 | 
			
		||||
    ):
 | 
			
		||||
        """
 | 
			
		||||
        Returns the grid data for the :meth:`index()` view.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2268,7 +2272,7 @@ class MasterView(View):
 | 
			
		|||
        route_prefix = self.get_route_prefix()
 | 
			
		||||
        return self.request.route_url(f"{route_prefix}.{action}", **kw)
 | 
			
		||||
 | 
			
		||||
    def get_action_url_view(self, obj, i):
 | 
			
		||||
    def get_action_url_view(self, obj, i):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Returns the "view" grid action URL for the given object.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2279,7 +2283,7 @@ class MasterView(View):
 | 
			
		|||
        """
 | 
			
		||||
        return self.get_action_url("view", obj)
 | 
			
		||||
 | 
			
		||||
    def get_action_url_edit(self, obj, i):
 | 
			
		||||
    def get_action_url_edit(self, obj, i):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Returns the "edit" grid action URL for the given object, if
 | 
			
		||||
        applicable.
 | 
			
		||||
| 
						 | 
				
			
			@ -2296,7 +2300,7 @@ class MasterView(View):
 | 
			
		|||
            return self.get_action_url("edit", obj)
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def get_action_url_delete(self, obj, i):
 | 
			
		||||
    def get_action_url_delete(self, obj, i):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Returns the "delete" grid action URL for the given object, if
 | 
			
		||||
        applicable.
 | 
			
		||||
| 
						 | 
				
			
			@ -2313,7 +2317,7 @@ class MasterView(View):
 | 
			
		|||
            return self.get_action_url("delete", obj)
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def is_editable(self, obj):
 | 
			
		||||
    def is_editable(self, obj):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Returns a boolean indicating whether "edit" should be allowed
 | 
			
		||||
        for the given model instance (and for current user).
 | 
			
		||||
| 
						 | 
				
			
			@ -2326,7 +2330,7 @@ class MasterView(View):
 | 
			
		|||
        """
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def is_deletable(self, obj):
 | 
			
		||||
    def is_deletable(self, obj):  # pylint: disable=unused-argument
 | 
			
		||||
        """
 | 
			
		||||
        Returns a boolean indicating whether "delete" should be
 | 
			
		||||
        allowed for the given model instance (and for current user).
 | 
			
		||||
| 
						 | 
				
			
			@ -2807,7 +2811,7 @@ class MasterView(View):
 | 
			
		|||
                [
 | 
			
		||||
                    prop.key
 | 
			
		||||
                    for prop in inspector.column_attrs
 | 
			
		||||
                    if all([col.name in keys for col in prop.columns])
 | 
			
		||||
                    if all(col.name in keys for col in prop.columns)
 | 
			
		||||
                ]
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,13 +119,19 @@ class PersonView(MasterView):
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
        if self.request.has_perm("users.view"):
 | 
			
		||||
            url = lambda user, i: self.request.route_url("users.view", uuid=user.uuid)
 | 
			
		||||
            grid.add_action("view", icon="eye", url=url)
 | 
			
		||||
 | 
			
		||||
            def view_url(user, i):  # pylint: disable=unused-argument
 | 
			
		||||
                return self.request.route_url("users.view", uuid=user.uuid)
 | 
			
		||||
 | 
			
		||||
            grid.add_action("view", icon="eye", url=view_url)
 | 
			
		||||
            grid.set_link("username")
 | 
			
		||||
 | 
			
		||||
        if self.request.has_perm("users.edit"):
 | 
			
		||||
            url = lambda user, i: self.request.route_url("users.edit", uuid=user.uuid)
 | 
			
		||||
            grid.add_action("edit", url=url)
 | 
			
		||||
 | 
			
		||||
            def edit_url(user, i):  # pylint: disable=unused-argument
 | 
			
		||||
                return self.request.route_url("users.edit", uuid=user.uuid)
 | 
			
		||||
 | 
			
		||||
            grid.add_action("edit", url=edit_url)
 | 
			
		||||
 | 
			
		||||
        return grid
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -160,14 +160,20 @@ class RoleView(MasterView):
 | 
			
		|||
        )
 | 
			
		||||
 | 
			
		||||
        if self.request.has_perm("users.view"):
 | 
			
		||||
            url = lambda user, i: self.request.route_url("users.view", uuid=user.uuid)
 | 
			
		||||
            grid.add_action("view", icon="eye", url=url)
 | 
			
		||||
 | 
			
		||||
            def view_url(user, i):  # pylint: disable=unused-argument
 | 
			
		||||
                return self.request.route_url("users.view", uuid=user.uuid)
 | 
			
		||||
 | 
			
		||||
            grid.add_action("view", icon="eye", url=view_url)
 | 
			
		||||
            grid.set_link("person")
 | 
			
		||||
            grid.set_link("username")
 | 
			
		||||
 | 
			
		||||
        if self.request.has_perm("users.edit"):
 | 
			
		||||
            url = lambda user, i: self.request.route_url("users.edit", uuid=user.uuid)
 | 
			
		||||
            grid.add_action("edit", url=url)
 | 
			
		||||
 | 
			
		||||
            def edit_url(user, i):  # pylint: disable=unused-argument
 | 
			
		||||
                return self.request.route_url("users.edit", uuid=user.uuid)
 | 
			
		||||
 | 
			
		||||
            grid.add_action("edit", url=edit_url)
 | 
			
		||||
 | 
			
		||||
        return grid
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,7 +110,9 @@ class UpgradeView(MasterView):
 | 
			
		|||
        )
 | 
			
		||||
        g.set_filter("executed_by", Executor.username, label="Executed By Username")
 | 
			
		||||
 | 
			
		||||
    def grid_row_class(self, upgrade, data, i):  # pylint: disable=empty-docstring
 | 
			
		||||
    def grid_row_class(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, upgrade, data, i
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        enum = self.app.enum
 | 
			
		||||
        if upgrade.status == enum.UpgradeStatus.EXECUTING:
 | 
			
		||||
| 
						 | 
				
			
			@ -321,7 +323,7 @@ class UpgradeView(MasterView):
 | 
			
		|||
            size = os.path.getsize(path) - offset
 | 
			
		||||
            if size > 0:
 | 
			
		||||
                # with open(path, 'rb') as f:
 | 
			
		||||
                with open(path) as f:
 | 
			
		||||
                with open(path, "rt", encoding="utf_8") as f:
 | 
			
		||||
                    f.seek(offset)
 | 
			
		||||
                    chunk = f.read(size)
 | 
			
		||||
                    # data['stdout'] = chunk.decode('utf8').replace('\n', '<br />')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,9 @@ class UserView(MasterView):
 | 
			
		|||
        g.set_sorter("person", model.Person.full_name)
 | 
			
		||||
        g.set_filter("person", model.Person.full_name, label="Person Full Name")
 | 
			
		||||
 | 
			
		||||
    def grid_row_class(self, user, data, i):  # pylint: disable=empty-docstring
 | 
			
		||||
    def grid_row_class(  # pylint: disable=empty-docstring,unused-argument
 | 
			
		||||
        self, user, data, i
 | 
			
		||||
    ):
 | 
			
		||||
        """ """
 | 
			
		||||
        if not user.active:
 | 
			
		||||
            return "has-background-warning"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,9 +54,15 @@ class TestPersonView(WebTestCase):
 | 
			
		|||
            self.assertIsInstance(form.widgets["users"], GridWidget)
 | 
			
		||||
 | 
			
		||||
    def test_make_users_grid(self):
 | 
			
		||||
        self.pyramid_config.add_route("users.view", "/users/{uuid}/view")
 | 
			
		||||
        self.pyramid_config.add_route("users.edit", "/users/{uuid}/edit")
 | 
			
		||||
        model = self.app.model
 | 
			
		||||
        view = self.make_view()
 | 
			
		||||
        person = model.Person(full_name="John Doe")
 | 
			
		||||
        self.session.add(person)
 | 
			
		||||
        user = model.User(username="john", person=person)
 | 
			
		||||
        self.session.add(user)
 | 
			
		||||
        self.session.commit()
 | 
			
		||||
 | 
			
		||||
        # basic
 | 
			
		||||
        grid = view.make_users_grid(person)
 | 
			
		||||
| 
						 | 
				
			
			@ -73,6 +79,9 @@ class TestPersonView(WebTestCase):
 | 
			
		|||
            self.assertEqual(grid.actions[0].key, "view")
 | 
			
		||||
            self.assertEqual(grid.actions[1].key, "edit")
 | 
			
		||||
 | 
			
		||||
            # render grid to ensure coverage for link urls
 | 
			
		||||
            grid.render_vue_template()
 | 
			
		||||
 | 
			
		||||
    def test_objectify(self):
 | 
			
		||||
        model = self.app.model
 | 
			
		||||
        view = self.make_view()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -95,9 +95,16 @@ class TestRoleView(WebTestCase):
 | 
			
		|||
        self.assertIsNotNone(form.validators["name"])
 | 
			
		||||
 | 
			
		||||
    def test_make_users_grid(self):
 | 
			
		||||
        self.pyramid_config.add_route("users.view", "/users/{uuid}/view")
 | 
			
		||||
        self.pyramid_config.add_route("users.edit", "/users/{uuid}/edit")
 | 
			
		||||
        model = self.app.model
 | 
			
		||||
        view = self.make_view()
 | 
			
		||||
        role = model.Role(name="Manager")
 | 
			
		||||
        self.session.add(role)
 | 
			
		||||
        user = model.User(username="freddie")
 | 
			
		||||
        user.roles.append(role)
 | 
			
		||||
        self.session.add(user)
 | 
			
		||||
        self.session.commit()
 | 
			
		||||
 | 
			
		||||
        # basic
 | 
			
		||||
        grid = view.make_users_grid(role)
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +122,9 @@ class TestRoleView(WebTestCase):
 | 
			
		|||
            self.assertEqual(grid.actions[0].key, "view")
 | 
			
		||||
            self.assertEqual(grid.actions[1].key, "edit")
 | 
			
		||||
 | 
			
		||||
            # render grid to ensure coverage for link urls
 | 
			
		||||
            grid.render_vue_template()
 | 
			
		||||
 | 
			
		||||
    def test_unique_name(self):
 | 
			
		||||
        model = self.app.model
 | 
			
		||||
        view = self.make_view()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue