Beispiel #1
0
        class Test(Base):
            __tablename__ = 'test15'

            id = sqla.Column('id', sqla.Integer, primary_key=True)
            data = sqla.Column(ptah.JsonListType())
Beispiel #2
0
class Node(Base):
    """ Base class for persistent objects.

    .. attribute:: __uri__

       Unique object id. **Required**

    .. attribute:: __type__

       Type information object :py:class:`ptah.cms.TypeInformation`

    .. attribute:: __parent__

       Parent of node. Ptah doesn't load `__parent__` automatically.
       To load node parents use :py:func:`ptah.cms.load_parents` function.

    .. attribute:: __owner__

       URI of owner principal. It possible to load principal object
       by using :py:func:`ptah.resolve` function.

    .. attribute:: __local_roles__

       :py:class:`ptah.JsonDictType` which contains a principal uri as a
       key and a sequence of role's granted to principal for Node.

    .. attribute:: __acls__

       a :py:class:`ptah.JsonListType` of :py:class:`ptah.ACL` strings
       registered with security machinery.

    .. attribute:: __uri_factory__

       function which will return value for __uri__.  the uri must be
       resolvable by using :py:func:`ptah.resolve` function.

    """

    __tablename__ = 'ptah_nodes'

    __id__ = sqla.Column('id', sqla.Integer, primary_key=True)
    __type_id__ = sqla.Column('type', sqla.String, info={'uri': True})
    __type__ = None

    __uri__ = sqla.Column('uri',
                          sqla.String,
                          unique=True,
                          nullable=False,
                          info={'uri': True})
    __parent_uri__ = sqla.Column('parent',
                                 sqla.String,
                                 sqla.ForeignKey(__uri__),
                                 info={'uri': True})

    __owner__ = sqla.Column('owner',
                            sqla.String,
                            default=text_type(''),
                            info={'uri': True})
    __local_roles__ = sqla.Column('roles', ptah.JsonDictType(), default={})
    __acls__ = sqla.Column('acls', ptah.JsonListType(), default=[])

    __children__ = sqla.orm.relationship('Node',
                                         backref=sqla.orm.backref(
                                             '__parent_ref__',
                                             remote_side=[__uri__]))

    __mapper_args__ = {'polymorphic_on': __type_id__}

    __parent__ = None
    __uri_factory__ = None

    __acl__ = ptah.ACLsProperty()

    def __init__(self, **kw):
        self.__owners__ = []
        self.__local_roles__ = {}
        self.__permissions__ = []

        for attr, value in kw.items():
            setattr(self, attr, value)

        if '__parent__' in kw and kw['__parent__'] is not None:
            self.__parent_uri__ = kw['__parent__'].__uri__

        try:
            self.__uri__ = self.__uri_factory__()
        except TypeError:
            raise TypeError('Subclass of Node has to override __uri_factory__')

    @action(permission=View)
    def info(self):
        info = OrderedDict((
            ('__type__', self.__type_id__),
            ('__content__', False),
            ('__uri__', self.__uri__),
            ('__parents__', [p.__uri__ for p in load_parents(self)]),
        ))

        return info
Beispiel #3
0
        class Test2(ptah.get_base()):
            __tablename__ = 'test5'

            id = sqla.Column('id', sqla.Integer, primary_key=True)
            name = sqla.Column(sqla.Unicode())
            json = sqla.Column(ptah.JsonListType())
Beispiel #4
0
class BaseContent(Node):
    """ Base class for content objects. A content class should inherit from
    `Content` to participate in content hierarchy traversal.

    .. attribute:: __path__

       A string used by the :py:class:`ptah.cms.ContentTraverser` which is
       used for efficient resolution of URL structure to content models.
       This is internal implementation and manually editing it can break
       your hierarchy.

    .. attribute:: __name__

       This is the identifier in a container if you are using containment and
       hierarchies.

    .. attribute:: title

       Content title which is editable by end user.

    .. attribute:: description

       Content description which is editable by end user.

    .. attribute:: view

       A URI which can be resolved with :py:func:`ptah.resolve` function
       which represents the 'default' view for content. Akin to index.html
       or default.php in Apache.

    .. attribute:: created

       Content creation time which is set by
       :py:func:`ptah.cms.content.createdHandler` during object creation.

       :type: :py:class:`datetime.datetime`

    .. attribute:: modified

       Content modification time which is set by
       :py:func:`ptah.cms.content.modifiedHandler` during object modification.

       :type: :py:class:`datetime.datetime`

    .. attribute:: effective

       :type: :py:class:`datetime.datetime` or None

    .. attribute:: expires

       :type: :py:class:`datetime.datetime` or None

    .. attribute:: creators

       a :py:class:`ptah.JsonListType` which contains sequence of users.  Using
       principal URIs is a good idea.

    .. attribute:: subjects

       a :py:class:`ptah.JsonListType` which contains sequence of subjects.
       Holding a sequence of URIs could resolve to subject objects. Or you can
       use strings.

    .. attribute: publisher

       a Unicode string which should identify the publisher.

    .. attribute: contributors

       a :py:class:`ptah.JsonListType` which contains sequence of contributors.
       You could keep a sequence of principal URIs.
    """

    __tablename__ = 'ptah_content'

    __id__ = sqla.Column('id',
                         sqla.Integer,
                         sqla.ForeignKey('ptah_nodes.id'),
                         primary_key=True)
    __path__ = sqla.Column('path', sqla.Unicode, default=text_type(''))
    __name_id__ = sqla.Column('name', sqla.Unicode(255))

    title = sqla.Column(sqla.Unicode, default=text_type(''))
    description = sqla.Column(sqla.Unicode,
                              default=text_type(''),
                              info={
                                  'missing': '',
                                  'field_type': 'textarea'
                              })
    view = sqla.Column(sqla.Unicode, default=text_type(''))

    created = sqla.Column(sqla.DateTime)
    modified = sqla.Column(sqla.DateTime)
    effective = sqla.Column(sqla.DateTime)
    expires = sqla.Column(sqla.DateTime)

    creators = sqla.Column(ptah.JsonListType(), default=[])
    subjects = sqla.Column(ptah.JsonListType(), default=[])
    publisher = sqla.Column(sqla.Unicode, default=text_type(''))
    contributors = sqla.Column(ptah.JsonListType(), default=[])

    # sql queries
    _sql_get = ptah.QueryFreezer(lambda: Session.query(BaseContent).filter(
        BaseContent.__uri__ == sqla.sql.bindparam('uri')))

    _sql_get_in_parent = ptah.QueryFreezer(
        lambda: Session.query(BaseContent).filter(
            BaseContent.__name_id__ == sqla.sql.bindparam('key')).filter(
                BaseContent.__parent_uri__ == sqla.sql.bindparam('parent')))

    _sql_parent = ptah.QueryFreezer(lambda: Session.query(BaseContent).filter(
        BaseContent.__uri__ == sqla.sql.bindparam('parent')))

    def __init__(self, **kw):
        super(BaseContent, self).__init__(**kw)

        if self.__name__ and self.__parent__ is not None:
            self.__path__ = '%s%s/' % (self.__parent__.__path__, self.__name__)

    @hybrid_property
    def __name__(self):
        return self.__name_id__

    @__name__.setter
    def __name__(self, value):
        self.__name_id__ = value

    def __resource_url__(self, request, info):
        return '%s%s' % (request.root.__root_path__,
                         self.__path__[len(request.root.__path__):])

    @action(permission=DeleteContent)
    def delete(self):
        parent = self.__parent__
        if parent is None:
            parent = self.__parent_ref__

        if parent is None:
            raise Error("Can't find parent")

        del parent[self]

    @action(permission=ModifyContent)
    def update(self, **data):
        if self.__type__:
            tinfo = self.__type__

            for field in tinfo.fieldset.fields():
                val = data.get(field.name, field.default)
                if val is not ptah.form.null:
                    setattr(self, field.name, val)

            get_current_registry().notify(
                ptah.events.ContentModifiedEvent(self))

    def _extra_info(self, info):
        if self.__type__:
            fieldset = self.__type__.fieldset.bind()
            for field in fieldset.fields():
                val = getattr(self, field.name, field.default)
                info[field.name] = field.serialize(val)

        info['view'] = self.view
        info['created'] = self.created
        info['modified'] = self.modified
        info['effective'] = self.effective
        info['expires'] = self.expires

    def info(self):
        info = super(BaseContent, self).info()
        info['__name__'] = self.__name__
        info['__content__'] = True
        info['__container__'] = False
        self._extra_info(info)
        return info