Exemple #1
0
def userdata_doctype_view(userdata_model, request):
    """
    View used to register doctypes status

        userdata_model

            The UserDatas model retrieved through traversal
    """
    if 'submit' in request.params:
        schema = get_doctypes_form_schema(userdata_model)[0]
        appstruct = request.POST.items()
        appstruct = peppercorn.parse(appstruct)
        try:
            appstruct = schema.deserialize(appstruct)
        except colander.Invalid:
            logger.exception(
                "Error while validating doctype registration"
            )
        else:
            node_schema = SQLAlchemySchemaNode(UserDatasSocialDocTypes)
            for data in appstruct.values():
                model = node_schema.objectify(data)
                request.dbsession.merge(model)
            request.session.flash(
                u"Les informations saisies ont bien été enregistrées"
            )

    return HTTPFound(
        request.route_path('userdata', id=userdata_model.id)
    )
    def test_specify_order_fields(self):
        """
        Test this issue:
        How to specify the order in which fields should be displayed ? #45
        """
        Base = declarative_base()

        # example taken from SQLAlchemy docs
        class MyClass(Base):
            __tablename__ = 'my_table'

            id = Column(Integer, primary_key=True)
            job_status = Column(String(50))

            status = synonym("job_status")

        schema = SQLAlchemySchemaNode(MyClass,
                                      includes=['foo', 'job_status', 'id'])
        self.assertEqual(['job_status', 'id'], [x.name for x in schema])
        self.assertNotIn('foo', schema)

        schema = SQLAlchemySchemaNode(MyClass,
                                      includes=['id', 'foo', 'job_status'])
        self.assertEqual(['id', 'job_status'], [x.name for x in schema])
        self.assertNotIn('foo', schema)
Exemple #3
0
def get_add_edit_schema(edit=False):
    """
    Return a user add schema
    """
    schema = SQLAlchemySchemaNode(
        User,
        includes=(
            'civilite',
            'firstname',
            'lastname',
            'email',
        ),
    )
    if not edit:
        schema.add(
            colander.SchemaNode(
                colander.Boolean(),
                name='add_login',
                title=u"Créer des identifiants pour ce compte ?",
                description=u"Les identifiants permettront au titulaire de ce "
                u"compte de se connecter",
            )
        )
    set_widgets(schema)
    return schema
 def _prep_schema(self):
     overrides = {
         'person': {
             'includes': ['name', 'surname', 'gender', 'addresses'],
             'overrides': {
                 'addresses': {
                     'includes': ['street', 'city'],
                     'overrides': {
                         'city': {
                             'exclude': False
                         }
                     }
                 }
             }
         },
     }
     includes = ['email', 'enabled', 'created', 'timeout', 'person']
     schema = SQLAlchemySchemaNode(Account, includes=includes,
                                   overrides=overrides)
     # Add a non-SQLAlchemy field
     schema.add(colander.SchemaNode(
         colander.String(),
         name='non_sql',
         missing=colander.drop
     ))
     return schema
Exemple #5
0
def get_password_schema():
    """
    Return the schema for user password change
    """
    schema = SQLAlchemySchemaNode(
        user.User,
        includes=('login', 'pwd',),
        title=u'Modification de mot de passe',
        validator=auth,
    )

    schema.insert(
        1,
        colander.SchemaNode(
            colander.String(),
            widget=deform.widget.PasswordWidget(),
            name='password',
            title=u'Mot de passe actuel',
            default=u'',
        )
    )

    schema['login'].widget = deform.widget.HiddenWidget()
    # Remove login validation
    schema['login'].validator = None

    return schema
Exemple #6
0
def get_password_schema():
    """
    Return the schema for user password change
    """
    schema = SQLAlchemySchemaNode(
        user.User,
        includes=(
            'login',
            'pwd',
        ),
        title=u'Modification de mot de passe',
        validator=auth,
    )

    schema.insert(
        1,
        colander.SchemaNode(
            colander.String(),
            widget=deform.widget.PasswordWidget(),
            name='password',
            title=u'Mot de passe actuel',
            default=u'',
        ))

    schema['login'].widget = deform.widget.HiddenWidget()
    # Remove login validation
    schema['login'].validator = None

    return schema
Exemple #7
0
    def test_dictify_with_null(self):
        """ Test SQLAlchemySchemaNode.dictify(obj) with null values
        and show that result is a valid appstruct for the given schema
        """
        Base = declarative_base()

        class Sensor(Base):
            __tablename__ = 'sensor'
            sensor_id = Column(Integer, primary_key=True)
            institution_id = Column(Integer, nullable=True)
            sensor_label = Column(String, nullable=True)

        sensor = Sensor(
            sensor_id=3,
            institution_id=None,
            sensor_label=None,
        )

        schema = SQLAlchemySchemaNode(Sensor)
        appstruct = schema.dictify(sensor)
        cstruct = schema.serialize(appstruct=appstruct)
        newappstruct = schema.deserialize(cstruct)
        newobj = schema.objectify(appstruct)

        self.assertEqual(appstruct, newappstruct)
        self.assertEqual(sensor.sensor_id, newobj.sensor_id)
        self.assertEqual(sensor.institution_id, newobj.institution_id)
        self.assertEqual(sensor.sensor_label, newobj.sensor_label)
Exemple #8
0
def get_project_schema():
    """
    Return the project Edition/add form schema
    """
    schema = SQLAlchemySchemaNode(Project, excludes=('_acl',))

    schema['name'].missing = colander.required

    # Add a custom node to be able to associate existing customers
    customer_id_node = colander.SchemaNode(
        colander.Integer(),
        widget=deferred_customer_select,
        validator=deferred_customer_validator,
        default=deferred_default_customer,
        name='un client'
    )
    customer_id_node.objectify = customer_objectify
    customer_id_node.dictify = customer_dictify

    schema.insert(3,
        colander.SchemaNode(
        colander.Sequence(),
        customer_id_node,
        widget=deform.widget.SequenceWidget(min_len=1),
        title=u"Clients",
        name='customers')
    )

    return schema
Exemple #9
0
def get_sequence_model_admin(model, title=u""):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(
        model,
        widget=deform.widget.MappingWidget(template=TEMPLATES_URL +
                                           "clean_mapping.pt", ))
    node_schema.name = 'data'

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(colander.Sequence(),
                            node_schema,
                            widget=deform.widget.SequenceWidget(
                                orderable=True,
                                template=TEMPLATES_URL + "clean_sequence.pt",
                            ),
                            title=title,
                            name='datas'))

    def dictify(models):
        return {'datas': [node_schema.dictify(model) for model in models]}

    def objectify(datas):
        return [node_schema.objectify(data) for data in datas]

    schema.dictify = dictify
    schema.objectify = objectify
    return schema
Exemple #10
0
def get_add_edit_schema(edit=False):
    """
    Return a user add schema
    """
    schema = SQLAlchemySchemaNode(
        User,
        includes=(
            'civilite',
            'firstname',
            'lastname',
            'email',
        ),
    )
    if not edit:
        schema.add(
            colander.SchemaNode(
                colander.Boolean(),
                name='add_login',
                title=u"Créer des identifiants pour ce compte ?",
                description=u"Les identifiants permettront au titulaire de ce "
                u"compte de se connecter",
            )
        )
    set_widgets(schema)
    return schema
Exemple #11
0
def userdata_doctype_view(userdata_model, request):
    """
    View used to register doctypes status

        userdata_model

            The UserDatas model retrieved through traversal
    """
    if 'submit' in request.params:
        schema = get_doctypes_form_schema(userdata_model)[0]
        appstruct = request.POST.items()
        appstruct = peppercorn.parse(appstruct)
        try:
            appstruct = schema.deserialize(appstruct)
        except colander.Invalid:
            logger.exception("Error while validating doctype registration")
        else:
            node_schema = SQLAlchemySchemaNode(UserDatasSocialDocTypes)
            for data in appstruct.values():
                model = node_schema.objectify(data)
                request.dbsession.merge(model)
            request.session.flash(
                u"Les informations saisies ont bien été enregistrées")

    return HTTPFound(request.route_path('userdata', id=userdata_model.id))
Exemple #12
0
def get_project_schema():
    """
    Return the project Edition/add form schema
    """
    schema = SQLAlchemySchemaNode(Project, excludes=('_acl', ))

    schema['name'].missing = colander.required

    # Add a custom node to be able to associate existing customers
    customer_id_node = colander.SchemaNode(
        colander.Integer(),
        widget=deferred_customer_select,
        validator=deferred_customer_validator,
        default=deferred_default_customer,
        name='un client')
    customer_id_node.objectify = customer_objectify
    customer_id_node.dictify = customer_dictify

    schema.insert(
        3,
        colander.SchemaNode(colander.Sequence(),
                            customer_id_node,
                            widget=deform.widget.SequenceWidget(min_len=1),
                            title=u"Clients",
                            name='customers'))

    return schema
Exemple #13
0
def test_payment(mode, tva, bank):
    from autonomie.models.task.invoice import Payment
    schema = SQLAlchemySchemaNode(Payment)
    schema = schema.bind()

    value = {
        'mode': mode.label,
        "amount": 12.5,
        "remittance_amount": u"Remittance",
        "date": NOW.isoformat(),
        "tva_id": tva.id,
        "bank_id": bank.id,
        "user_id": 5,
        "task_id": 5,
    }

    expected_value = {
        'mode': mode.label,
        "amount": 1250000,
        "remittance_amount": u"Remittance",
        "date": NOW,
        "tva_id": tva.id,
        "bank_id": bank.id,
        "user_id": 5,
        "task_id": 5,
    }
    result = schema.deserialize(value)

    for key, value in expected_value.items():
        assert result[key] == value
Exemple #14
0
def get_password_schema():
    """
    Return the schema for user password change

    :returns: a colander Schema
    """
    schema = SQLAlchemySchemaNode(
        Login,
        includes=('pwd_hash',),
        title=u'',
    )
    set_widgets(schema)

    schema.insert(
        0,
        colander.SchemaNode(
            colander.String(),
            widget=deform.widget.PasswordWidget(),
            name='password',
            title=u'Mot de passe actuel',
            default=u'',
        )
    )

    schema['pwd_hash'].title = u"Nouveau mot de passe"
    schema.validator = deferred_password_validator
    schema.after_bind = remove_actual_password_my_account

    return schema
Exemple #15
0
def statistic_sheet_add_edit_view(context, request):
    """
    View for adding editing statistics sheets
    """
    post_datas = request.POST or request.json_body
    if 'title' in post_datas:
        schema = SQLAlchemySchemaNode(StatisticSheet, includes=('title',))

        try:
            appstruct = schema.deserialize(request.POST)
        except colander.Invalid:
            logger.exception(u"Erreur à la création de la feuille de \
statistiques")
        else:
            if context.__name__ == 'statistic_sheet':
                sheet = schema.objectify(appstruct, context)
                sheet = request.dbsession.merge(sheet)
            else:
                sheet = schema.objectify(appstruct)
                request.dbsession.add(sheet)
            request.dbsession.flush()
            url = request.route_path('statistic', id=sheet.id)
            return dict(redirect=url)
        logger.debug(u"Invalid datas have been passed")
        raise HTTPClientError()
    logger.debug(u"Missing datas in the request")
    raise HTTPClientError()
    def test_null_issues(self):
        """ Make sure nullable values are set properly when null

        #42 introduced an issue where values may not have been properly
        set if the value is supposed to be set to null
        """
        Base = declarative_base()

        class Person(Base):
            __tablename__ = 'person'
            id = Column(Integer, primary_key=True)
            fullname = Column(String, nullable=True)
            age = Column(Integer, nullable=True)

        schema = SQLAlchemySchemaNode(Person)

        person = Person(
            id=7,
            fullname="Joe Smith",
            age=35,
        )

        # dict coming from a form submission
        update_cstruct = {
            'id': '7',
            'fullname': '',
            'age': '',
        }
        update_appstruct = schema.deserialize(update_cstruct)
        schema.objectify(update_appstruct, context=person)

        self.assertEqual(person.id, 7)
        self.assertEqual(person.fullname, None)
        self.assertEqual(person.age, None)
Exemple #17
0
def statistic_sheet_add_edit_view(context, request):
    """
    View for adding editing statistics sheets
    """
    logger.info("Here we are")
    logger.info(request.POST)
    if 'title' in request.POST:
        schema = SQLAlchemySchemaNode(StatisticSheet, includes=('title',))

        try:
            appstruct = schema.deserialize(request.POST)
        except colander.Invalid:
            logger.exception(u"Erreur à la création de la feuille de \
statistiques")
        else:
            if context.__name__ == 'statistic_sheet':
                sheet = schema.objectify(appstruct, context)
                sheet = request.dbsession.merge(sheet)
            else:
                sheet = schema.objectify(appstruct)
                request.dbsession.add(sheet)
            request.dbsession.flush()
            url = request.route_path('statistic', id=sheet.id)
            return HTTPFound(url)
        logger.debug(u"Invalid datas have been passed")
        raise HTTPClientError()
    logger.debug(u"Missing datas in the request")
    raise HTTPClientError()
    def test_relationship_infinite_recursion(self):
        """Test to ensure infinite recursion does not occur when following backrefs
        """

        # Unpatched, creating a bar or baz schema node causes infinite recursion
        schema = SQLAlchemySchemaNode(Bar)
        schema = SQLAlchemySchemaNode(Baz)
Exemple #19
0
def get_doctypes_schema(userdatas_model):
    """
    Build a form schema for doctypes registration

    :param obj userdatas_model: An instance of userdatas we're building 
    the form for
    """
    registered = userdatas_model.doctypes_registrations
    node_schema = SQLAlchemySchemaNode(UserDatasSocialDocTypes)
    node_schema.widget = deform.widget.MappingWidget(
        template="clean_mapping.pt"
    )
    node_schema['status'].widget = deform.widget.CheckboxWidget()

    form_schema = colander.Schema()
    for index, entry in enumerate(registered):
        node = node_schema.clone()
        name = 'node_%s' % index
        node.name = name
        node.title = u''
        node['status'].title = u''
        node['status'].label = entry.doctype.label
        form_schema.add(node)

    return form_schema
def get_doctypes_schema(userdatas_model):
    """
    Build a form schema for doctypes registration

    :param obj userdatas_model: An instance of userdatas we're building
    the form for
    """
    registered = userdatas_model.doctypes_registrations
    node_schema = SQLAlchemySchemaNode(UserDatasSocialDocTypes)
    node_schema.widget = deform.widget.MappingWidget(
        template="clean_mapping.pt"
    )
    node_schema['status'].widget = deform.widget.CheckboxWidget()

    form_schema = colander.Schema()
    for index, entry in enumerate(registered):
        node = node_schema.clone()
        name = 'node_%s' % index
        node.name = name
        node.title = u''
        node['status'].title = u''
        node['status'].label = entry.doctype.label
        form_schema.add(node)

    return form_schema
Exemple #21
0
def get_password_schema():
    """
    Return the schema for user password change

    :returns: a colander Schema
    """
    schema = SQLAlchemySchemaNode(
        Login,
        includes=('pwd_hash', ),
        title=u'',
        validator=deferred_password_validator,
    )
    set_widgets(schema)

    schema.insert(
        0,
        colander.SchemaNode(
            colander.String(),
            widget=deform.widget.PasswordWidget(),
            name='password',
            title=u'Mot de passe actuel',
            default=u'',
        ))

    schema['pwd_hash'].title = u"Nouveau mot de passe"

    return schema
Exemple #22
0
def test_payment_line_task_id():
    from autonomie.models.task.estimation import PaymentLine
    schema = SQLAlchemySchemaNode(PaymentLine, includes=('task_id', ))
    value = {'task_id': 5}
    assert schema.deserialize(value) == value
    value = {}
    with pytest.raises(colander.Invalid):
        schema.deserialize(value)
Exemple #23
0
def test_discount_line_description():
    from autonomie.models.task.task import DiscountLine
    schema = SQLAlchemySchemaNode(DiscountLine, includes=('description', ))
    value = {'description': u"description"}
    assert schema.deserialize(value) == value
    value = {"description": u"<br /><p></p>\n"}
    with pytest.raises(colander.Invalid):
        schema.deserialize(value)
Exemple #24
0
def test_task_line_group_task_id():
    from autonomie.models.task.task import TaskLineGroup
    schema = SQLAlchemySchemaNode(TaskLineGroup, includes=('task_id', ))
    value = {'task_id': 5}
    assert schema.deserialize(value) == value
    value = {}
    with pytest.raises(colander.Invalid):
        schema.deserialize(value)
    def test_default_clause(self):
        """Test proper handling of default and server_default values
        """
        Base = declarative_base()

        def give_me_three():
            return 3

        class Patient(Base):
            __tablename__ = 'patient'
            # default= is equivalent to ColumnDefault()
            # server_default= is equivalent to DefaultClause()
            id = Column(BigInteger(unsigned=True), default=text("uuid_short()"), primary_key=True, autoincrement=False)
            received_timestamp = Column(TIMESTAMP, server_default=func.now(), nullable=False)
            some_number = Column(Integer, DefaultClause('3'), nullable=False)
            scalar_number = Column(Integer, default=3, nullable=False)
            pyfunc_test = Column(Integer, default=give_me_three, nullable=False)

        schema = SQLAlchemySchemaNode(Patient)

        '''
        Conceivably you should be able to test DefaultClause for a 
        scalar type value and use it as a default/missing in Colander.
        However, the value is interpreted by the backend engine and
        could be a interpreted by it in an unexpected way.  For this
        reason we drop the value and let the backend handle it.
        '''

        # from <FORM> result into SQLA; tests missing
        self.assertEqual(schema['id'].missing, colander.drop)
        self.assertEqual(schema['received_timestamp'].missing, colander.drop)
        self.assertEqual(schema['some_number'].missing, colander.drop)
        self.assertEqual(schema['scalar_number'].missing, 3)
        self.assertEqual(schema['pyfunc_test'].missing, 3)
        deserialized = schema.deserialize({})
        self.assertIn('scalar_number', deserialized)
        self.assertEqual(deserialized['scalar_number'], 3)
        self.assertIn('pyfunc_test', deserialized)
        self.assertEqual(deserialized['pyfunc_test'], 3)

        # from SQLA result into <FORM>; tests default
        self.assertEqual(schema['id'].default, colander.null)
        self.assertEqual(schema['received_timestamp'].default, colander.null)
        self.assertEqual(schema['some_number'].default, colander.null)
        self.assertEqual(schema['scalar_number'].default, 3)
        self.assertEqual(schema['pyfunc_test'].default, 3)
        serialized = schema.serialize({})
        self.assertIn('id', serialized)
        self.assertEqual(serialized['id'], colander.null)
        self.assertIn('received_timestamp', serialized)
        self.assertEqual(serialized['received_timestamp'], colander.null)
        self.assertIn('some_number', serialized)
        self.assertEqual(serialized['some_number'], colander.null)
        self.assertIn('scalar_number', serialized)
        self.assertEqual(serialized['scalar_number'], str(3))
        self.assertIn('pyfunc_test', serialized)
        self.assertEqual(serialized['pyfunc_test'], str(3))
    def test_clone(self):
        schema = SQLAlchemySchemaNode(Account, dummy='dummy', dummy2='dummy2')
        cloned = schema.clone()
        for attr in ['class_', 'includes', 'excludes', 'overrides']:
            self.assertEqual(getattr(schema, attr), getattr(cloned, attr))
        self.assertEqual(cloned.kwargs, schema.kwargs)

        self.assertEqual([node.name for node in schema.children],
                         [node.name for node in cloned.children])
def get_company_customer_schema():
    """
    return the schema for user add/edit regarding the current user's role
    """
    schema = SQLAlchemySchemaNode(Customer)
    schema = _customize_schema(schema)
    schema['name'].missing = colander.required
    schema.after_bind = _customer_after_bind
    return schema
Exemple #28
0
def get_company_customer_schema():
    """
    return the schema for user add/edit regarding the current user's role
    """
    schema = SQLAlchemySchemaNode(Customer)
    schema = _customize_schema(schema)
    schema['name'].missing = colander.required
    schema.after_bind = _customer_after_bind
    return schema
Exemple #29
0
def test_payment_line_date():
    import datetime
    from autonomie.models.task.estimation import PaymentLine
    schema = SQLAlchemySchemaNode(PaymentLine, includes=('date', ))
    schema = schema.bind()
    value = {'date': datetime.date.today().isoformat()}
    assert schema.deserialize(value) == {'date': datetime.date.today()}
    value = {}
    assert schema.deserialize(value) == value
Exemple #30
0
 def __init__(self, class_, includes=None,
              excludes=None, overrides=None, unknown='raise'):
     self.comparators = {}
     self.order_by_values = []
     SQLAlchemySchemaNode.__init__(self,
                                   class_,
                                   includes,
                                   excludes,
                                   overrides,
                                   unknown)
 def test_missing_mapping_configuration(self):
     """ Test to check ``missing`` is set to an SQLAlchemy-suitable value.
     """
     schema = SQLAlchemySchemaNode(Account)
     self.assertEqual(schema['person_id'].missing, colander.null)
     self.assertEqual(schema['person'].missing, [])
     deserialized = schema.deserialize({'email': '*****@*****.**',
                                        'timeout': '09:44:33'})
     self.assertEqual(deserialized['person_id'], colander.null)
     self.assertEqual(deserialized['person'], [])
Exemple #32
0
    def test_context_billing_email_allowed_for_billing_email(self):
        from pyramid_bimt.views.user import deferred_user_billing_email_validator  # noqa

        schema = SQLAlchemySchemaNode(User)
        self.request.context = User.by_email('*****@*****.**')
        self.request.POST['email'] = '*****@*****.**'

        validator = deferred_user_billing_email_validator(
            None, {'request': self.request})

        self.assertFalse(validator(schema.get('email'), '*****@*****.**'))
Exemple #33
0
    def test_context_name_allowed_for_name(self):
        from pyramid_bimt.views.group import deferred_group_name_validator

        schema = SQLAlchemySchemaNode(Group)
        self.request.context = Group.by_name('enabled')
        self.request.POST['name'] = 'enabled'

        validator = deferred_group_name_validator(None,
                                                  {'request': self.request})

        self.assertFalse(validator(schema.get('name'), 'enabled'))
Exemple #34
0
    def test_context_product_id_allowed_for_product_id(self):
        from pyramid_bimt.views.group import deferred_group_product_id_validator  # noqa

        schema = SQLAlchemySchemaNode(Group)
        self.request.context = Group.by_name('enabled')
        self.request.context.product_id = '123'
        self.request.POST['product_id'] = '123'

        validator = deferred_group_product_id_validator(
            None, {'request': self.request})

        self.assertFalse(validator(schema.get('product_id'), '123'))
    def test_imperative_colums_overrides(self):
        overrides = {'email': {'typ': colander.Integer}}
        account_schema = SQLAlchemySchemaNode(Account, overrides=overrides)
        self.assertTrue(
            isinstance(account_schema['email'].typ, colander.Integer))
        overrides = {'email': {'name': 'Name'}}
        self.assertRaises(ValueError, SQLAlchemySchemaNode, Account, None,
                          None, overrides)

        overrides = {'email': {'children': []}}
        # following shouldn't raise an exception allowing the test to pass
        SQLAlchemySchemaNode(Account, None, None, overrides)
    def test_imperative_relationships_overrides(self):
        overrides = {'person': {'name': 'Name'}}
        self.assertRaises(ValueError, SQLAlchemySchemaNode, Account, None,
                          None, overrides)
        overrides = {'person': {'typ': colander.Integer}}
        self.assertRaises(ValueError, SQLAlchemySchemaNode, Account, None,
                          None, overrides)
        overrides = {
            'person': {
                'children': [],
                'includes': ['id']
            },
        }
        schema = SQLAlchemySchemaNode(Account, overrides=overrides)
        self.assertEqual(schema['person'].children, [])
        overrides = {
            'person': {
                'includes': ['id']
            },
        }
        schema = SQLAlchemySchemaNode(Account, overrides=overrides)
        self.assertIn('id', schema['person'])
        self.assertEqual(len(schema['person'].children), 1)
        overrides = {
            'person': {
                'excludes': ['id']
            },
        }
        schema = SQLAlchemySchemaNode(Account, overrides=overrides)
        self.assertNotIn('id', schema['person'])

        overrides = {
            'addresses': {
                'overrides': {
                    'id': {
                        'typ': colander.Float
                    }
                }
            }
        }
        overrides = {
            'addresses': {
                'overrides': {
                    'id': {
                        'typ': colander.String
                    }
                }
            }
        }
        schema = SQLAlchemySchemaNode(Person, overrides=overrides)
        self.assertTrue(
            isinstance(schema['addresses'].children[0]['id'].typ,
                       colander.String))
Exemple #37
0
def get_individual_customer_schema():
    """
    return the schema for user add/edit regarding the current user's role
    """
    excludes = ('name', 'tva_intracomm', 'function', 'registration')
    schema = SQLAlchemySchemaNode(Customer, excludes=excludes)
    schema = _customize_schema(schema)
    schema['firstname'].title = u"Prénom"
    schema['lastname'].title = u'Nom'
    schema['civilite'].missing = colander.required
    schema['lastname'].missing = colander.required
    schema.after_bind = _customer_after_bind
    return schema
def get_individual_customer_schema():
    """
    return the schema for user add/edit regarding the current user's role
    """
    excludes = ('name', 'tva_intracomm', 'function', 'registration')
    schema = SQLAlchemySchemaNode(Customer, excludes=excludes)
    schema = _customize_schema(schema)
    schema['firstname'].title = u"Prénom"
    schema['lastname'].title = u'Nom'
    schema['civilite'].missing = colander.required
    schema['lastname'].missing = colander.required
    schema.after_bind = _customer_after_bind
    return schema
Exemple #39
0
def test_estimation_payment_lines():
    from autonomie.models.task.estimation import Estimation
    schema = SQLAlchemySchemaNode(Estimation, includes=('payment_lines', ))
    schema = schema.bind()

    value = {'payment_lines': []}
    with pytest.raises(colander.Invalid):
        schema.deserialize(value)

    value = {}
    with pytest.raises(colander.Invalid):
        schema.deserialize(value)

    value = {
        'payment_lines': [{
            'task_id': 5,
            'date': datetime.date.today().isoformat(),
            'amount': 12.5,
            'description': u"Description"
        }]
    }
    expected_value = {
        'payment_lines': [{
            'task_id': 5,
            'date': datetime.date.today(),
            'amount': 1250000,
            'description': u"Description",
            'order': 1
        }]
    }
    assert schema.deserialize(value) == expected_value
def get_sequence_model_admin(model, title=u"", excludes=(), **kw):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(
        model,
        widget=CleanMappingWidget(),
        excludes=excludes,
    )
    node_schema.name = 'data'

    colanderalchemy_config = getattr(model, '__colanderalchemy_config__', {})

    default_widget_options = dict(
        orderable=True,
        min_len=1,
    )
    widget_options = colanderalchemy_config.get('seq_widget_options', {})
    widget_options.update(kw.get('widget_options', {}))

    for key, value in widget_options.items():
        default_widget_options[key] = value

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(
            colander.Sequence(),
            node_schema,
            widget=CleanSequenceWidget(
                **default_widget_options
            ),
            title=title,
            name='datas')
    )

    def dictify(models):
        return {'datas': [node_schema.dictify(model) for model in models]}

    def objectify(datas):
        return [node_schema.objectify(data) for data in datas]

    schema.dictify = dictify
    schema.objectify = objectify
    return schema
Exemple #41
0
def get_sequence_model_admin(model, title=u"", excludes=(), **kw):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(
        model,
        widget=CleanMappingWidget(),
        excludes=excludes,
    )
    node_schema.name = 'data'

    colanderalchemy_config = getattr(model, '__colanderalchemy_config__', {})

    default_widget_options = dict(
        orderable=True,
        min_len=1,
    )
    widget_options = colanderalchemy_config.get('seq_widget_options', {})
    widget_options.update(kw.get('widget_options', {}))

    for key, value in widget_options.items():
        default_widget_options[key] = value

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(
            colander.Sequence(),
            node_schema,
            widget=CleanSequenceWidget(
                **default_widget_options
            ),
            title=title,
            name='datas')
    )

    def dictify(models):
        return {'datas': [node_schema.dictify(model) for model in models]}

    def objectify(datas):
        return [node_schema.objectify(data) for data in datas]

    schema.dictify = dictify
    schema.objectify = objectify
    return schema
Exemple #42
0
 def schema(self):
     return SQLAlchemySchemaNode(CompetenceGridSubItem,
                                 includes=(
                                     'evaluation',
                                     'id',
                                     'comments',
                                 ))
    def test_doc_example_deform(self):
        """
        Test 'using ColanderAlchemy with Deform' example found
        in docs/source/deform.rst
        """
        Base = declarative_base()

        class Phone(Base):
            __tablename__ = 'phones'

            person_id = Column(Integer, ForeignKey('persons.id'),
                               primary_key=True)
            number = Column(Unicode(128), primary_key=True)
            location = Column(Enum('home', 'work'))

        class Person(Base):
            __tablename__ = 'persons'

            id = Column(Integer, primary_key=True)
            name = Column(Unicode(128), nullable=False)
            surname = Column(Unicode(128), nullable=False)
            phones = relationship(Phone)

        schema = SQLAlchemySchemaNode(Person)

        # because of naming clashes, we need to do this in another function
        def generate_colander():
            class Phone(colander.MappingSchema):
                person_id = colander.SchemaNode(colander.Int())
                number = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(0, 128)
                )
                location = colander.SchemaNode(
                    colander.String(),
                    validator=colander.OneOf(['home', 'work']),
                    missing=colander.null
                )

            class Phones(colander.SequenceSchema):
                phones = Phone(missing=[])

            class Person(colander.MappingSchema):
                id = colander.SchemaNode(colander.Int(),
                                         missing=colander.drop)
                name = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(0, 128)
                )
                surname = colander.SchemaNode(
                    colander.String(),
                    validator=colander.Length(0, 128)
                )
                phones = Phones(missing=[])

            return Person()

        schema2 = generate_colander()

        self.is_equal_schema(schema, schema2)
Exemple #44
0
def get_sequence_model_admin(model, title=u"", excludes=(), **kw):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(
        model,
        widget=deform.widget.MappingWidget(
            template=TEMPLATES_URL + "clean_mapping.pt",
        ),
        excludes=excludes,
    )
    node_schema.name = 'data'

    default_widget_options = dict(
        orderable=True,
        template=TEMPLATES_URL + "clean_sequence.pt",
        min_len=1,
    )
    widget_options = kw.get('widget_options', {})
    for key, value in widget_options.items():
        default_widget_options[key] = value

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(
            colander.Sequence(),
            node_schema,
            widget=deform.widget.SequenceWidget(
                **default_widget_options
            ),
            title=title,
            name='datas')
    )

    def dictify(models):
        return {'datas': [node_schema.dictify(model) for model in models]}

    def objectify(datas):
        return [node_schema.objectify(data) for data in datas]

    schema.dictify = dictify
    schema.objectify = objectify
    return schema
Exemple #45
0
def get_user_schema(edit=False, permanent=True):
    """
    Return the schema for adding/editing users

        edit

            Is this an edit form

        permanent

            Is this form related to permanent edition (managers or admins)
    """
    if permanent:
        schema = SQLAlchemySchemaNode(user.User, excludes=('compte_tiers',))
    else:
        schema = SQLAlchemySchemaNode(user.User)

    if permanent:
        schema.insert(
            0,
            colander.SchemaNode(
                colander.Integer(),
                name='primary_group',
                validator=deferred_primary_group_validator,
                widget=deferred_primary_group_widget,
                title=u"Rôle de l'utilisateur",
            )
        )
        schema.add(
            CompanySchema(
                name='companies',
                title=u"Entreprise(s)",
                widget=deform.widget.SequenceWidget(
                    add_subitem_text_template=u"Ajouter une entreprise"
                )
            )
        )
    else:
        schema.add(
            colander.SchemaNode(
                colander.Set(),
                name="groups",
                validator=deferred_group_validator,
                widget=deferred_group_widget,
                title=u"Groupes de l'utilisateur",
            )
        )


    if edit:
        schema['login'].validator = deferred_login_validator
        schema['pwd'].missing = colander.drop
    else:
        schema['login'].validator = get_unique_login_validator()

    return schema
Exemple #46
0
def get_doctypes_form_schema(userdatas_model):
    """
    Returns a dynamically built form for doctypes registration
    """
    registrations = userdatas_model.doctypes_registrations
    node_schema = SQLAlchemySchemaNode(UserDatasSocialDocTypes)

    appstruct = {}
    form_schema = colander.Schema()

    for index, registration in enumerate(registrations):
        node = node_schema.clone()
        name = 'node_%s' % index
        node.name = name
        node.title = u''
        node['status'].title = registration.doctype.label
        form_schema.add(node)
        appstruct[name] = node_schema.dictify(registration)

    return form_schema, appstruct
Exemple #47
0
 def add_nodes(self, includes, excludes, overrides):
     SQLAlchemySchemaNode.add_nodes(self, includes, excludes, overrides)
     start = colander.SchemaNode(colander.Int(),
                                 name='start',
                                 title='Start',
                                 missing=0,
                                 default=0,
                                 validator=colander.Range(min=0))
     limit = colander.SchemaNode(colander.Int(),
                                 name='limit',
                                 title='Limit',
                                 missing=25,
                                 default=25,
                                 validator=colander.Range(min=1))
     values = [prop.key for prop in self.inspector.column_attrs]
     order_by = colander.SchemaNode(colander.String(),
                                    name='order_by',
                                    title='Order By',
                                    missing=values[0],
                                    default=values[0],
                                    validator=colander.OneOf(values))
     direction_values = ['asc', 'desc']
     validator = colander.OneOf(direction_values)
     direction = colander.SchemaNode(colander.String(),
                                     name='direction',
                                     title='Direction',
                                     missing='asc',
                                     default='asc',
                                     validator=validator)
     intersect = colander.SchemaNode(colander.Boolean(),
                                     name='intersect',
                                     title='Intersect Criterions',
                                     missing=True,
                                     default=True)
     self.order_by_values = values
     self.direction_values = direction_values
     self.add(start)
     self.add(limit)
     self.add(order_by)
     self.add(direction)
     self.add(intersect)
Exemple #48
0
    def test_dictify(self):
        import datetime
        overrides = {
            'person': {
                'includes': ['name', 'surname', 'gender', 'addresses'],
                'overrides': {
                    'addresses': {
                        'includes': ['street', 'city'],
                        'overrides': {
                            'city': {
                                'exclude': False
                            }
                        }
                    }
                }
            },
        }
        includes = ['email', 'enabled', 'created', 'timeout', 'person']
        schema = SQLAlchemySchemaNode(Account, includes=includes, overrides=overrides)
        #Add a non-SQLAlchemy field
        schema.add(colander.SchemaNode(colander.String, name='non_sql'))

        args = dict(street='My Street', city='My City')
        address = Address(**args)
        kws = dict(name='My Name', surname='My Surname', gender='M', addresses=[address])
        person = Person(**kws)
        params = dict(email='*****@*****.**',
                      enabled=True,
                      created=datetime.datetime.now(),
                      timeout=datetime.time(hour=00, minute=00),
                      person=person)
        account = Account(**params)
        dictified = schema.dictify(account)
        kws['addresses'] = [args]
        params['person'] = kws
        self.assertEqual(dictified, params)
        for key in params:
            self.assertIn(key, dictified)
            if key == 'person':
                for k in kws:
                    self.assertIn(k, dictified[key])
Exemple #49
0
    def test_defaultmissing_primarykey(self):
        """Ensure proper handling of empty values on primary keys
        """
        Base = declarative_base()

        class User(Base):
            __tablename__ = 'user'
            # the follwing is automatically made autoincrement=True
            id = Column(Integer, primary_key=True)

        schema = SQLAlchemySchemaNode(User)

        # from <FORM> result into SQLA; tests missing
        self.assertEqual(schema['id'].missing, colander.drop)
        deserialized = schema.deserialize({})
        self.assertNotIn('id', deserialized)

        # from SQLA result into <FORM>; tests default
        self.assertEqual(schema['id'].default, colander.null)
        serialized = schema.serialize({})
        self.assertIn('id', serialized)
        self.assertEqual(serialized['id'], colander.null)

        class Widget(Base):
            __tablename__ = 'widget'
            id = Column(String, primary_key=True)

        schema = SQLAlchemySchemaNode(Widget)

        # from <FORM> result into SQLA; tests missing
        self.assertEqual(schema['id'].missing, colander.required)
        self.assertRaises(colander.Invalid, schema.deserialize, {})

        # from SQLA result into <FORM>; tests default
        self.assertEqual(schema['id'].default, colander.null)
        serialized = schema.serialize({})
        self.assertIn('id', serialized)
        self.assertEqual(serialized['id'], colander.null)
Exemple #50
0
def get_sequence_model_admin(model, title=u""):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(
        model,
        widget=deform.widget.MappingWidget(
            template=TEMPLATES_URL + "clean_mapping.pt",
        )
    )
    node_schema.name = 'data'

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(
            colander.Sequence(),
            node_schema,
            widget=deform.widget.SequenceWidget(
                orderable=True,
                template=TEMPLATES_URL + "clean_sequence.pt",
            ),
            title=title,
            name='datas')
    )
    def dictify(models):
        return {'datas': [node_schema.dictify(model) for model in models]}

    def objectify(datas):
        return [node_schema.objectify(data) for data in datas]

    schema.dictify = dictify
    schema.objectify = objectify
    return schema
Exemple #51
0
def get_add_edit_schema(edit=False):
    """
    Add a form schema for login add/edit

    :returns: A colander form schema
    """
    schema = SQLAlchemySchemaNode(Login)
    set_widgets(schema)

    schema.add(
        colander.SchemaNode(
            colander.String(),
            name="primary_group",
            validator=_deferred_primary_group_validator,
            widget=_deferred_primary_group_widget,
            title=u"Rôle de l'utilisateur",
        )
    )
    schema.add(
        colander.SchemaNode(
            colander.Set(),
            name="groups",
            validator=_deferred_group_validator,
            widget=_deferred_group_widget,
            title=u"Droits spécifiques",
        )
    )

    if edit:
        schema['login'].validator = _deferred_login_validator
        schema['pwd_hash'].missing = colander.drop
        schema['user_id'].validator = _deferred_user_id_validator
    else:
        schema['user_id'].validator = _get_unique_user_id_validator()
        schema['login'].validator = _get_unique_login_validator()
    return schema
Exemple #52
0
def get_sequence_model_admin(model, title=u""):
    """
    Return a schema for configuring sequence of models

        model

            The SQLAlchemy model to configure
    """
    node_schema = SQLAlchemySchemaNode(model)
    node_schema.name = 'data'

    schema = colander.SchemaNode(colander.Mapping())
    schema.add(
        colander.SchemaNode(
            colander.Sequence(),
            node_schema,
            widget=deform_widget.SequenceWidget(
                min_len=1,
                orderable=True,
            ),
            title=title,
            name='datas')
    )
    return schema
Exemple #53
0
    def get_schema_from_relationship(self, prop, overrides):
        rel_node = SQLAlchemySchemaNode.get_schema_from_relationship(self,
                                                                     prop,
                                                                     overrides)
        if rel_node == None:
          return None

        name = prop.key
        if prop.uselist:
            comparators = [('', ''),
                           ('contains', 'contains'),
                           ('notcontains', 'not contains'),
                           ('__eq__', '=='),
                           ('__neq__', '!=')]
            default_comp = '__eq__'

        else:
            comparators = [('', ''),
                           ('__eq__', '=='),
                           ('__neq__', '!=')]
            default_comp = '__eq__'

        self.comparators[name] = comparators
        validator = colander.OneOf([v[0] for v in comparators if v[0]])
        # Create the right node!
        rel_node.name = 'value'
        rel_node.title = rel_node.title.title()
        comp_node = colander.SchemaNode(colander.String(),
                                        name='comparator',
                                        title='Comparator',
                                        missing=default_comp,
                                        default=default_comp,
                                        validator=validator)
        mapping_name = '{}_criterion'.format(name)
        mapping_title = '{} Criterion'.format(title)
        return colander.SchemaNode(colander.Mapping(),
                                   rel_node,
                                   comp_node,
                                   name=mapping_name,
                                   title=mapping_title)
def get_admin_income_statement_measure_schema(total=False):
    """
    Build the schema for income statement measure type edit/add

    Total types are more complex and can be :

        * The sum of categories
        * A list of account prefix (like the common type of measure_types)
    """
    if total:
        schema = SQLAlchemySchemaNode(
            IncomeStatementMeasureType,
            includes=(
                "category_id",
                'label',
                "account_prefix",
                'is_total',
                'order',
            ),
        )
        schema['label'].validator = deferred_label_validator
        schema['is_total'].widget = deform.widget.HiddenWidget()
        schema.add_before(
            'account_prefix',
            colander.SchemaNode(
                colander.String(),
                name="total_type",
                title=u"Cet indicateur est il définit comme :",
                widget=deform_extensions.RadioChoiceToggleWidget(
                    values=(
                        (
                            "categories",
                            u"la somme des indicateurs de une ou plusieurs "
                            u"catégories ?",
                            "categories",
                        ),
                        (
                            "account_prefix",
                            u"un groupement d'écritures ?",
                            "account_prefix",
                        ),
                        (
                            "complex_total",
                            u"le résultat d'une formule arithmétique basée sur "
                            u"les catégories et les indicateurs ?",
                            "complex_total",
                        ),
                    )
                ),
                missing=colander.drop,
            )
        )
        schema['account_prefix'].missing = ""

        schema.add(
            colander.SchemaNode(
                colander.String(),
                name="complex_total",
                title=u"Combinaison complexe de catégories et d'indicateurs",
                description=deferred_complexe_total_description,
                validator=complex_total_validator,
                missing=""
            )
        )

        schema.add(
            colander.SchemaNode(
                CsvTuple(),
                name="categories",
                title=u"Somme des catégories",
                description=u"Représentera la somme des catégories "
                u"sélectionnées",
                widget=deferred_categories_widget,
            )
        )
    else:
        schema = SQLAlchemySchemaNode(
            IncomeStatementMeasureType,
            excludes=('is_total', "categories")
        )
        schema['label'].validator = deferred_label_validator
    return schema
Exemple #55
0
from sqlalchemy import Column, String, Text
from colander import null
from colanderalchemy import SQLAlchemySchemaNode
from deform.widget import RichTextWidget, HiddenWidget, PasswordWidget

from terms.server.schemata import Schema


class Person(Schema):

    name = Column(String())
    surname = Column(String())
    password = Column(String())

PersonSchema = SQLAlchemySchemaNode(Person)

PersonSchema.get('id').widget = HiddenWidget()
PersonSchema.get('_id').widget = HiddenWidget()
PersonSchema.get('ntype').widget = HiddenWidget()


class PasswordWidget(PasswordWidget):

    def deserialize(self, field, pstruct):
        value = super(PasswordWidget, self).deserialize(field, pstruct)
        if isinstance(value, basestring) and len(value) == 60:
            return value
        try:
            return bcrypt.hashpw(value, bcrypt.gensalt())
        except TypeError:
Exemple #56
0
    def get_schema_from_column(self, prop, overrides):
        col_node = SQLAlchemySchemaNode.get_schema_from_column(self,
                                                               prop,
                                                               overrides)
        col_node.missing = colander.null
        col_node.default = colander.null
        name = prop.key
        column = prop.columns[0]
        column_type = getattr(column.type, 'impl', column.type)
        type_ = colander.String()
        if isinstance(column_type, (Boolean, Enum)):
            comparators = [('', ''),
                           ('__eq__', '=='),
                           ('__neq__', '!=')]
            default_comp = '__eq__'

        elif isinstance(column_type, String):
            comparators = [('', ''),
                           ('like', 'like'),
                           ('ilike', 'ilike')]
            default_comp = 'like'

        elif isinstance(column_type, (Date,
                                      DateTime,
                                      Time)):
            comparators = [('', ''),
                           ('__lt__', '<'),
                           ('__lte__', '<='),
                           ('__eq__', '=='),
                           ('__neq__', '!='),
                           ('__gte__', '>='),
                           ('__gt__', '>')]
            default_comp = '__gte__'

        elif isinstance(column_type, (Float,
                                      Integer,
                                      Numeric)):
            comparators = [('', ''),
                           ('__lt__', '<'),
                           ('__lte__', '<='),
                           ('__eq__', '=='),
                           ('__neq__', '!='),
                           ('__gte__', '>='),
                           ('__gt__', '>')]
            default_comp = '__eq__'

        else:
            raise NotImplementedError('Unknown type: %s' % column_type)

        self.comparators[name] = comparators
        validator = colander.OneOf([v[0] for v in comparators if v[0]])
        # Create right node!
        col_node.title = col_node.title.title()
        comp_node = colander.SchemaNode(colander.String(),
                                        name='comparator',
                                        title='Comparator',
                                        missing=default_comp,
                                        default=default_comp,
                                        validator=validator)
        mapping_name = '{}_criterion'.format(name)
        mapping_title = ''  # '{} Criterion'.format(title)
        return colander.SchemaNode(colander.Mapping(),
                                   col_node,
                                   comp_node,
                                   name=mapping_name,
                                   title=mapping_title)