Edit me on GitHub

substanced API

substanced.includeme(config)

Do the work of substanced.include(), then substanced.scan(). Makes config.include(substanced) work.

substanced.include(config)

Perform all config.include tasks required for Substance D and the default aspects of the SDI to work.

substanced.scan(config)

Perform all config.scan tasks required for Substance D and the default aspects of the SDI to work.

substanced.audit API

class substanced.audit.AuditLog(max_layers=10, layer_size=100, entries=None)
add(_name, _oid, **kw)

Add a record the audit log. _name should be the event name, _oid should be an object oid or None, and kw should be a json-serializable dictionary

latest_id()

Return the generation and the index id as a tuple, representing the latest audit log entry

newer(generation, index_id, oids=None)

Return the events newer than the combination of generation and oid. Filter using oids if supplied.

substanced.catalog API

class substanced.catalog.Text(**kw)
class substanced.catalog.Field(**kw)
class substanced.catalog.Keyword(**kw)
class substanced.catalog.Facet(**kw)
class substanced.catalog.Allowed(**kw)
class substanced.catalog.Path(**kw)
class substanced.catalog.Catalog(family=None)
__setitem__(name, other)

Set object other into this folder under the name name.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding.

name cannot be the empty string.

When other is seated into this folder, it will also be decorated with a __parent__ attribute (a reference to the folder into which it is being seated) and __name__ attribute (the name passed in to this function. It must not already have a __parent__ attribute before being seated into the folder, or an exception will be raised.

If a value already exists in the foldr under the name name, raise KeyError.

When this method is called, the object will be added to the objectmap, an substanced.event.ObjectWillBeAdded event will be emitted before the object obtains a __name__ or __parent__ value, then a substanced.event.ObjectAdded will be emitted after the object obtains a __name__ and __parent__ value.

__getitem__(name)

Return the object named name added to this folder or raise KeyError if no such object exists. name must be a Unicode object or directly decodeable to Unicode using the system default encoding.

Retrieve an index.

get(name, default=None)

Return the object named by name or the default.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding.

Retrieve an index or return failobj.

flush(all=True)

Flush pending indexing actions for all indexes in this catalog.

If all is True, all pending indexing actions will be immediately executed regardless of the action’s mode.

If all is False, pending indexing actions which are MODE_ATCOMMIT will be executed but actions which are MODE_DEFERRED will not be executed.

index_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using oid as the indexing identifier. If oid is not supplied, the __oid__ attribute of the resource will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED, indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

reindex(dry_run=False, commit_interval=3000, indexes=None, path_re=None, output=None, registry=None)

Reindex all objects in the catalog using the existing set of indexes immediately.

If dry_run is True, do no actual work but send what would be changed to the logger.

commit_interval controls the number of objects indexed between each call to transaction.commit() (to control memory consumption).

indexes, if not None, should be a list of index names that should be reindexed. If indexes is None, all indexes are reindexed.

path_re, if it is not None should be a regular expression object that will be matched against each object’s path. If the regular expression matches, the object will be reindexed, if it does not, it won’t.

output, if passed should be one of None, False or a function. If it is a function, the function should accept a single message argument that will be used to record the actions taken during the reindex. If False is passed, no output is done. If None is passed (the default), the output will wind up in the substanced.catalog Python logger output at info level.

registry, if passed, should be a Pyramid registry. If one is not passed, the get_current_registry() function will be used to look up the current registry. This function needs the registry in order to access content catalog views.

reindex_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using oid as the indexing identifier. If oid is not supplied, the __oid__ attribute of resource will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

The result of calling this method is logically the same as calling unindex_resource, then index_resource with the same resource, but calling those two methods in succession is often more expensive than calling this single method, as member indexes can choose to do smarter things during a reindex than what they would do during an unindex followed by a successive index.

reset()

Reset all indexes in this catalog and clear self.objectids.

transaction = <module 'transaction' from '/home/docs/checkouts/readthedocs.org/user_builds/substanced/envs/latest/local/lib/python2.7/site-packages/transaction/__init__.pyc'>
unindex_resource(resource_or_oid, action_mode=None)

Deregister the resource in indexes of this catalog using the indexing identifier resource_or_oid. If resource_or_oid is an integer, it will be used as the indexing identifier; if resource_or_oid is a resource, its __oid__ attribute will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

update_indexes(registry=None, dry_run=False, output=None, replace=False, reindex=False, **reindex_kw)

Use the candidate indexes registered via config.add_catalog_factory to populate this catalog. Any indexes which are present in the candidate indexes, but not present in the catalog will be created. Any indexes which are present in the catalog but not present in the candidate indexes will be deleted.

registry, if passed, should be a Pyramid registry. If one is not passed, the get_current_registry() function will be used to look up the current registry. This function needs the registry in order to access content catalog views.

If dry_run is True, don’t commit the changes made when this function is called, just send what would have been done to the logger.

output, if passed should be one of None, False or a function. If it is a function, the function should accept a single message argument that will be used to record the actions taken during the reindex. If False is passed, no output is done. If None is passed (the default), the output will wind up in the substanced.catalog Python logger output at info level.

This function does not reindex new indexes added to the catalog unless reindex=True is passed.

Arguments to this method captured as kw are passed to substanced.catalog.Catalog.reindex() if reindex is True, otherwise kw is ignored.

If replace is True, an existing catalog index that is not in the category supplied but which has the same name as a candidate index will be replaced. If replace is False, existing indexes will never be replaced.

class substanced.catalog.CatalogsService(data=None, family=None)
class Catalog(family=None)
flush(all=True)

Flush pending indexing actions for all indexes in this catalog.

If all is True, all pending indexing actions will be immediately executed regardless of the action’s mode.

If all is False, pending indexing actions which are MODE_ATCOMMIT will be executed but actions which are MODE_DEFERRED will not be executed.

index_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using oid as the indexing identifier. If oid is not supplied, the __oid__ attribute of the resource will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED, indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

reindex(dry_run=False, commit_interval=3000, indexes=None, path_re=None, output=None, registry=None)

Reindex all objects in the catalog using the existing set of indexes immediately.

If dry_run is True, do no actual work but send what would be changed to the logger.

commit_interval controls the number of objects indexed between each call to transaction.commit() (to control memory consumption).

indexes, if not None, should be a list of index names that should be reindexed. If indexes is None, all indexes are reindexed.

path_re, if it is not None should be a regular expression object that will be matched against each object’s path. If the regular expression matches, the object will be reindexed, if it does not, it won’t.

output, if passed should be one of None, False or a function. If it is a function, the function should accept a single message argument that will be used to record the actions taken during the reindex. If False is passed, no output is done. If None is passed (the default), the output will wind up in the substanced.catalog Python logger output at info level.

registry, if passed, should be a Pyramid registry. If one is not passed, the get_current_registry() function will be used to look up the current registry. This function needs the registry in order to access content catalog views.

reindex_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using oid as the indexing identifier. If oid is not supplied, the __oid__ attribute of resource will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

The result of calling this method is logically the same as calling unindex_resource, then index_resource with the same resource, but calling those two methods in succession is often more expensive than calling this single method, as member indexes can choose to do smarter things during a reindex than what they would do during an unindex followed by a successive index.

reset()

Reset all indexes in this catalog and clear self.objectids.

transaction = <module 'transaction' from '/home/docs/checkouts/readthedocs.org/user_builds/substanced/envs/latest/local/lib/python2.7/site-packages/transaction/__init__.pyc'>
unindex_resource(resource_or_oid, action_mode=None)

Deregister the resource in indexes of this catalog using the indexing identifier resource_or_oid. If resource_or_oid is an integer, it will be used as the indexing identifier; if resource_or_oid is a resource, its __oid__ attribute will be used as the indexing identifier.

action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED indicating when the updates should take effect. The action_mode value will overrule any action mode a member index has been configured with except None which explicitly indicates that you’d like to use the index’s action_mode value.

update_indexes(registry=None, dry_run=False, output=None, replace=False, reindex=False, **reindex_kw)

Use the candidate indexes registered via config.add_catalog_factory to populate this catalog. Any indexes which are present in the candidate indexes, but not present in the catalog will be created. Any indexes which are present in the catalog but not present in the candidate indexes will be deleted.

registry, if passed, should be a Pyramid registry. If one is not passed, the get_current_registry() function will be used to look up the current registry. This function needs the registry in order to access content catalog views.

If dry_run is True, don’t commit the changes made when this function is called, just send what would have been done to the logger.

output, if passed should be one of None, False or a function. If it is a function, the function should accept a single message argument that will be used to record the actions taken during the reindex. If False is passed, no output is done. If None is passed (the default), the output will wind up in the substanced.catalog Python logger output at info level.

This function does not reindex new indexes added to the catalog unless reindex=True is passed.

Arguments to this method captured as kw are passed to substanced.catalog.Catalog.reindex() if reindex is True, otherwise kw is ignored.

If replace is True, an existing catalog index that is not in the category supplied but which has the same name as a candidate index will be replaced. If replace is False, existing indexes will never be replaced.

add_catalog(name, update_indexes=True)

Create and add a catalog named name to this catalogs service. Return the newly created catalog object. If a catalog named name already exists in this catalogs service, an exception will be raised.

Example usage in a root created subscriber:

@subscribe_created(content_type='Root')
def created(event):
    root = event.object
    service = root['catalogs']
    catalog = service.add_catalog('app1', update_indexes=True)

If update_indexes is True, indexes in the named catalog factory will be added to the newly created catalog.

substanced.catalog.is_catalogable(resource, registry=None)
substanced.catalog.catalog_factory(name)

Decorator for a class which acts as a template for index creation.:

from substanced.catalog import Text

@catalog_factory('myapp')
class MyAppIndexes(object):
    text = Text()
    title = Field()

When scanned, this catalog factory will be added to the registry as if substanced.catalog.add_catalog_factory() were called like:

config.add_catalog_factory('myapp', MyAppIndexes)
substanced.catalog.includeme(config)
substanced.catalog.add_catalog_factory(config, name, cls)

Directive which adds a named catalog factory to the configuration state. The cls argument should be a class that has named index factory instances as attributes. The name argument should be a string.

substanced.catalog.add_indexview(self, *arg, **kw)

Directive which adds an index view to the configuration state state. The view argument should be function that is an indeview function, or or a class with a __call__ method that acts as an indexview method. For example:

def title(resource, default):
    return getattr(resource, 'title', default)

config.add_indexview(title, catalog_name='myapp', index_name='title')

Or, a class:

class IndexViews(object):
    def __init__(self, resource):
        self.resource = resource

    def __call__(self, default):
        return getattr(self.resource, 'title', default)

config.add_indexview(
    IndexViews, catalog_name='myapp', index_name='title'
    )

If an attr arg is supplied to add_indexview, you can use a different attribute of the class instad of __call__:

class IndexViews(object):
    def __init__(self, resource):
        self.resource = resource

    def title(self, default):
        return getattr(self.resource, 'title', default)

    def name(self, default):
        return getattr(self.resource, 'name', default)

config.add_indexview(
    IndexViews, catalog_name='myapp', index_name='title', attr='title'
    )
config.add_indexview(
    IndexViews, catalog_name='myapp', index_name='name', attr='name'
    )

In this way you can use the same class to represent a bunch of different index views. An index view will be looked up by the cataloging machinery when it wants to insert value into a particular catalog type’s index. The catalog_name you use specify which catalog name this indeview is good for; it should match the string passed to add_catalog_factory as a name. The index_name argument should match an index name used within such a catalog.

Index view lookups work a bit like Pyramid view lookups: you can use the context argument to pass an interface or class which should be used to register the index view; such an index view will only be used when the resource being indexed has that class or interface. Eventually we’ll provide a way to add predicates other than context too.

The substanced.catalog.indexview decorator provides a declarative analogue to using this configuration directive.

class substanced.catalog.indexview(**settings)

A class decorator which, when applied to an index view class method, will mark the method as an index view. This decorator accepts all the arguments accepted by substanced.catalog.add_indexview(), and each has the same meaning.

class substanced.catalog.indexview_defaults(**settings)

A class decorator which, when applied to a class, will provide defaults for all index view configurations defined in the class. This decorator accepts all the arguments accepted by substanced.catalog.indexview(), and each has the same meaning.

substanced.catalog.indexes API

class substanced.catalog.indexes.FieldIndex(discriminator=None, family=None, action_mode=None)
class substanced.catalog.indexes.KeywordIndex(discriminator=None, family=None, action_mode=None)
class substanced.catalog.indexes.TextIndex(discriminator=None, lexicon=None, index=None, family=None, action_mode=None)
class substanced.catalog.indexes.FacetIndex(discriminator=None, facets=None, family=None, action_mode=None)
class substanced.catalog.indexes.PathIndex(discriminator=None, family=None)

Uses the substanced.objectmap.ObjectMap.pathlookup() to apply a query to retrieve object identifiers at or under a path.

path can be passed to methods as:

  • resource object
  • tuple of strings (usually returned value of pyramid.traverse.resource_path_tuple())
  • a string path (e.g. /foo/bar)

Query methods accept following parameters:

Query types supported:

  • Eq
  • NotEq
class substanced.catalog.indexes.AllowedIndex(discriminator, family=None)

An index which defers to objectmap.allowed as part of a query intersection.

allows(principals, permission)

principals may either be 1) a sequence of principal indentifiers, 2) a single principal identifier, or 3) a Pyramid request, which indicates that all the effective principals implied by the request are used.

permission must be a permission name.

hypatia.query API

Comparators

class hypatia.query.Contains(index, value)

Contains query.

CQE equivalent: ‘foo’ in index

class hypatia.query.Eq(index, value)

Equals query.

CQE equivalent: index == ‘foo’

class hypatia.query.NotEq(index, value)

Not equal query.

CQE eqivalent: index != ‘foo’

class hypatia.query.Gt(index, value)

Greater than query.

CQE equivalent: index > ‘foo’

class hypatia.query.Lt(index, value)

Less than query.

CQE equivalent: index < ‘foo’

class hypatia.query.Ge(index, value)

Greater (or equal) query.

CQE equivalent: index >= ‘foo’

class hypatia.query.Le(index, value)

Less (or equal) query.

CQE equivalent: index <= ‘foo

class hypatia.query.Contains(index, value)

Contains query.

CQE equivalent: ‘foo’ in index

class hypatia.query.NotContains(index, value)

CQE equivalent: ‘foo’ not in index

class hypatia.query.Any(index, value)

Any of query.

CQE equivalent: index in any([‘foo’, ‘bar’])

class hypatia.query.NotAny(index, value)

Not any of query (ie, None of query)

CQE equivalent: index not in any([‘foo’, ‘bar’])

class hypatia.query.All(index, value)

All query.

CQE equivalent: index in all([‘foo’, ‘bar’])

class hypatia.query.NotAll(index, value)

NotAll query.

CQE equivalent: index not in all([‘foo’, ‘bar’])

class hypatia.query.InRange(index, start, end, start_exclusive=False, end_exclusive=False)

Index value falls within a range.

CQE eqivalent: lower < index < upper
lower <= index <= upper
class hypatia.query.NotInRange(index, start, end, start_exclusive=False, end_exclusive=False)

Index value falls outside a range.

CQE eqivalent: not(lower < index < upper)
not(lower <= index <= upper)

Boolean Operators

class hypatia.query.Or(*queries)

Boolean Or of multiple queries.

class hypatia.query.And(*queries)

Boolean And of multiple queries.

class hypatia.query.Not(query)

Negation of a query.

Other Helpers

class hypatia.query.Name(name)

A variable name in an expression, evaluated at query time. Can be used to defer evaluation of variables used inside of expressions until query time.

Example:

from hypatia.query import Eq
from hypatia.query import Name

# Define query at module scope
find_cats = Eq('color', Name('color')) & Eq('sex', Name('sex'))

# Use query in a search function, evaluating color and sex at the
# time of the query
def search_cats(catalog, resolver, color='tabby', sex='female'):
    # Let resolver be some function which can retrieve a cat object
    # from your application given a docid.
    params = dict(color=color, sex=sex)
    count, docids = catalog.query(find_cats, params)
    for docid in docids:
        yield resolver(docid)
hypatia.query.parse_query(expr, catalog, optimize_query=True)

Parses the given expression string and returns a query object. Requires Python >= 2.6.

hypatia.util API

class hypatia.util.ResultSet(ids, numids, resolver, sort_type=None)

Implements hypatia.interfaces.IResultSet

intersect(docids)

Intersect this resultset with a sequence of docids or another resultset. Returns a new ResultSet.

interface hypatia.interfaces.IResultSet

Iterable sequence of documents or document identifiers.

sort(index, reverse=False, limit=None, sort_type=None, raise_unsortable=True)

Return another IResultSet sorted using the index (an IIndexSort) passed to it after performing the sort using the index and the limit, reverse, and sort_type parameters.

If sort_type is not None, it should be the value hypatia.interfaces.STABLE to specify that the sort should be stable or hypatia.interfaces.OPTIMAL to specify that the sort algorithm chosen should be optimal (but not necessarily stable). It’s usually unnecessary to pass this value, even if you’re resorting an already-sorted set of docids, because the implementation of IResultSet will internally ensure that subsequent sorts of the returned result set of an initial sort will be stable; if you don’t want this behavior, explicitly pass hypatia.interfaces.OPTIMAL on the second and subsequent sorts of a set of docids.

If raise_unsortable is True (the default), if the index cannot resolve any of the docids in the set of docids in this result set, a hypatia.exc.Unsortable exception will be raised during iteration over the sorted docids.

all(resolve=True)

Return a sequence representing all elements in the resultset. If ``resolve` is True, and the result set has a valid resolver, return an iterable of the resolved documents, otherwise return an iterable containing the document id of each document.

ids

An iterable sequence of document identifiers

one(resolve=True)

Return the element in the resultset, asserting that there is only one result. If the resultset has more than one element, raise an hypatia.exc.MultipleResults exception. If the resultset has no elements, raise an hypatia.exc.NoResults exception. If ``resolve` is True, and the result set has a valid resolver, return the resolved document, otherwise return the document id of the document.

__iter__()

Return an iterator over the results of self.all()

resolver

A callable which accepts a document id and which returns a document. May be None, in which case, resolution performed by result set methods is not performed, and document identifiers are returned unresolved.

__len__()

Return the length of the result set

first(resolve=True)

Return the first element in the sequence. If resolve is True, and the result set has a valid resolver, return the resolved document, otherwise return the document id of the first document.

substanced.content API

class substanced.content.content(content_type, factory_type=None, **meta)

Use as a decorator for a content factory (usually a class). Accepts a content type, a factory type (optionally), and a set of meta keywords. These values mean the same thing as they mean for substanced.content.add_content_type(). This decorator attaches information to the object it decorates which is used to call add_content_type() during a scan.

class substanced.content.service(content_type, factory_type=None, **meta)

This class is meant to be used as a decorator for a content factory that creates a service object (aka a service factory). A service object is an instance of a content type that can be looked up by name and which provides a service to application code. Services have well-known names within a folder. For example, the principals service within a folder is ‘the principals service’, the catalog object within a folder is ‘the catalog service’ and so on.

This decorator accepts a content type, a factory type (optionally), and a set of meta keywords. These values mean the same thing as they mean for the substanced.content.content decorator and substanced.content.add_content_type(). The decorator attaches information to the object it decorates which is used to call add_content_type() during a scan.

There is only one difference between using the substanced.content.content decorator and the substanced.service.service decorator. The service decorator honors a service_name keyword argument. If this argument is passed, and a service already exists in the folder by this name, the service will not be shown as addable in the add-content dropdown in the SDI UI.

substanced.content.add_content_type(config, content_type, factory, factory_type=None, **meta)

Configurator directive method which register a content type factory with the Substance D type system. Call via config.add_content_type during Pyramid configuration phase.

content_type is a hashable object (usually a string) representing the content type.

factory is a class or function which produces a content instance. It must be a global object (e.g. it cannot be a callable which is a method of a class or a callable instance). If factory is a function rather than a class, a factory wrapper is used (see below).

**meta is an arbitrary set of keywords associated with the content type in the content registry.

Some of the keywords in **meta have special meaning:

  • If meta contains the keyword propertysheets, the content type will obtain a tab in the SDI that allows users to manage its properties.
  • If meta contains the keyword icon, this value will be used as the icon for the content type that shows up next to the content in a folder content view.

Other keywords in meta will just be stored, and have no special meaning.

factory_type is an optional argument that can be used if the same factory must be used for two different content types; it is used during content type lookup (e.g. substanced.util.get_content_type()) to figure out which content type a constructed object is an instance of; it only needs to be used when the same factory is used for two different content types. Note that two content types cannot have the same factory type, unless it is None.

If factory_type is passed, the supplied factory will be wrapped in a factory wrapper which adds a __factory_type__ attribute to the constructed instance. The value of this attribute will be used to determine the content type of objects created by the factory.

If the factory is a function rather than a class, a factory wrapper is used unconditionally.

The upshot wrt to factory_type: if your factory is a class and you pass a factory_type or if your factory is a function, you won’t be able to successfully use the ‘bare’ factory callable to construct an instance of this content in your code, because the resulting instance will not have a __factory_type__ attribute. Instead, you’ll be required to use substanced.content.Content.create() to create an instance of the object with a proper __factory_type__ attribute. But if your factory is a class, and you don’t pass factory_type (the ‘garden path’), you’ll be able to use the class’ constructor directly in your code to create instances of your content objects, which is more convenient and easier to unit test.

substanced.content.add_service_type(config, content_type, factory, factory_type=None, **meta)

Configurator directive method which registers a service factory. Call via config.add_service_type during Pyramid configuration phase. All arguments mean the same thing as they mean for the substanced.content.add_content_type.

A service factory is a special kind of content factory. A service factory creates a service object. A service object is an instance of a content type that can be looked up by name and which provides a service to application code. Services often have well-known names within the services folder. For example, the principals object within a services folder is ‘the principals service’, the catalog object within a services folder is ‘the catalog service’ and so on.

There is only one difference between using the substanced.content.add_content_type function and the substanced.service.add_service_type decorator. The add_service_type function honors a service_name keyword argument in its **meta. If this argument is passed, and a service already exists in a folder by this name, the service will not be shown as addable in the add-content dropdown in the SDI UI of the folder.

class substanced.content.ContentRegistry(registry)

An object accessible as registry.content (aka request.registry.content, aka config.registry.content) that contains information about Substance D content types.

add(content_type, factory_type, factory, **meta)

Add a content type to this registry

all()

Return all content types known my this registry as a sequence.

create(content_type, *arg, **kw)

Create an instance of content_type by calling its factory with *arg and **kw. If the meta of the content type has an after_create value, call it (if it’s a string, it’s assumed to be a method of the created object, and if it’s a sequence, each value should be a string or a callable, which will be called in turn); then send a substanced.event.ContentCreatedEvent. Return the created object.

If the key __oid is in the kw arguments, it will be used as the created object’s oid.

exists(content_type)

Return True if content_type has been registered within this content registry, False otherwise.

factory_type_for_content_type(content_type)

Return the factory_type value for the content_type requested

find(resource, content_type)

Return the first object in the lineage of the resource that supplies the content_type or None if no such object can be found.

See also pyramid.traversal.find_interface() to find object by an interface or a class.

istype(resource, content_type)

Return True if resource is of content type content_type, False otherwise.

metadata(resource, name, default=None)

Return a metadata value for the content type of resource based on the **meta value passed to add(). If a value in that content type’s metadata was passed using name as its name, the value will be returned, otherwise default will be returned.

typeof(resource)

Return the content type of resource

substanced.content.includeme(config)

substanced.db API

substanced.db.root_factory(request, t=<module 'transaction' from '/home/docs/checkouts/readthedocs.org/user_builds/substanced/envs/latest/local/lib/python2.7/site-packages/transaction/__init__.pyc'>, g=<function get_connection>, mark_unfinished_as_finished=<function mark_unfinished_as_finished>)

A function which can be used as a Pyramid root_factory. It accepts a request and returns an instance of the Root content type.

substanced.dump API

substanced.db.includeme(config)

substanced.editable API

interface substanced.editable.IEditable

Adapter interface for editing content as a file.

put(fileish)

Update context based on the contents of fileish.

  • fileish is a file-type object: its read method should return the (new) file representation of the context.
get()

Return (body_iter, mimetype) representing the context.

  • body_iter is an iterable, whose chunks are bytes represenating the context as an editable file.
  • mimetype is the MIMEType corresponding to body_iter.
class substanced.editable.FileEditable(context, request)

IEditable adapter for stock SubstanceD ‘File’ objects.

substanced.editable.register_editable_adapter(config, adapter, iface)

Configuration directive: register IEditable adapter for iface.

  • adapter is the adapter factory (a class or other callable taking (context, request)).
  • iface is the interface / class for which the adapter is registered.
substanced.editable.get_editable_adapter(context, request)

Return an editable adapter for the context

Return None if no editable adapter is registered.

substanced.event API

class substanced.event.ObjectAdded(object, parent, name, duplicating=False, moving=False, loading=False)

An event sent just after an object has been added to a folder.

class substanced.event.ObjectWillBeAdded(object, parent, name, duplicating=False, moving=False, loading=False)

An event sent just before an object has been added to a folder.

class substanced.event.ObjectRemoved(object, parent, name, removed_oids, moving=False, loading=False)

An event sent just after an object has been removed from a folder.

class substanced.event.ObjectWillBeRemoved(object, parent, name, moving=False, loading=False)

An event sent just before an object has been removed from a folder.

removed_oids

Helper property that caches oids that will be removed as the result of this event. Will return an empty sequence if objectmap cannot be found on self.parent.

class substanced.event.ObjectModified(object)

An event sent when an object has been modified.

class substanced.event.ACLModified(object, old_acl, new_acl)
class substanced.event.LoggedIn(login, user, context, request)
class substanced.event.RootAdded(object)
class substanced.event.AfterTransition(object, old_state, new_state, transition)

Event sent after any workflow transition happens

class substanced.event.subscribe_added(obj=None, container=None, **predicates)

Decorator for registering an object added event subscriber (a subscriber for ObjectAdded).

event = <InterfaceClass substanced.interfaces.IObjectAdded>
class substanced.event.subscribe_removed(obj=None, container=None, **predicates)

Decorator for registering an object removed event subscriber (a subscriber for ObjectRemoved).

event = <InterfaceClass substanced.interfaces.IObjectRemoved>
class substanced.event.subscribe_will_be_added(obj=None, container=None, **predicates)

Decorator for registering an object will-be-added event subscriber (a subscriber for ObjectWillBeAdded).

event = <InterfaceClass substanced.interfaces.IObjectWillBeAdded>
class substanced.event.subscribe_will_be_removed(obj=None, container=None, **predicates)

Decorator for registering an object will-be-removed event subscriber (a subscriber for ObjectWillBeRemoved).

event = <InterfaceClass substanced.interfaces.IObjectWillBeRemoved>
class substanced.event.subscribe_modified(obj=None, **predicates)

Decorator for registering an object modified event subscriber (a subscriber for ObjectModified).

event = <InterfaceClass substanced.interfaces.IObjectModified>
class substanced.event.subscribe_acl_modified(obj=None, **predicates)

Decorator for registering an acl modified event subscriber (a subscriber for ObjectModified).

event = <InterfaceClass substanced.interfaces.IACLModified>
class substanced.event.subscribe_logged_in(**predicates)

Decorator for registering an event listener for when a user is logged in

event = <InterfaceClass substanced.interfaces.ILoggedIn>
class substanced.event.subscribe_root_added(**predicates)

Decorator for registering an event listener for when a root object has a database connection

event = <InterfaceClass substanced.interfaces.IRootAdded>
class substanced.event.subscribe_after_transition(**predicates)

Decorator for registering an event listener for when a transition has been done on an object

event = <InterfaceClass substanced.interfaces.IAfterTransition>

substanced.evolution API

substanced.evolution.add_evolution_step(config, func, before=None, after=None, name=None)

A configurator directive which adds an evolution step. An evolution step can be used to perform upgrades or migrations of data structures in existing databases to meet expectations of new code.

func should be a function that performs the evolution logic. It should accept two arguments (conventionally-named) root and registry.  ``root will be the root of the ZODB used to serve your Substance D site, and registry will be the Pyramid application registry.

before should either be None, another evolution step function, or the dotted name to such a function. By default, it is None, which means execute in the order defined by the calling order of add_evolution_step.

after should either be None, another evolution step function, or the dotted name to such a function. By default, it is None.

name is the name of the evolution step. It must be unique between all registered evolution steps. If it is not provided, the dotted name of the function used as func will be used as the evolution step name.

substanced.evolution.mark_unfinished_as_finished(app_root, registry, t=None)

Given the root object of a Substance D site as app_root and a Pyramid registry, mark all pending evolution steps as completed without actually executing them.

substanced.evolution.includeme(config)

substanced.file API

substanced.file.USE_MAGIC

A constant value used as an argument to various methods of the substanced.file.File class.

class substanced.file.File(stream=None, mimetype=None, title=u'')
__init__(stream=None, mimetype=None, title=u'')

The constructor of a File object.

stream should be a filelike object (an object with a read method that takes a size argument) or None. If stream is None, the blob attached to this file object is created empty.

title must be a string or Unicode object.

mimetype may be any of the following:

  • None, meaning set this file object’s mimetype to application/octet-stream (the default).

  • A mimetype string (e.g. image/gif)

  • The constant substanced.file.USE_MAGIC, which will derive the mimetype from the stream content (if stream is also supplied) using the python-magic library.

    Warning

    On non-Linux systems, successful use of substanced.file.USE_MAGIC requires the installation of additional dependencies. See Installing python-magic.

blob

The ZODB blob object associated with this file.

mimetype

The mimetype of this file object (a string).

get_etag()

Return a token identifying the “version” of the file.

get_response(**kw)

Return a WebOb-compatible response object which uses the blob content as the stream data and the mimetype of the file as the content type. The **kw arguments will be passed to the pyramid.response.FileResponse constructor as its keyword arguments.

get_size()

Return the size in bytes of the data in the blob associated with the file

upload(stream, mimetype_hint=None)

Replace the current contents of this file’s blob with the contents of stream. stream must be a filelike object (it must have a read method that takes a size argument).

mimetype_hint can be any of the following:

  • None, meaning don’t reset the current mimetype. This is the default. If you already know the file’s mimetype, and you don’t want it divined from a filename or stream content, use None as the mimetype_hint value, and set the mimetype attribute of the file object directly before or after calling this method.

  • A string containing a filename that has an extension; the mimetype will be derived from the extension in the filename using the Python mimetypes module, and the result will be set as the mimetype attribute of this object.

  • The constant substanced.file.USE_MAGIC, which will derive the mimetype using the python-magic library based on the stream’s actual content. The result will be set as the mimetype attribute of this object.

    Warning

    On non-Linux systems, successful use of substanced.file.USE_MAGIC requires the installation of additional dependencies. See Installing python-magic.

substanced.folder API

class substanced.folder.FolderKeyError
class substanced.folder.Folder(data=None, family=None)

A folder implementation which acts much like a Python dictionary.

Keys must be Unicode strings; values must be arbitrary Python objects.

__init__(data=None, family=None)

Constructor. Data may be an initial dictionary mapping object name to object.

order

A tuple of name values. If set, controls the order in which names should be returned from __iter__(), keys(), values(), and items(). If not set, use an effectively random order.

add(name, other, send_events=True, reserved_names=(), duplicating=None, moving=None, loading=False, registry=None)

Same as __setitem__.

If send_events is False, suppress the sending of folder events. Don’t allow names in the reserved_names sequence to be added.

If duplicating not None, it must be the object which is being duplicated; a result of a non-None duplicating means that oids will be replaced in objectmap. If moving is not None, it must be the folder from which the object is moving; this will be the moving attribute of events sent by this function too. If loading is True, the loading attribute of events sent as a result of calling this method will be True too.

This method returns the name used to place the subobject in the folder (a derivation of name, usually the result of self.check_name(name)).

add_service(name, obj, registry=None, **kw)

Add a service to this folder named name.

check_name(name, reserved_names=())

Perform all the validation checks implied by validate_name() against the name supplied but also fail with a FolderKeyError if an object with the name name already exists in the folder.

clear(registry=None)

Clear all items from the folder. This is the equivalent of calling .remove with each key that exists in the folder.

copy(name, other, newname=None, registry=None)

Copy a subobject named name from this folder to the folder represented by other. If newname is not none, it is used as the target object name; otherwise the existing subobject name is used.

find_service(service_name)

Return a service named by service_name in this folder or any parent service folder or None if no such service exists. A shortcut for substanced.service.find_service().

find_services(service_name)

Returns a sequence of service objects named by service_name in this folder’s lineage or an empty sequence if no such service exists. A shortcut for substanced.service.find_services()

get(name, default=None)

Return the object named by name or the default.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding.

is_ordered()

Return true if the folder has a manually set ordering, false otherwise.

is_reorderable()

Return true if the folder can be reordered, false otherwise.

items()

Return an iterable sequence of (name, value) pairs in the folder.

Respect order, if set.

keys()

Return an iterable sequence of object names present in the folder.

Respect order, if set.

load(name, newobject, registry=None)

A replace method used by the code that loads an existing dump. Events sent during this replace will have a true loading flag.

move(name, other, newname=None, registry=None)

Move a subobject named name from this folder to the folder represented by other. If newname is not none, it is used as the target object name; otherwise the existing subobject name is used.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events as well as the Added and WillBeAdded events sent will indicate that the object is moving.

order

Return an iterable sequence of object names present in the folder.

Respect order, if set.

pop(name, default=<object object>, registry=None)

Remove the item stored in the under name and return it.

If name doesn’t exist in the folder, and default is not passed, raise a KeyError.

If name doesn’t exist in the folder, and default is passed, return default.

When the object stored under name is removed from this folder, remove its __parent__ and __name__ values.

When this method is called, emit an substanced.event.ObjectWillBeRemoved event before the object loses its __name__ or __parent__ values. Emit an substanced.event.ObjectRemoved after the object loses its __name__ and __parent__ value,

remove(name, send_events=True, moving=None, loading=False, registry=None)

Same thing as __delitem__.

If send_events is false, suppress the sending of folder events.

If moving is not None, the moving argument must be the folder to which the named object will be moving. This value will be passed along as the moving attribute of the events sent as the result of this action. If loading is True, the loading attribute of events sent as a result of calling this method will be True too.

rename(oldname, newname, registry=None)

Rename a subobject from oldname to newname.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events sent will indicate that the object is moving.

reorder(names, before)

Move one or more items from a folder into new positions inside that folder. names is a list of ids of existing folder subobject names, which will be inserted in order before the item named before. All other items are left in the original order. If before is None, the items will be appended after the last item in the current order. If this method is called on a folder which does not have an order set, or which is not reorderable, a ValueError will be raised. A KeyError is raised, if before does not correspond to any item, and is not None.

replace(name, newobject, send_events=True, registry=None)

Replace an existing object named name in this folder with a new object newobject. If there isn’t an object named name in this folder, an exception will not be raised; instead, the new object will just be added.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events will be sent for the old object, and the WillBeAdded and Added events will be sent for the new object.

set_order(names, reorderable=None)

Sets the folder order. names is a list of names for existing folder items, in the desired order. All names that currently exist in the folder must be mentioned in names, or a ValueError will be raised.

If reorderable is passed, value, it must be None, True or False. If it is None, the reorderable flag will not be reset from its current value. If it is anything except None, it will be treated as a boolean and the reorderable flag will be set to that value. The reorderable value of a folder will be returned by that folder’s is_reorderable() method. The is_reorderable() method is used by the SDI folder contents view to indicate that the folder can or cannot be reordered via the web UI.

If reorderable is set to True, the reorder() method will work properly, otherwise it will raise a ValueError when called.

unset_order()

Remove set order from a folder, making it unordered, and non-reorderable.

validate_name(name, reserved_names=())

Validate the name passed to ensure that it’s addable to the folder. Returns the name decoded to Unicode if it passes all addable checks. It’s not addable if:

  • the name is not decodeable to Unicode.
  • the name starts with @@ (conflicts with explicit view names).
  • the name has slashes in it (WSGI limitation).
  • the name is empty.

If any of these conditions are untrue, raise a ValueError. If the name passed is in the list of reserved_names, raise a ValueError.

values()

Return an iterable sequence of the values present in the folder.

Respect order, if set.

class substanced.folder.SequentialAutoNamingFolder(data=None, family=None, autoname_length=None, autoname_start=None)

An auto-naming folder which autonames a subobject by sequentially incrementing the maximum key of the folder.

Example names: 0000001, then 0000002, and so on.

This class implements the substanced.interfaces.IAutoNamingFolder interface and inherits from substanced.folder.Folder.

This class is typically used as a base class for a custom content type.

__init__(data=None, family=None, autoname_length=None, autoname_start=None)

Constructor. Data may be an initial dictionary mapping object name to object. Autoname length may be supplied. If it is not, it will default to 7. Autoname start may be supplied. If it is not, it will default to -1.

add_next(subobject, send_events=True, duplicating=None, moving=None, registry=None)

Add a subobject, naming it automatically, giving it the name returned by this folder’s next_name method. It has the same effect as calling substanced.folder.Folder.add(), but you needn’t provide a name argument.

This method returns the name of the subobject.

next_name(subobject)

Return a name string based on:

  • intifying the maximum key of this folder and adding one.
  • zero-filling the left hand side of the result with as many zeroes as are in the value of this folder’s autoname_length constructor value.

If the folder has no items in it, the initial value used as a name will be the value of this folder’s autoname_start constructor value.

add(name, other, send_events=True, reserved_names=(), duplicating=None, moving=None, loading=False, registry=None)

The add method of a SequentialAutoNamingFolder will raise a ValueError if the name it is passed is not intifiable, as its next_name method relies on controlling the types of names that are added to it (they must be intifiable). It will also zero-fill the name passed based on this folder’s autoname_length constructor value. It otherwise just calls its superclass’ add method and returns the result.

class substanced.folder.RandomAutoNamingFolder(data=None, family=None, autoname_length=None)

An auto-naming folder which autonames a subobject using a random string.

Example names: MXF937A, FLTP2F9.

This class implements the substanced.interfaces.IAutoNamingFolder interface and inherits from substanced.folder.Folder.

This class is typically used as a base class for a custom content type.

__init__(data=None, family=None, autoname_length=None)

Constructor. Data may be an initial dictionary mapping object name to object. Autoname length may be supplied. If it is not, it will default to 7.

add_next(subobject, send_events=True, duplicating=None, moving=None, registry=None)

Add a subobject, naming it automatically, giving it the name returned by this folder’s next_name method. It has the same effect as calling substanced.folder.Folder.add(), but you needn’t provide a name argument.

This method returns the name of the subobject.

next_name(subobject)

Return a name string based on generating a random string composed of digits and uppercase letters of a length determined by this folder’s autoname_length constructor value. It tries generatoing values continuously until one that is unused is found.

substanced.folder.views API

substanced.form API

class substanced.form.Form(schema, action='', method='POST', buttons=(), formid='deform', use_ajax=False, ajax_options='{}', autocomplete=None, **kw)

Subclass of deform.form.Form which uses a custom resource registry designed for Substance D. XXX point at deform docs.

class substanced.form.FormView(context, request)

A class which can be used as a view which introspects a schema to present the form. XXX describe better using pyramid_deform documentation.

form_class

alias of Form

class substanced.form.FileUploadTempStore(request)

A Deform FileUploadTempStore implementation that stores file upload data in the Pyramid session and on disk. The request passed to its constructor must be a fully-initialized Pyramid request (it have a registry attribute, which must have a settings attribute, which must be a dictionary). The substanced.uploads_tempdir variable in the settings dictionary must be set to the path of an existing directory on disk. This directory will temporarily store file upload data on behalf of Deform and Substance D when a form containing a file upload widget fails validation.

See the Deform documentation for more information about FileUploadTempStore objects.

substanced.locking API

Advisory exclusive DAV-style locks for content objects.

When a resource is locked, it is presumed that its SDI UI will display a warning to users who do not hold the lock. The locking service can also be used by add-ons such as DAV implementations.

class substanced.locking.Lock(infinite=False, timeout=3600, comment=None, last_refresh=None)

A persistent object representing a lock.

ownerid

The owner oid for this lock.

owner

The owner object of this lock (a User).

resourceid

The oid of the resource related to this lock.

resource

The resource object related to this lock.

commit_suicide()

Remove this lock from the lock service.

expires()

Return the future datetime at which this lock will expire.

For invalid locks, the returned value indicates the point in the past at which the lock expired.

is_valid(when=None)

Return True if the lock has not expired and its resource exists.

refresh(timeout=None, when=None)

Refresh the lock.

If the timeout is not None, set the timeout for this lock too.

class substanced.locking.LockError(lock)

Raised when a lock cannot be created due to a conflicting lock.

Instances of this class have a lock attribute which is a substanced.locking.Lock object, representing the conflicting lock.

class substanced.locking.UnlockError(lock)

Raised when a lock cannot be removed

This may be because the owner suplied in the unlock request does not match the owner of the lock, or becaues the lock no longer exists.

Instances of this class have a lock attribute which is a substanced.locking.Lock object, representing the conflicting lock, or None if there was no lock to unlock.

substanced.locking.lock_resource(resource, owner_or_ownerid, timeout=None, comment=None, locktype=<ReferenceClass substanced.interfaces.WriteLock>, infinite=False)

Lock a resource using the lock service.

If the resource is already locked by the owner supplied as owner_or_ownerid, refresh the lock using timeout.

If the resource is not already locked by another user, create a new lock with the given values.

If the resource is already locked by a different user, raise a substanced.locking.LockError

If a Lock Service does not already exist in the lineage, a ValueError will be raised.

Warning

Callers should assert that the owner has the sdi.lock permission against the resource before calling this function to ensure that a user can’t lock a resource he is not permitted to.

substanced.locking.unlock_resource(resource, owner_or_ownerid, locktype=<ReferenceClass substanced.interfaces.WriteLock>)

Unlock a resource using the lock service.

If the resource is already locked by a user other than the owner supplied as owner_or_ownerid or the resource isn’t already locked with this lock type, raise a substanced.locking.UnlockError exception.

Otherwise, remove the lock.

If a Lock Service does not already exist in the lineage, a ValueError will be raised.

Warning

Callers should assert that the owner has the sdi.lock permission against the resource before calling this function to ensure that a user can’t lock a resource he is not permitted to.

substanced.locking.discover_resource_locks(resource, include_invalid=False, include_lineage=True, locktype=<ReferenceClass substanced.interfaces.WriteLock>)

Return locks related to resource for the given locktype.

Return a sequence of substanced.locking.Lock objects.

By default, only valid locks are returned.

Invalid locks for the resource may exist, but they are not returned unless include_invalid is True.

Under normal circumstances, the length of the sequence returned will be either 0 (if there are no locks) or 1 (if there is any lock).

In some special circumstances, however, when the substanced.locking.lock_resource API is not used to create locks, there may be more than one lock of the same type related to a resource.

substanced.objectmap API

class substanced.objectmap.ObjectMap(root, family=None)
add(obj, path_tuple, duplicating=False, moving=False)

Add a new object to the object map at the location specified by path_tuple (must be the path of the object in the object graph as a tuple, as returned by Pyramid’s resource_path_tuple function).

If duplicating is True, replace the oid of the added object even if it already has one and adjust extents involving the new oid.

If moving is True, don’t add any extents.

It is an error to pass a true value for both duplicating and moving.

allowed(oids, principals, permission)

For the set of oids present in oids, return a sequence of oids that are permitted permission against each oid if the implied user is a member of the set of principals implied by principals. This method uses the data collected via the set_acl method of this class.

connect(source, target, reftype)

Connect a source object or objectid to a target object or objectid using reference type reftype

disconnect(source, target, reftype)

Disconnect a source object or objectid from a target object or objectid using reference type reftype

get_extent(name, default=())

Return the extent for name (typically a factory name, e.g. the dotted name of the content class). It will be a TreeSet composed entirely of oids. If no extent exist by this name, this will return the value of default.

get_reftypes()

Return a sequence of reference types known by this objectmap.

has_references(obj, reftype=None)

Return true if the object participates in any reference as a source or a target. obj may be an object or an oid.

new_objectid()

Obtain an unused integer object identifier

object_for(objectid_or_path_tuple, context=None)

Returns an object or None given an object id or a path tuple

objectid_for(obj_or_path_tuple)

Returns an objectid or None, given an object or a path tuple

order_sources(targetid, reftype, order=<object object>)

Set the ordering of the source ids of a reference relative to the targetid. order should be a tuple or list of oids or objects in the order that they should be kept in the reference map. If the reftyp+targetid combination has existing reference values, the values in order must mention all of their oids, or a ValueError will be raised. You can unset an order for this targetid+reftype combination by passing None as the order.

order_targets(sourceid, reftype, order=<object object>)

Set the ordering of the target ids of a reference type. order should be a tuple (or list) of oids or objects in the order that they should be kept in the reference map. If the reference type has existing reference values, the values in order must mention all of their oids, or a ValueError will be raised. You can unset an ordering by passing None as the order.

path_for(objectid)

Returns an path or None given an object id

pathcount(obj_or_path_tuple, depth=None, include_origin=True)

Return the total number of objectids under a given path given an object or a path tuple. If depth is None, count all object ids under the path. If depth is an integer, use that depth instead. If include_origin is True, count the object identifier of the object that was passed, otherwise omit it.

pathlookup(obj_or_path_tuple, depth=None, include_origin=True)

Return a set of objectids under a given path given an object or a path tuple. If depth is None, return all object ids under the path. If depth is an integer, use that depth instead. If include_origin is True, include the object identifier of the object that was passed, otherwise omit it from the returned set.

remove(obj_objectid_or_path_tuple, moving=False)

Remove an object from the object map give an object, an object id or a path tuple. If moving is False, also remove any references added via connect and any extents related to the removed objects.

Return a set of removed oids (including the oid related to the object passed).

set_acl(obj_objectid_or_path_tuple, acl)

For the resource implied by obj_objectid_or_path_tuple, set the cached version of its ACL (for later used by allowed) to the ACL passed as acl

sourceids(obj, reftype)

Return a set of object identifiers of the objects connected to obj a source using reference type reftype

sources(obj, reftype)

Return a generator which will return the objects connected to obj as a source using reference type reftype

targetids(obj, reftype)

Return a set of object identifiers of the objects connected to obj a target using reference type reftype

targets(obj, reftype)

Return a generator which will return the objects connected to obj as a target using reference type reftype

class substanced.objectmap.Multireference(context, objectmap, reftype, ignore_missing, resolve, orientation, ordered=False)

An iterable of objects (if resolve is true) or oids (if resolve is false). Also supports the Python sequence protocol.

Additionally supports connect, disconnect, and clear methods for mutating the relationships implied by the reference.

clear()

Clear all references in this relationship.

connect(objects, ignore_missing=None)

Connect objects to this reference’s relationship. objects should be a sequence of content objects or object identifiers.

disconnect(objects, ignore_missing=None)

Disconnect objects from this reference’s relationship. objects should be a sequence of content objects or object identifiers.

substanced.objectmap.reference_sourceid_property(reftype)

Returns a property which, when set, establishes an object map reference between the property’s instance (the source) and another object in the objectmap (the target) based on the reference type reftype. It is comparable to a Python ‘weakref’ between the persistent object instance which the property is attached to and the persistent target object id; when the target object or the object upon which the property is defined is removed from the system, the reference is destroyed.

The reftype argument is a reference type, a hashable object that describes the type of the relation. See substanced.objectmap.ObjectMap.connect() for more information about reference types.

You can set, get, and delete the value. When you set the value, a relation is formed between the object which houses the property and the target object id. When you get the value, the related value (or None if no relation exists) is returned, when you delete the value, the relation is destroyed and the value will revert to None.

For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# definition

from substanced.content import content
from substanced.objectmap import reference_sourceid_property

@content('Profile')
class Profile(Persistent):
    user_id = reference_sourceid_property('profile-to-userid')

# subsequent usage of the property in a view...

profile = registry.content.create('Profile')
somefolder['profile'] = profile
profile.user_id = get_oid(request.user)
print profile.user_id # will print the oid of the user

# if the user is later deleted by unrelated code...

print profile.user_id # will print None

# or if you delete the value explicitly...

del profile.user_id
print profile.user_id # will print None
substanced.objectmap.reference_source_property(reftype)

Exactly like substanced.objectmap.reference_sourceid_property(), except its getter returns the instance related to the target instead of the target object id. Likewise, its setter will accept another persistent object instance that has an object id.

For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# definition

from substanced.content import content
from substanced.objectmap import reference_source_property

@content('Profile')
class Profile(Persistent):
    user = reference_source_property('profile-to-user')

# subsequent usage of the property in a view...

profile = registry.content.create('Profile')
somefolder['profile'] = profile
profile.user = request.user
print profile.user # will print the user object

# if the user is later deleted by unrelated code...

print profile.user # will print None

# or if you delete the value explicitly...

del profile.user
print profile.user # will print None
substanced.objectmap.reference_targetid_property(reftype)

Same as substanced.objectmap.reference_sourceid_property(), except the object upon which the property is defined is the target of the reference and any object assigned to the property is the source.

substanced.objectmap.reference_target_property(reftype)

Same as substanced.objectmap.reference_source_property(), except the object upon which the property is defined is the target of the reference and any object assigned to the property is the source.

substanced.objectmap.multireference_sourceid_property(reftype, ignore_missing=False, ordered=None)

Like substanced.objectmap.reference_sourceid_property(), but maintains a substanced.objectmap.Multireference rather than an object id. If ignore_missing is True, attempts to connect or disconnect unresolveable object identifiers will not cause an exception. If ordered is True, the relative ordering of references in a sequence will be maintained when you assign that sequence to the property and when you use the .connect method of the property. If ordered is None, defers to the appropriate attribute on the reftype.

substanced.objectmap.multireference_source_property(reftype, ignore_missing=False, ordered=None)

Like substanced.objectmap.reference_source_property(), but maintains a substanced.objectmap.Multireference rather than a single object reference. If ignore_missing is True, attempts to connect or disconnect unresolveable object identifiers will not cause an exception. If ordered is True, the relative ordering of references in a sequence will be maintained when you assign that sequence to the property and when you use the .connect method of the property. If ordered is None, defers to the appropriate attribute on the reftype.

substanced.objectmap.multireference_targetid_property(reftype, ignore_missing=False, ordered=None)

Like substanced.objectmap.reference_targetid_property(), but maintains a substanced.objectmap.Multireference rather than an object id. If ignore_missing is True, attempts to connect or disconnect unresolveable object identifiers will not cause an exception. If ordered is True, the relative ordering of references in a sequence will be maintained when you assign that sequence to the property and when you use the .connect method of the property. If ordered is None, defers to the appropriate attribute on the reftype.

substanced.objectmap.multireference_target_property(reftype, ignore_missing=False, ordered=None)

Like substanced.objectmap.reference_target_property(), but maintains a substanced.objectmap.Multireference rather than a single object reference. If ignore_missing is True, attempts to connect or disconnect unresolveable object identifiers will not cause an exception. If ordered is True, the relative ordering of references in a sequence will be maintained when you assign that sequence to the property and when you use the .connect method of the property. If ordered is None, defers to the appropriate attribute on the reftype.

class substanced.objectmap.ReferentialIntegrityError(obj, reftype, oids)

Exception raised when a referential integrity constraint is violated. Raised before an object involved in a relation with an integrity constraint is removed from a folder.

Attributes:

obj: the object which would have been removed were its removal not
     prevented by the raising of this exception

reftype: the reference type (usually a class)

oids: the oids that reference the to-be-removed object.
get_objects()

Return the objects which hold a reference to the object inovlved in the integrity error.

class substanced.objectmap.SourceIntegrityError(obj, reftype, oids)
class substanced.objectmap.TargetIntegrityError(obj, reftype, oids)

substanced.principal API

substanced.property API

class substanced.property.PropertySheet(context, request)

Bases: object

Convenience base class for concrete property sheet implementations

before_render(form)

Hook: allow subclasses to scribble on form.

Called by substanced.property.views.PropertySheetsView.before, after building the form but before rendering it.

substanced.property.add_propertysheet(self, *arg, **kw)

Add a propertysheet for the content types implied by iface and predicates.

The propsheet argument represents a propertysheet class (or a dotted Python name which identifies such a class); it will be called with two objects: context and request whenever Substance D determines that the propertysheet is necessary to display. The iface may be an interface or a class or a dotted Python name to a global object representing an interface or a class.

Using the default iface value, None will cause the propertysheet to be registered for all content types.

Any number of predicate keyword arguments may be passed in **predicates. Each predicate named will narrow the set of circumstances in which the propertysheet will be invoked. Each named predicate must have been registered via pyramid.config.Configurator.add_propertysheet_predicate() before it can be used.

substanced.property.add_propertysheet_predicate(self, *arg, **kw)

Adds a property sheet predicate factory. The associated property sheet predicate can later be named as a keyword argument to pyramid.config.Configurator.add_propertysheet() in the **predicates anonymous keyword argument dictionary.

name should be the name of the predicate. It must be a valid Python identifier (it will be used as a **predicates keyword argument to add_propertysheet()).

factory should be a predicate factory or dotted Python name which refers to a predicate factory.

class substanced.property.PropertySheet(context, request)

Convenience base class for concrete property sheet implementations

before_render(form)

Hook: allow subclasses to scribble on form.

Called by substanced.property.views.PropertySheetsView.before, after building the form but before rendering it.

substanced.schema API

class substanced.schema.Schema(*arg, **kw)

A colander.Schema subclass which generates and validates a CSRF token automatically. You must use it like so:

from substanced.schema import Schema as CSRFSchema
import colander

class MySchema(CSRFSchema):
    my_value = colander.SchemaNode(colander.String())

And in your application code, bind the schema, passing the request as a keyword argument:

def aview(request):
    schema = MySchema().bind(request=request)

In order for the CRSFSchema to work, you must configure a session factory in your Pyramid application. This is usually done by Substance D itself, but may not be done for you in extremely custom configurations.

schema_type

alias of RemoveCSRFMapping

class substanced.schema.NameSchemaNode(*arg, **kw)

Convenience Colander schemanode used to represent the name (aka __name__) of an object in a propertysheet or add form which allows for customizing the detection of whether editing or adding is being done, and setting a max length for the name.

By default it uses the context’s check_name API to ensure that the name provided is valid, and limits filename length to a default of 100 characters. Some usage examples follow.

This sets up the name_node to assume that it’s in ‘add’ mode with the default 100 character max limit.:

name_node = NameSchemaNode()

This sets up the name_node to assume that it’s in ‘add’ mode, and that the maximum length of the name provided is 20 characters:

name_node = NameSchemaNode(max_len=20)

This sets up the name_node to assume that it’s in ‘edit’ mode (check_name will be called on the parent of the bind context, not on the context itself):

name_node = NameSchemaNode(editing=True)

This sets up the name_node to condition whether it’s in edit mode on the result of a function:

def i_am_editing(context, request):
    return request.registry.content.istype(context, 'Document')

name_node = NameSchemaNode(editing=i_am_editing)
class substanced.schema.PermissionsSchemaNode(*arg, **kw)

A SchemaNode which represents a set of permissions; uses a widget which collects all permissions from the introspection system. Deserializes to a set.

substanced.sdi API

substanced.schema.LEFT
substanced.schema.MIDDLE
substanced.schema.RIGHT

substanced.root API

class substanced.root.Root(data=None, family=None)

An object representing the root of a Substance D application (the object represented in the root of the SDI). It is a subclass of substanced.folder.Folder.

When created as the result of registry.content.create, an instance of a Root will contain a principals service. The principals service will contain a user whose name is specified via the substanced.initial_login deployment setting with a password taken from the substanced.initial_password setting. This user will also be a member of an admins group. The admins group will be granted the ALL_PERMISSIONS special permission in the root.

If this class is created by hand, its after_create method must be called manually to create its objectmap, the services, the user, and the group.

substanced.stats API

substanced.stats.statsd_timer()

Return a context manager that can be used for statsd timing, e.g.:

with statsd_timer('addlotsofstuff'):
    # add lots of stuff

name is the statsd stat name, rate is the sample rate (a float between 0 and 1), and registry can be passed to speed up lookups (it should be the Pyramid registry).

substanced.stats.statsd_gauge()

Register a statsd gauge value. For example:

statsd_gauge('connections', numconnections)

name is the statsd stat name, rate is the sample rate (a float between 0 and 1), and registry can be passed to speed up lookups (it should be the Pyramid registry).

substanced.stats.statsd_incr()

Incremement or decrement a statsd counter value. For example:

    statsd_incr('hits', 1)

To decrement::

    statsd_incr('numusers', -1)

name is the statsd stat name, rate is the sample rate (a float between 0 and 1), and registry can be passed to speed up lookups (it should be the Pyramid registry).

substanced.util API

substanced.util.acquire(resource, name, default=<object object>)
substanced.util.get_oid(resource, default=<object object>)

Return the object identifer of resource. If resource has no object identifier, raise an AttributeError exception unless default was passed a value; if default was passed a value, return the default in that case.

substanced.util.set_oid(resource, oid)

Set the object id of the resource to oid.

substanced.util.get_acl(resource, default=<object object>)

Return the ACL of the object or the default if the object has no ACL. If no default is passed, an AttributeError will be raised if the object doesn’t have an ACL.

substanced.util.set_acl(resource, new_acl, registry=None)

Change the ACL on resource to new_acl, which may be a valid ACL or None. If new_acl is None, any existing non-None __acl__ attribute of the resource will be removed (via del resource.__acl__). Otherwise, if the resource’s __acl__ and the new_acl differ, set the resource’s __acl__ to new_acl via setattr.

If the new ACL and the object’s original ACL differ, send a substanced.event.ACLModified event with the new ACL and the original ACL (the __acl__ attribute of the resource, or None if it doesn’t have one) as arguments to the event.

This function will return True if a mutation to the resource’s __acl__ was performed, and False otherwise.

If registry is passed, it should be a Pyramid registry; if it is not passed, this function will use the current threadlocal registry to send the event.

substanced.util.get_interfaces(obj, classes=True)

Return the set of interfaces provided by obj. Include its __class__ if classes is True.

substanced.util.get_content_type(resource, registry=None)

Return the content type of a resource or None if the object has no content type. If registry is not supplied, the current Pyramid registry will be looked up as a thread local in order to find the Substance D content registry.

substanced.util.find_content(resource, content_type, registry=None)

Return the first object in the lineage of the resource that supplies the content_type. If registry is not supplied, the current Pyramid registry will be looked up as a thread local in order to find the Substance D content registry.

substanced.util.find_service(resource, name, *subnames)

Find the first service named name in the lineage of resource or return None if no such-named service could be found.

If subnames is supplied, when a service named name is found in the lineage, it will attempt to traverse the service as a folder, finding a content object inside the service, and it will return it instead of the service object itself. For example, find_service(resource, 'principals', 'users') would find and return the users subobject in the principals service. find_service(resource, 'principals', 'users', 'fred') would find and return the fred subobject of the users subobject of the principals service, and so forth. If subnames are supplied, and the named object cannot be found, the lineage search continues.

substanced.util.find_services(resource, name, *subnames)

Finds all services named name in the lineage of resource and returns a sequence containing those service objects. The sequence will begin with the most deepest nested service and will end with the least deeply nested service. Returns an empty sequence if no such-named service could be found.

If subnames is supplied, when a service named name is found in the lineage, it will attempt to traverse the service as a folder, finding a content object inside the service, and this API will append this object rather than the service itself to the list of things returned. For example, find_services(resource, 'principals', 'users') would find the users subobject in the principals service. find_services(resource, 'principals', 'users', 'fred') would find the fred subobject of the users subobject of the principals service, and so forth. If subnames are supplied, whether or not the named object can be found, the lineage search continues.

substanced.util.find_objectmap(context)

Returns the object map for the root object in the lineage of the context or None if no objectmap can be found.

substanced.util.find_catalogs(resource, name=None)

Return all catalogs in the lineage. If name is supplied, return only catalogs that have this name in the lineage, otherwise return all catalogs in the lineage.

substanced.util.find_catalog(resource, name)

Return the first catalog named name in the lineage of the resource

substanced.util.find_index(resource, catalog_name, index_name)

Find the first catalog named catalog_name in the lineage of the resource, and ask it for its index_name index; return the resulting index. If either a catalog of the provided name or an index of the provided name does not exist, this function will return None.

substanced.util.get_principal_repr(principal_or_id)

Given as principal_or_id a resource object that has a __principal_repr__ method, return the result of calling that method (without arguments); it must be a string that uniquely identifies the principal amongst all principals in the system.

Given as principal_or_id a resource object that does not have a __principal_repr__ method, return the result of the stringification of the __oid__ attribute of the resource object.

Given an integer as principal_or_id, return a stringification of the integer.

Given any other string value, return it.

substanced.util.is_folder(resource)

Return True if the object is a folder, False if not.

substanced.util.is_service(resource)

Returns True if the resource is a service, False if not.

substanced.util.get_factory_type(resource)

If the resource has a __factory_type__ attribute, return it. Otherwise return the full Python dotted name of the resource’s class.

substanced.util.coarse_datetime_repr(date)

Convert a datetime to an integer with 100 second granularity.

The granularity reduces the number of index entries in a fieldindex when it’s used in an indexview to convert a datetime value to an integer.

substanced.util.postorder(startnode)

Walks over nodes in a folder recursively. Yields deepest nodes first.

substanced.util.merge_url_qs(url, **kw)

Merge the query string elements of a URL with the ones in kw. If any query string element exists in url that also exists in kw, replace it.

substanced.util.chunks(stream, chunk_size=10000)

Return a generator that will iterate over a stream (a filelike object) chunk_size bytes at a time.

substanced.util.renamer()

Returns a property. The getter of the property returns the __name__ attribute of the instance on which it’s defined. The setter of the property calls rename() on the __parent__ of the instance on which it’s defined if the new value doesn’t match the existing __name__ of the instance (this will cause __name__ to be reset if the parent is a normal Substance D folder ). Sample usage:

class SomeContentType(Persistent):
    name = renamer()
substanced.util.get_dotted_name(g)

Return the dotted name of a global object.

substanced.util.get_icon_name(resource, request)

Returns the content registry icon name of the resource or None if the resource type has no icon in the content registry.

substanced.util.get_auditlog(context)

Returns the current substanced.audit.AuditLog object or None if no audit database is configured

class substanced.util.Batch(seq, request, url=None, default_size=10, toggle_size=40, seqlen=None)

Given a sequence named seq, and a Pyramid request, return an object with the following attributes:

items

A list representing a slice of seq. It will contain the number of elements in request.params['batch_size'] or the default_size number if such a key does not exist in request.params or the key is invalid. The slice will begin at request.params['batch_num'] or zero if such a key does not exist in request.params or the batch_num key could not successfully be converted to a positive integer.

This value can be iterated over via the __iter__ of the batch object.

size

The value obtained from request.params['batch_size'] or default_size if no batch_size parameter exists in request.params or the batch_size parameter could not successfully be converted to a positive interger.

num

The value obtained from request.params['batch_num'] or 0 if no batch_num parameter exists in request.params or if the batch_num parameter could not successfully be converted to a positive integer. Batch numbers are indexed from zero, so batch 0 is the first batch, batch 1 the second, and so forth.

length

This is length of the current batch. It is usually equal to size but may be different in the very last batch. For example, if the seq is [1,2,3,4] and the batch size is 3, the first batch’s length will be 3 because the batch content will be [1,2,3]; but the second and final batch’s length will be 1 because the batch content will be [4].

last

The batch number computed from the sequence length of the last batch (indexed from zero).

first_url

The URL of the first batch. This will be a URL with batch_num and batch_size in its query string. The base URL will be taken from the url value passed to this function. If a url value is not passed to this function, the URL will be taken from request.url. This value will be None if the current batch_num is 0.

prev_url

The URL of the previous batch. This will be a URL with batch_num and batch_size in its query string. The base URL will be taken from the url value passed to this function. If a url value is not passed to this function, the URL will be taken from request.url. This value will be None if there is no previous batch.

next_url

The URL of the next batch. This will be a URL with batch_num and batch_size in its query string. The base URL will be taken from the url value passed to this function. If a url value is not passed to this function, the URL will be taken from request.url. This value will be None if there is no next batch.

last_url

The URL of the next batch. This will be a URL with batch_num and batch_size in its query string. The base URL will be taken from the url value passed to this function. If a url value is not passed to this function, the URL will be taken from request.url. This value will be None if there is no next batch.

required

True if either next_url or prev_url are True (meaning batching is required).

multicolumn

True if the current view should be rendered in multiple columns.

toggle_url

The URL to be used for the multicolumn/single column toggle button. The batch_size, batch_num, and multicolumn parameters are converted to their multicolumn or single column equivalents. If a user is viewing items 40-80 in multiple columns, the toggle will switch to items 40-50 in a single column. If a user is viewing items 50-60 in a single column, the toggle will switch to items 40-80 in multiple columns.

toggle_text

The text to display on the multi-column/single column toggle.

make_columns

A method to split items into a nested list representing columns.

seqlen

This is total length of the sequence (across all batches).

startitem

The item number that starts this batch (indexed from zero).

enditem

The item number that ends this batch (indexed from zero).
make_columns(column_size=10, num_columns=4)

Break self.items into a nested list representing columns.

substanced.workflow API

class substanced.workflow.ACLState(acl=None, **kw)

Bases: dict

class substanced.workflow.ACLWorkflow(initial_state, type, name='', description='')

Bases: substanced.workflow.Workflow

class substanced.workflow.Workflow(initial_state, type, name='', description='')

Bases: object

Finite state machine.

Implements substanced.interfaces.IWorkflow.

Parameters:
  • initial_state (string) – Initial state of the workflow assigned to the content
  • type (string) – Identifier to separate multiple workflows on same content.
  • name (string) – Display name.
  • description (string) – Not used internally, provided as help text to describe what workflow does.
add_state(state_name, callback=None, **kw)

Add a new workflow state.

Parameters:
Raises:

WorkflowError if state already exists.

Callback is called with content as a single positional argument and the keyword arguments workflow, transition, and request. Be aware that methods as Workflow.initialize() pass transition as an empty dictionary.

Note

**kw must not contain the key callback. This name is reserved for internal use.

add_transition(transition_name, from_state, to_state, callback=None, permission=None, **kw)

Add a new workflow transition.

Parameters:
  • transition_name – Unique name of transition for this workflow.
  • callback (callable) – Will be called when transition is executed. Meaning Workflow.transition() and Workflow.transition_to_state() will trigger callback if this transition is executed.
  • **kw – Metadata assigned to this transition.
Raises:

WorkflowError if transition already exists.

Raises:

WorkflowError if from_state or to_state don’t exist.

Callback is called with content as a single positional argument and the keyword arguments workflow, transition, and request.

Note

**kw must not contain any of the keys from_state, name, to_state, or callback; these are reserved for internal use.

check()

Check the consistency of the workflow state machine.

Raises:WorkflowError if workflow is inconsistent.
get_states(content, request, from_state=None)

Return all states for the workflow.

Parameters:
  • content – Object to be operated on
  • requestpyramid.request.Request instance
  • from_state – State of the content. If None, Workflow.state_of() will be used on content.
Return type:

list of dicts

Returns:

Where dictionary contains information about the transition, such as title, initial, current, transitions and data. transitions is return value of Workflow.get_transitions() call for current state. data is a dictionary containing at least callback.

Note

States that fail has_permission check for their transition are left out.

get_transitions(content, request, from_state=None)

Get all transitions from the content state.

Parameters:
  • content – Object to be operated on.
  • requestpyramid.request.Request instance
  • from_state – Name of the state to retrieve transitions. If None, Workflow.state_of() will be used on content.
Return type:

list of dicts

Returns:

Where dictionary contains information about the transition, such as from_state, to_state, callback, permission and name.

Note

Transitions that fail has_permission check are left out.

has_state(content)

Return True if the content has state for this workflow, False if not.

initialize(content, request=None)

Initialize the content object to the initial state of this workflow.

Parameters:
  • content – Object to be operated on
  • requestpyramid.request.Request instance
Returns:

(initial_state, msg)

msg is a string returned by the state callback.

reset(content, request=None)

Reset the content workflow by calling the callback of it’s current state and setting its state attr.

If content has no current state, it will be initialized for this workflow (see initialize).

msg is a string returned by the state callback.

Parameters:
  • content – Object to be operated on
  • requestpyramid.request.Request instance
Returns:

(state, msg)

state_of(content)

Return the current state of the content object or None if the content object does not have this workflow.

transition(content, request, transition_name)

Execute a transition using a transition_name on content.

Parameters:
  • content – Object to be operated on.
  • requestpyramid.request.Request instance
  • transition_name – Name of transition to execute.
Raises:

WorkflowError if no transition is found

Raises:

WorkflowError if transition doesn’t pass has_permission check

transition_to_state(content, request, to_state, skip_same=True)

Execute a transition to another state using a state name (to_state). All possible transitions towards to_state will be tried until one if found that passes without exception.

Parameters:
  • content – Object to be operated on.
  • requestpyramid.request.Request instance
  • to_state – State to transition to.
  • skip_same – If True and the to_state is the same as the content state, no transition is issued.
Raises:

WorkflowError if no transition is found

exception substanced.workflow.WorkflowError

Bases: exceptions.Exception

Exception raised for anything related to substanced.workflow.

substanced.workflow.add_workflow(config, workflow, content_types=(None, ))

Configurator method for adding a workflow.

If no content_types is given, workflow is registered globally.

Parameters:
  • config – Pyramid configurator
  • workflowWorkflow instance
  • content_types (iterable) – Register workflow for given content_types
Raises:

ConfigurationError if Workflow.check() fails

Raises:

ConfigurationError if content_type does not exist

Raises:

DoesNotImplement if workflow does not implement IWorkflow

substanced.workflow.get_workflow(request, type, content_type=None)

Return a workflow based on a content_type and the workflow type.

Parameters:
  • requestpyramid.request.Request instance
  • type – Workflow type
  • content_type – Substanced content type or None for default workflow.

substanced.interfaces

These represent interfaces implemented by various Substance D objects.

interface substanced.interfaces.IACLModified

Extends: zope.interface.interfaces.IObjectEvent

May be sent when an object’s ACL is modified

old_acl

The object ACL before the modification

object

The object being modified

new_acl

The object ACL after the modification

interface substanced.interfaces.IAfterTransition

An event type sent after a transition has been done

transition

The transition name

new_state

The new state of the object

object

The object on which the transition has been done

initial_state

The initial state of the object

interface substanced.interfaces.ICatalog

A collection of indices.

reset()

Clear all indexes in this catalog and clear self.objectids.

__getitem__(name)

Return the index named name

update_indexes(registry=None, dry_run=False, output=None, replace=False, reindex=False, **kw)

Use the candidate indexes registered via config.add_catalog_factory to populate this catalog.

reindex_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using objectid oid. If oid is not supplied, the __oid__ of the resource will be used. action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED indicating when the updates should take effect. The action_mode value will overrule any action mode that a member index has been configured with.

The result of calling this method is logically the same as calling unindex_resource, then index_resource for the same resource/oid combination, but calling those two methods in succession is often more expensive than calling this single method, as member indexes can choose to do smarter things during a reindex than what they would do during an unindex then an index.

reindex(dry_run=False, commit_interval=200, indexes=None, path_re=None, output=None)

Reindex all objects in this collection of indexes.

If dry_run is True, do no actual work but send what would be changed to the logger.

commit_interval controls the number of objects indexed between each call to transaction.commit() (to control memory consumption).

indexes, if not None, should be a list of index names that should be reindexed. If indexes is None, all indexes are reindexed.

path_re, if it is not None should be a regular expression object that will be matched against each object’s path. If the regular expression matches, the object will be reindexed, if it does not, it won’t.

output, if passed should be one of None, False or a function. If it is a function, the function should accept a single message argument that will be used to record the actions taken during the reindex. If False is passed, no output is done. If None is passed (the default), the output will wind up in the substanced.catalog Python logger output at info level.

unindex_resource(resource_or_oid, action_mode=None)

Deregister the resource in indexes of this catalog using objectid or resource resource_or_oid. If resource_or_oid is an integer, it will be used as the oid; if resource_or_oid is a resource, its __oid__ attribute will be used as the oid. action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED.

index_resource(resource, oid=None, action_mode=None)

Register the resource in indexes of this catalog using objectid oid. If oid is not supplied, the __oid__ of the resource will be used. action_mode, if supplied, should be one of None, MODE_IMMEDIATE, MODE_ATCOMMIT or MODE_DEFERRED.

objectids

a sequence of objectids that are cataloged in this catalog

flush(immediate=True)

Flush any pending indexing actions for all indexes in this catalog. If immediate is True, all actions will be immediately executed. If immediate is False, MODE_DEFERRED actions will be sent to the actions processor if one is active, and all other actions will be executed immediately.

interface substanced.interfaces.IContentCreated

An event type sent when a Substance D content object is created via registry.content.create

object

The freshly created content object. It will not yet have been seated into any folder.

meta

The metainformation about the content type in the content registry

content_type

The content type of the object that was created

interface substanced.interfaces.IDefaultWorkflow

Marker interface used internally for workflows that aren’t associated with a particular content type

interface substanced.interfaces.IEditable

Adapter interface for editing content as a file.

put(fileish)

Update context based on the contents of fileish.

  • fileish is a file-type object: its read method should return the (new) file representation of the context.
get()

Return (body_iter, mimetype) representing the context.

  • body_iter is an iterable, whose chunks are bytes represenating the context as an editable file.
  • mimetype is the MIMEType corresponding to body_iter.
interface substanced.interfaces.IEvolutionSteps

Utility for obtaining evolution step data

interface substanced.interfaces.IFile

An object representing file content

mimetype

The mimetype of the file content

upload(stream, mimetype_hint=False)

Replace the current contents of this file’s blob with the contents of stream. mimetype_hint can be any of the folliwing:

  • None, meaning don’t reset the current mimetype. This is the default.
  • A string containing a filename with an extension; the mimetype will be derived from the extension in the filename.
  • The constant substanced.file.USE_MAGIC, which will derive the content type using the python-magic library based on the stream’s actual content.
get_size()

Return the size in bytes of the data in the blob associated with the file

blob

The ZODB blob object holding the file content

get_response(**kw)

Return a WebOb-compatible response object which uses the blob content as the stream data and the mimetype of the file as the content type. The **kw arguments will be passed to the pyramid.response.FileResponse constructor as its keyword arguments.

interface substanced.interfaces.IFolder

A Folder which stores objects using Unicode keys.

All methods which accept a name argument expect the name to either be Unicode or a byte string decodable using the default system encoding or the UTF-8 encoding.

rename(oldname, newname)

Rename a subobject from oldname to newname.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events sent will indicate that the object is moving.

load(name, newobject)

Same as substanced.interfaces.IFolder.replace() except it causes the loading flag of added and removed events sent during the add and remove events implied by the replacement to be True.

move(name, other, newname=None)

Move a subobject named name from this folder to the folder represented by other. If newname is not none, it is used as the target object name; otherwise the existing subobject name is used.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events sent will indicate that the object is moving.

set_order(value, reorderable=None)

Makes the folder orderable and sets its order to the list of names provided in value. Names should be existing names for objects contained in the folder at the time order is set.

If reorderable is passed, value, it must be None, True or False. If it is None, the reorderable flag will not be reset from its current value. If it is anything except None, it will be treated as a boolean and the reorderable flag will be set to that value. The reorderable value of a folder will be returned by that folder’s is_reorderable() method.

The is_reorderable() method is used by the SDI folder contents view to indicate that the folder can or cannot be reordered via the web UI.

If reorderable is set to True, the reorder() method will work properly, otherwise it will raise a ValueError when called.

pop(name, default=None)

Remove the item stored in the under name and return it.

If name doesn’t exist in the folder, and default is not passed, raise a KeyError.

If name doesn’t exist in the folder, and default is passed, return default.

When the object stored under name is removed from this folder, remove its __parent__ and __name__ values.

When this method is called, emit an IObjectWillBeRemoved event before the object loses its __name__ or __parent__ values. Emit an ObjectRemoved after the object loses its __name__ and __parent__ value,

replace(name, newobject)

Replace an existing object named name in this folder with a new object newobject. If there isn’t an object named name in this folder, an exception will not be raised; instead, the new object will just be added.

This operation is done in terms of a remove and an add. The Removed and WillBeRemoved events will be sent for the old object, and the WillBeAdded and Add events will be sent for the new object.

__contains__(name)

Does the container contains an object named by name?

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding or the UTF-8 encoding.

is_reorderable()

Return true if the folder can be reordered, false otherwise.

keys()

Return an iterable sequence of object names present in the folder.

Respect order, if set.

add(name, other, send_events=True, reserved_names=(), duplicating=None, moving=None, loading=False, registry=None)

Same as __setitem__.

If send_events is false, suppress the sending of folder events. Disallow the addition of the name provided is in the reserved_names list. If duplicating is not None, it must be the object being duplicated; when non-None, the ObjectWillBeAdded and ObjectAdded events sent will be marked as ‘duplicating’, which typically has the effect that the subobject’s object id will be overwritten instead of reused. If registry is passed, it should be a Pyramid registry object; otherwise the pyramid.threadlocal.get_current_registry() function is used to look up the current registry.

This method returns the name used to place the subobject in the folder (a derivation of name, usually the result of self.check_name(name)).

__len__()

Return the number of subobjects in this folder.

sort(oids, reverse=False, limit=None)

Return the intersection of the oids of the folder’s order with the oids passed in. If reverse is True, reverse the result set. If limit is an integer, return only that number of items (after reversing, if reverse is True).

__getitem__(name)

Return the object represented by name in this folder or raise a KeyError if no such object exists.

get(name, default=None)

Return the object named by name or the default.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding or the UTF-8 encoding.

is_ordered()

Return True if the folder has a manual ordering (e.g. its order attribute has been set), False otherwise.

unset_order()

Removes the folder internal ordering, making it an unordered folder.

validate_name(name, reserved_names=())

Checks the name passed for validity. If the name is valid and is not present in reserved_names returns a validated name. Otherwise a ValueError will be raised.

__iter__()

An alias for keys.

Respect order, if set.

check_name(name, reserved_names=())

Performs all checks associated with validate_name but also raises a substanced.folder.FolderKeyError if an object with the name name already exists in the folder. Returns the name (with any modifications) returned by validate_name.

__delitem__(name)

Remove the object from this folder stored under name.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding or the UTF-8 encoding.

If no object is stored in the folder under name, raise a KeyError.

When the object stored under name is removed from this folder, remove its __parent__ and __name__ values.

When this method is called, emit an IObjectWillBeRemoved event before the object loses its __name__ or __parent__ values. Emit an IObjectRemoved after the object loses its __name__ and __parent__ value,

__nonzero__()

Always return True

items()

Return an iterable sequence of (name, value) pairs in the folder.

Respect order, if set.

clear()

Clear all objects from the folder. Calling this is equivalent to calling .remove for each key in the folder.

__setitem__(name, other)

Set object other into this folder under the name name.

name must be a Unicode object or a bytestring object.

If name is a bytestring object, it must be decodable using the system default encoding or the UTF-8 encoding.

name cannot be the empty string.

When other is seated into this folder, it will also be decorated with a __parent__ attribute (a reference to the folder into which it is being seated) and __name__ attribute (the name passed in to this function.

If a value already exists in the foldr under the name name, raise KeyError.

When this method is called, emit an IObjectWillBeAdded event before the object obtains a __name__ or __parent__ value. Emit an IObjectAdded event after the object obtains a __name__ and __parent__ value.

remove(name, send_events=True, moving=None, loading=False)

Same thing as __delitem__.

If send_events is false, suppress the sending of folder events. If moving is not None, it should be the folder object from which the object is being moved; the events sent will indicate that a move is in process.

values()

Return an iterable sequence of the values present in the folder.

Respect order, if set.

reorder(items, before)

Move one or more items from a folder into new positions inside that folder. items is a list of ids of existing folder items, which will be inserted in order before the item named before. All other items are left in the original order. If this method is called on a folder which does not have an order set, or which is not reorderable, a ValueError will be raised.

interface substanced.interfaces.IGroup

Extends: substanced.interfaces.IPrincipal

Marker interface representing a group

interface substanced.interfaces.IGroups

Marker interface representing a collection of groups

interface substanced.interfaces.IIndexFactory

A factory for an index

interface substanced.interfaces.IIndexingActionProcessor

Processor of deferred indexing/unindexing actions of catalogs in the system

interface substanced.interfaces.ILock

Represents a lock to be applied by the lock service

interface substanced.interfaces.ILoggedIn

An event type sent when a user supplies a valid username and password to a login view. Note that this event is not sent on every request that the user initiates, just ones which result in an interactive login.

request

The request which resulted in the login

user

The user object computed by Substance D

context

The context resource that was active during login

login

The login name used by the user

interface substanced.interfaces.IObjectAdded

Extends: zope.interface.interfaces.IObjectEvent

An event type sent when an object is added

loading

Boolean indicating that this add is part of a load (during a dump load process)

name

The name of the object within the folder

parent

The folder to which the object is being added

object

The object being added

duplicating

The object being duplicated or None

moving

None or the folder from which the object being added was moved

interface substanced.interfaces.IObjectMap

A map of objects to paths and a reference engine

pathlookup(obj_or_path_tuple, depth=None, include_origin=True)

Returns an iterator of document ids within obj_or_path_tuple (a traversable object or a path tuple). If depth is specified, returns only objects at that depth. If include_origin is True, returns the docid of the object passed as obj_or_path_tuple in the returned set, otherwise it omits it.

disconnect(src, target, reftype)

Disonnect src_object from target_object using the reference type reftype. src and target may be objects or object identifiers

path_for(objectid)

Return the path tuple for objectid

objectid_for(obj_or_path_tuple)

Return the object id for obj_or_path_tuple

remove(obj_objectid_or_path_tuple)

Removes an object from the object map using the object itself, an object id, or a path tuple. Returns a set of objectids (children, inclusive) removed as the result of removing this object from the object map.

targets(obj, reftype)

Return a generator consisting of objects which have obj as a relationship target using reftype. obj can be an object or an object id.

sources(obj, reftype)

Return a generator consisting of objects which have obj as a relationship source using reftype. obj can be an object or an object id.

add(obj)

Add a new object to the object map. Assigns a new objectid to obj.__oid__ to the object if it doesn’t already have one. The object’s path or objectid must not already exist in the map. Returns the object id.

connect(src, target, reftype)

Connect src_object to target_object using the reference type reftype. src and target may be objects or object identifiers.

targetids(obj, reftype)

Return a set of objectids which have obj as a relationship target using reftype. obj can be an object or an object id.

object_for(objectid)

Return the object associated with objectid or None if the object cannot be found.

sourceids(obj, reftype)

Return a set of objectids which have obj as a relationship source using reftype. obj can be an object or an object id.

interface substanced.interfaces.IObjectModified

Extends: zope.interface.interfaces.IObjectEvent

May be sent when an object is modified

object

The object being modified

interface substanced.interfaces.IObjectRemoved

Extends: zope.interface.interfaces.IObjectEvent

An event type sent when an object is removed

loading

Boolean indicating that this remove is part of a load (during a dump load process)

name

The name of the object within the folder

parent

The folder from which the object is being removed

object

The object being removed

moving

None or the folder to which the object being removed will be moved

removed_oids

The set of oids removed as the result of this object being removed (including the oid of the object itself). This may be any number of oids if the object was folderish

interface substanced.interfaces.IObjectWillBeAdded

Extends: zope.interface.interfaces.IObjectEvent

An event type sent when an before an object is added

loading

Boolean indicating that this add is part of a load (during a dump load process)

name

The name which the object is being added to the folder with

parent

The folder to which the object is being added

object

The object being added

duplicating

The object being duplicated or None

moving

None or the folder from which the object being added was moved

interface substanced.interfaces.IObjectWillBeRemoved

Extends: zope.interface.interfaces.IObjectEvent

An event type sent before an object is removed

loading

Boolean indicating that this remove is part of a load (during a dump load process)

name

The name of the object within the folder

parent

The folder from which the object is being removed

object

The object being removed

moving

None or the folder to which the object being removed will be moved

interface substanced.interfaces.IPasswordReset

Marker interface represent a password reset request

interface substanced.interfaces.IPasswordResets

Marker interface representing a collection of password reset requests

interface substanced.interfaces.IPrincipal

Marker interface representing a user or group

interface substanced.interfaces.IPrincipals

Marker interface representing a container of users and groups

interface substanced.interfaces.IPropertySheet

Interface for objects with a set of properties defined by a Colander schema. The class substanced.property.PropertySheet (which is meant to be subclassed for specialization) implements this interface.

set(struct, omit=())

Accept struct (a dictionary representing the property state) and persist it to the context, refraining from persisting the keys in the struct that are named in omit (a sequence of strings or a string). The data structure will have already been validated against the propertysheet schema.

You can return a value from this method. It will be passed as changed into the after_set method. It should be False if your set implementation did not change any persistent data. Any other return value will be conventionally interpreted as the implementation having changed persistent data.

get()

Return a dictionary representing the current property state compatible with the schema for serialization

request

The current request

context

The context of the property sheet (a resource)

after_set(changed)

Perform operations after a successful set. changed is the value returned from the set method.

The default propertysheet implementation sends an ObjectModified event if the changed value is not False.

schema

The Colander schema instance which defines the fields related to this property sheet

interface substanced.interfaces.IRootAdded

An event type sent when the Substance D root object has a connection to the database as its _p_jar attribute.

object

The root object

interface substanced.interfaces.ISDIAPI

Easy access to common templating operations on all views. This object is available as request.sdiapi.

mgmt_path(obj, *arg, **kw)

Return the route_path inside the SDI for an object

sdi_title()

The sdi_title of the virtual root or “Substance D” if not defined

mgmt_views(context)

The list of management views on a resource

breadcrumbs()

Return a sequence of dicts for the breadcrumb information. Each dict contains:

  • url: The request.mgmt_path to that resource
  • name: The resource __name__ or ‘Home’ for the root
  • active: Boolean representing whether the resource is in the breadcrumb is the current context
  • icon: The full path to the icon for that resource type
get_macro(asset_spec, name=None)

Return a Chameleon template macro based on the asset spec (e.g. somepackage:templates/foo.pt) and the name. If the name is None, the bare template implementation is returned, otherwise the named macro from within the template is returned.

mgmt_url(obj, *arg, **kw)

Return the route_url inside the SDI for an object

main_template

The loaded master.pt which can be used in view templates with metal:use-macro="request.sdiapi.main_template".

flash_with_undo(msg, queue='', allow_duplicate=True)

Display a Pyramid flash message to the appropriate queue with a button to allow an undo of the commit.

interface substanced.interfaces.IService

Marker for items which are showin in the “Services” tab.

interface substanced.interfaces.IUser

Extends: substanced.interfaces.IPrincipal

Marker interface representing a user

interface substanced.interfaces.IUserLocator

Adapter responsible for returning a user by his login name and/or userid as well as group objects of a user by his userid.

get_groupids(userid)

Return all the group-related principal identifiers for a user with the user principal identifier userid as a sequence. If no user exists under userid, return None.

get_user_by_email(email)

Return an IUser object or None if no such user exists. The email argument is the email address of the user.

get_user_by_userid(userid)

Return an IUser object or None if no such user exists. The userid argument is the user id of the user (usually an oid).

get_user_by_login(login)

Return an IUser object or None if no such user exists. The login argument is the login name of the user, not an oid.

interface substanced.interfaces.IUsers

Marker interface representing a collection of users

interface substanced.interfaces.IWorkflow
reset(content, request=None)
has_state(content)
get_transitions(content, request, from_state=None)
add_state(name, callback=None, **kw)
transition(content, request, transition_name)
state_of(content)
check()
get_states(content, request, from_state=None)
initialize(content, request=None)
transition_to_state(content, request, to_state, skip_same=True)
add_transition(name, from_state, to_state, callback=None, **kw)
interface substanced.interfaces.MODE_ATCOMMIT

Sentinel indicating that an indexing action should take place at the successful end of the current transaction.

interface substanced.interfaces.MODE_DEFERRED

Sentinel indicating that an indexing action should be performed by an external indexing processor (e.g. drain_catalog_indexing) if one is active at the successful end of the current transaction. If an indexing processor is unavailable at the successful end of the current transaction, this mode will be taken to imply the same thing as MODE_ATCOMMIT.

interface substanced.interfaces.MODE_IMMEDIATE

Sentinel indicating that an indexing action should take place as immediately as possible.

class substanced.interfaces.ReferenceClass(*arg, **kw)

Bases: zope.interface.interface.InterfaceClass

interface substanced.interfaces.UserToLock

Extends: substanced.interfaces.ReferenceType

A reference type which represents the relationship from a user to his set of locks

interface substanced.interfaces.WriteLock

Extends: substanced.interfaces.ReferenceType

Represents a DAV-style writelock. It’s a Substance D reference type from resource object to lock object