From c4a19f279b99ff551711caa4d34f417cc35440bb Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Mon, 19 Jan 2015 00:45:26 -0600 Subject: [PATCH] Remove some edbob, unicode tweak, etc. In particular it was noticed that edbob has been configuring FormAlchemy all this time, whoops. That's still partially the case but now at least it's explicit. --- tailbone/app.py | 30 ++++++++++++++-------- tailbone/templates/crud.mako | 2 +- tailbone/views/labels.py | 11 +++------ tailbone/views/users.py | 48 +++++++++++++++++++++++++++--------- 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/tailbone/app.py b/tailbone/app.py index 55f85c7b..d9c791e4 100644 --- a/tailbone/app.py +++ b/tailbone/app.py @@ -1,9 +1,8 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2012 Lance Edgar +# Copyright © 2010-2015 Lance Edgar # # This file is part of Rattail. # @@ -21,22 +20,29 @@ # along with Rattail. If not, see . # ################################################################################ - """ Application Entry Point """ -from pyramid.config import Configurator +from __future__ import unicode_literals -import os.path -import edbob +import os from sqlalchemy import engine_from_config -from .db import Session + +import edbob +from edbob.pyramid.forms.formalchemy import TemplateEngine + +from rattail.db.types import GPCType + +import formalchemy +from pyramid.config import Configurator +from pyramid.authentication import SessionAuthenticationPolicy from zope.sqlalchemy import ZopeTransactionExtension -from pyramid.authentication import SessionAuthenticationPolicy -from .auth import TailboneAuthorizationPolicy +from tailbone.db import Session +from tailbone.auth import TailboneAuthorizationPolicy +from tailbone.forms import GPCFieldRenderer def main(global_config, **settings): @@ -73,6 +79,10 @@ def main(global_config, **settings): # Bring in the rest of Tailbone. config.include('tailbone') + # Configure FormAlchemy. + formalchemy.config.engine = TemplateEngine() + formalchemy.FieldSet.default_renderers[GPCType] = GPCFieldRenderer + # Consider PostgreSQL server restart errors to be "retryable." config.add_tween('edbob.pyramid.tweens.sqlerror_tween_factory', under='pyramid_tm.tm_tween_factory') diff --git a/tailbone/templates/crud.mako b/tailbone/templates/crud.mako index 9d3a6297..b1afa0e5 100644 --- a/tailbone/templates/crud.mako +++ b/tailbone/templates/crud.mako @@ -3,7 +3,7 @@ <%def name="title()">${"New "+form.pretty_name if form.creating else form.pretty_name+' : '+capture(self.model_title)} -<%def name="model_title()">${h.literal(str(form.fieldset.model))} +<%def name="model_title()">${h.literal(unicode(form.fieldset.model))} <%def name="head_tags()"> ${parent.head_tags()} diff --git a/tailbone/views/labels.py b/tailbone/views/labels.py index 82b49dec..bd292fcb 100644 --- a/tailbone/views/labels.py +++ b/tailbone/views/labels.py @@ -1,9 +1,8 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2012 Lance Edgar +# Copyright © 2010-2015 Lance Edgar # # This file is part of Rattail. # @@ -21,11 +20,12 @@ # along with Rattail. If not, see . # ################################################################################ - """ Label Views """ +from __future__ import unicode_literals + from pyramid.httpexceptions import HTTPFound import formalchemy @@ -35,7 +35,6 @@ from webhelpers.html import HTML from ..db import Session from . import SearchableAlchemyGridView, CrudView from ..grids.search import BooleanSearchFilter -from edbob.pyramid.forms import StrippingFieldRenderer from rattail.db.model import LabelProfile @@ -102,8 +101,6 @@ class ProfileCrud(CrudView): return super(FormatFieldRenderer, self).render(**kwargs) fs = self.make_fieldset(model) - fs.printer_spec.set(renderer=StrippingFieldRenderer) - fs.formatter_spec.set(renderer=StrippingFieldRenderer) fs.format.set(renderer=FormatFieldRenderer) fs.configure( include=[ diff --git a/tailbone/views/users.py b/tailbone/views/users.py index 562ec8e3..983fe3ad 100644 --- a/tailbone/views/users.py +++ b/tailbone/views/users.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2014 Lance Edgar +# Copyright © 2010-2015 Lance Edgar # # This file is part of Rattail. # @@ -20,27 +20,24 @@ # along with Rattail. If not, see . # ################################################################################ - """ User Views """ from __future__ import unicode_literals +from rattail.db.model import User, Person, Role +from rattail.db.auth import guest_role, set_user_password + +import formalchemy from formalchemy import Field, ValidationError from formalchemy.fields import SelectFieldRenderer - -from edbob.pyramid.views import users +from webhelpers.html import tags +from webhelpers.html import HTML from . import SearchableAlchemyGridView, CrudView from ..forms import PersonFieldLinkRenderer from ..db import Session -from rattail.db.model import User, Person, Role -from rattail.db.auth import guest_role - -from webhelpers.html import tags -from webhelpers.html import HTML - from tailbone.grids.search import BooleanSearchFilter @@ -141,6 +138,33 @@ def RolesFieldRenderer(request): return RolesFieldRenderer +class PasswordFieldRenderer(formalchemy.PasswordFieldRenderer): + + def render(self, **kwargs): + return tags.password(self.name, value='', maxlength=self.length, **kwargs) + + +def passwords_match(value, field): + if field.parent.confirm_password.value != value: + raise formalchemy.ValidationError("Passwords do not match") + return value + + +class PasswordField(formalchemy.Field): + + def __init__(self, *args, **kwargs): + kwargs.setdefault('value', lambda x: x.password) + kwargs.setdefault('renderer', PasswordFieldRenderer) + kwargs.setdefault('validate', passwords_match) + super(PasswordField, self).__init__(*args, **kwargs) + + def sync(self): + if not self.is_readonly(): + password = self.renderer.deserialize() + if password: + set_user_password(self.model, password) + + class UserCrud(CrudView): mapped_class = User @@ -152,9 +176,9 @@ class UserCrud(CrudView): # Must set Person options to empty set to avoid unwanted magic. fs.person.set(options=[]) - fs.append(users.PasswordField('password')) + fs.append(PasswordField('password')) fs.append(Field('confirm_password', - renderer=users.PasswordFieldRenderer)) + renderer=PasswordFieldRenderer)) fs.append(RolesField( 'roles', renderer=RolesFieldRenderer(self.request)))