def library(name, path='', type='', require='', prefix='', postfix='', extra=None): """ Registers a library with one or more assets. Used to logically group JS and CSS collections. Provides ability to declarare dependency/requirements between library collections. :param name: Library collection name :param path: The ``path`` argument points at a file or directory on disk. :param type: A string, either `css` or `js` :param require: A library name to be considered dependency (Optional) :param prefix: A string which will be generated before the library HTML :param postfix: A string which will be generated after the library HTML An example of prefix/postfix is <!-- JS/CSS --> :param extra: Additional attributes for computed library tag An example of extra is {'type':'text/pythonscript'} """ if type not in ('js', 'css'): raise ValueError("Uknown type '%s'" % type) if isinstance(path, string_types): path = (path, ) if require and isinstance(require, string_types): require = (require, ) if extra is None: extra = {} discr = (LIBRARY_ID, name, tuple(path)) intr = config.Introspectable(LIBRARY_ID, discr, name, LIBRARY_ID) intr['name'] = name intr['path'] = path intr['type'] = type intr['require'] = require intr['prefix'] = prefix intr['postfix'] = postfix intr['extra'] = extra def library_impl(cfg, name, path, type, require, prefix, postfix, extra): data = cfg.get_cfg_storage(LIBRARY_ID) lib = data.get(name) if lib is None: lib = Library(name) data[name] = lib lib.add(path, type, require, prefix, postfix, extra) info = config.DirectiveInfo() info.attach( config.Action(library_impl, (name, path, type, require, prefix, postfix, extra), discriminator=discr, introspectables=(intr, )))
def auth_checker(checker, __cfg=None, __depth=1): """Register authentication checker. Checker function accepts :py:class:`ptah.authentication.AuthInfo` object. :param checker: Checker function. Checker function interface :py:func:`ptah.interfaces.auth_checker` .. code-block:: python @ptah.auth_checker def my_checker(info): ... """ info = config.DirectiveInfo(__depth) discr = (AUTH_CHECKER_ID, hash(checker)) intr = config.Introspectable(AUTH_CHECKER_ID, discr, checker.__name__, 'ptah-authchecker') intr['name'] = '{0}.{1}'.format(info.codeinfo.module, checker.__name__) intr['callable'] = checker intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, checker: config.get_cfg_storage(AUTH_CHECKER_ID)\ .update({id(checker): checker}), (checker,), discriminator=discr, introspectables=(intr,)), __cfg) return checker
def __init__(self, name, title, description='', prefix='role:', system=False): id = '%s%s' % (prefix, name) self.id = id self.name = name self.title = title self.description = description self.system = system self.allowed = set() self.denied = set() # conflict detection and introspection info = config.DirectiveInfo() discr = (ID_ROLE, name) intr = config.Introspectable(ID_ROLE, discr, title, 'ptah-role') intr['role'] = self intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, r: \ config.get_cfg_storage(ID_ROLE).update({r.name: r}), (self, ), discriminator=discr, introspectables=(intr,)) )
def __call__(self, cls): typeinfo = TypeInformation(cls, self.name, **self.kw) cls.__type__ = typeinfo # config actino and introspection info discr = (TYPES_DIR_ID, self.name) intr = config.Introspectable(TYPES_DIR_ID, discr, self.name, 'ptah-type') intr['name'] = self.name intr['type'] = typeinfo intr['codeinfo'] = self.info.codeinfo def register_type_impl(cfg): # run phase handlers for name, handler in phase_data: handler(cfg, cls, typeinfo, self.name, **self.kw) cfg.get_cfg_storage(TYPES_DIR_ID)[typeinfo.__uri__] = typeinfo self.info.attach( config.Action(register_type_impl, discriminator=discr, introspectables=(intr, ))) return cls
def register_uri_resolver(schema, resolver, depth=1): """ Register resolver for given schema :param schema: uri schema :type schema: string :param resolver: Callable object that accept one parameter. Resolver interface:: class Resolver(object): def __call__(self, uri): return content """ discr = (ID_RESOLVER, schema) info = config.DirectiveInfo(depth=depth) intr = config.Introspectable(ID_RESOLVER, discr, resolver.__doc__, ID_RESOLVER) intr['schema'] = schema intr['callable'] = resolver intr['codeinfo'] = info.codeinfo info.attach( config.Action(_register_uri_resolver, (schema, resolver), discriminator=discr, introspectables=(intr, )))
def register_migration(pkg, path, title='', force=False): """Registers a migration for package. Check :ref:`data_migration_chapter` chapter for detailed description. :param pkg: Package name :param path: String implying a path or `asset specification` (e.g. ``ptah:migrations``). Path to directory with migration scripts. :param title: Optional human readable title. :param force: Force execute migration during bootstrap process .. code-block:: python import ptah ptah.register_migration( 'ptah', 'ptah:migrations', 'Ptah database migration') """ info = config.DirectiveInfo() discr = (MIGRATION_ID, pkg) intr = config.Introspectable(MIGRATION_ID, discr, pkg, MIGRATION_ID) intr['package'] = pkg intr['path'] = path intr['title'] = title intr['force'] = force def _complete(cfg, pkg, path): cfg.get_cfg_storage(MIGRATION_ID)[pkg] = path info.attach( config.Action(_complete, (pkg, path), discriminator=discr, introspectables=(intr, )))
def register_settings(name, *fields, **kw): """ register settings group """ iname = name for ch in ('.', '-'): iname = iname.replace(ch, '_') category = InterfaceClass('SettingsGroup:%s' % iname.upper(), (), __doc__='Settings group: %s' % name, __module__='ptah.config.settings') for field in fields: field.required = False if field.default is form.null: raise StopException( 'Default value is required for "{0}.{1}"'.format( name, field.name)) group = Group(name=name, *fields, **kw) interface.directlyProvides(Group, category) info = config.DirectiveInfo() discr = (ID_SETTINGS_GROUP, name) intr = config.Introspectable(ID_SETTINGS_GROUP, discr, group.__title__, ID_SETTINGS_GROUP) intr['name'] = name intr['group'] = group intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, group: config.get_cfg_storage(ID_SETTINGS_GROUP)\ .update({group.__name__: group.clone(config.registry)}), (group,), discriminator=discr, introspectables=(intr,)) )
def __call__(self, factory, cfg=None): intr = self.intr intr['factory'] = factory self.info.attach( config.Action(lambda cfg, name, intr: cfg.get_cfg_storage( POPULATE_ID).update({name: intr}), (intr['name'], intr), discriminator=self.discr, introspectables=(intr, )), cfg) return factory
def __call__(self, factory, cfg=None): intr = self.intr intr['factory'] = factory self.info.attach( config.Action(lambda cfg, name, f: cfg.get_cfg_storage( ID_ROLES_PROVIDER).update({name: f}), (intr['name'], factory), discriminator=self.discr, introspectables=(intr, )), cfg) return factory
def __call__(self, view): intr = self.intr intr['view'] = view self.info.attach( config.Action( config.LayerWrapper(register_layout_impl, self.discr), (view, intr['name'], intr['context'], intr['renderer'], intr['parent'], intr['route_name'], intr['use_global_views']), discriminator=self.discr, introspectables=(intr, ))) return view
def wrapper(func): discr = (PREVIEW_ID, cls) intr = config.Introspectable(PREVIEW_ID, discr, '', PREVIEW_ID) intr['field'] = cls intr['preview'] = func info.attach( config.Action(lambda config, cls, func: config.get_cfg_storage( PREVIEW_ID).update({cls: func}), (cls, func), discriminator=discr, introspectables=(intr, ))) return func
def __call__(self, changer, cfg=None): self.intr.title = changer.__doc__ self.intr['callable'] = changer self.info.attach( config.Action( lambda config, schema, changer: \ config.get_cfg_storage(ID_PASSWORD_CHANGER).update( {schema: changer}), (self.intr['schema'], changer), discriminator=self.discr, introspectables=(self.intr,)), cfg) return changer
def test_action(self): info = config.DirectiveInfo() action = config.Action(None, discriminator=('test', )) self.assertIsNone(action.hash) info.attach(action) self.assertIsNotNone(action.hash) self.assertIsNotNone(hash(action)) self.assertRaises(TypeError, info.attach, action) self.assertEqual(repr(action), '<Action "test">')
def __call__(self, searcher, cfg=None): self.intr['callable'] = searcher self.info.attach( config.Action( lambda config, name, searcher: config.get_cfg_storage(AUTH_SEARCHER_ID)\ .update({name: searcher}), (self.intr['name'], searcher), discriminator=self.discr, introspectables=(self.intr,)), cfg, self.depth) return searcher
def __call__(self, cls, __cfg=None): self.intr['provider'] = cls self.intr['name'] = '{0}.{1}'.format(self.info.codeinfo.module, cls.__name__) self.info.attach( config.Action( lambda config, n, p: config.get_cfg_storage(AUTH_PROVIDER_ID)\ .update({n: cls()}), (self.intr['name'], cls), discriminator=self.discr, introspectables=(self.intr,)), __cfg, self.depth) return cls
def register_principal_searcher(name, searcher): """ register principal searcher """ discr = (AUTH_SEARCHER_ID, name) intr = config.Introspectable(AUTH_SEARCHER_ID, discr, name, AUTH_SEARCHER_ID) intr['name'] = name intr['callable'] = searcher info = config.DirectiveInfo() info.attach( config.Action( lambda config, name, searcher: config.get_cfg_storage(AUTH_SEARCHER_ID).update({name:searcher}), (name, searcher), discriminator=discr, introspectables=(intr,)) )
def __call__(self, resolver, cfg=None): self.intr.title = resolver.__doc__ self.intr['callable'] = resolver self.info.attach( config.Action( lambda cfg, schema, resolver: cfg.get_cfg_storage(ID_RESOLVER)\ .update({schema: resolver}), (self.intr['schema'], resolver), discriminator=self.discr, introspectables=(self.intr,)), cfg, self.depth) return resolver
def wrapper(func): discr = (ID_RESOLVER, schema) intr = config.Introspectable(ID_RESOLVER, discr, func.__doc__, ID_RESOLVER) intr['schema'] = schema intr['callable'] = func intr['codeinfo'] = info.codeinfo info.attach( config.Action(_register_uri_resolver, (schema, func), discriminator=discr, introspectables=(intr, ))) return func
def wrapper(cls): intr = config.Introspectable(FIELD_ID, discr, name, FIELD_ID) intr['name'] = name intr['layer'] = layer intr['field'] = cls intr['codeinfo'] = info.codeinfo info.attach( config.Action(config.LayerWrapper(register_field_impl, discr), ( cls, name, ), discriminator=discr, introspectables=(intr, ))) return cls
def wrapper(cls): discr = (MANAGE_ID, name) intr = config.Introspectable(MANAGE_ID, discr, cls.title, MANAGE_ID) intr['name'] = name intr['factory'] = cls intr['codeinfo'] = info.codeinfo def _complete(cfg, cls, name): cls.name = name cfg.get_cfg_storage(MANAGE_ID)[name] = cls info.attach( config.Action(_complete, (cls, name), discriminator=discr, introspectables=(intr, ))) return cls
def wrapper(changer): discr = (ID_PASSWORD_CHANGER, schema) intr = config.Introspectable(ID_PASSWORD_CHANGER, discr, changer.__doc__, ID_PASSWORD_CHANGER) intr.update(schema=schema, callable=changer) info.attach( config.Action( lambda config, schema, changer: \ config.get_cfg_storage(ID_PASSWORD_CHANGER).update( {schema: changer}), (schema, changer), discriminator=discr, introspectables = (intr,)) ) return changer
def wrapper(searcher): discr = (AUTH_SEARCHER_ID, name) intr = config.Introspectable( AUTH_SEARCHER_ID, discr, name, AUTH_SEARCHER_ID) intr['name'] = name intr['callable'] = searcher info.attach( config.Action( lambda config, name, searcher: config.get_cfg_storage(AUTH_SEARCHER_ID)\ .update({name: searcher}), (name, searcher), discriminator=discr, introspectables=(intr,)) ) return searcher
def register_field_factory(cls, name, layer=''): info = config.DirectiveInfo() discr = (FIELD_ID, name, layer) intr = config.Introspectable(FIELD_ID, discr, name, FIELD_ID) intr['name'] = name intr['layer'] = layer intr['field'] = cls info.attach( config.Action(config.LayerWrapper(register_field_impl, discr), ( cls, name, ), discriminator=discr, introspectables=(intr, )))
def wrapper(func): discr = (ID_FORMATTER, name) intr = config.Introspectable(ID_FORMATTER, discr, name, ID_FORMATTER) intr['name'] = name intr['callable'] = func intr['description'] = func.__doc__ intr['codeinfo'] = info.codeinfo info.attach( config.Action(lambda config, name, func: config.get_cfg_storage( ID_FORMATTER).update({name: func}), (name, func), discriminator=discr, introspectables=(intr, ))) return func
def wrapper(cls): discr = (AUTH_PROVIDER_ID, name) intr = config.Introspectable( AUTH_PROVIDER_ID, discr, name, AUTH_PROVIDER_ID) intr['id'] = name intr['name'] = '{0}.{1}'.format(info.codeinfo.module, cls.__name__) intr['provider'] = cls intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, n, p: config.get_cfg_storage(AUTH_PROVIDER_ID)\ .update({n: cls()}), (name, cls), discriminator=discr, introspectables=(intr,)) ) return cls
def wrapper(view): discr = (SNIPPET_ID, name, context, layer) intr = config.Introspectable(SNIPPET_ID, discr, name, SNIPPET_ID) intr['name'] = name intr['context'] = context intr['renderer'] = renderer intr['layer'] = layer intr['module'] = info.module.__name__ intr['codeinfo'] = info.codeinfo info.attach( config.Action(config.LayerWrapper(register_snippet_impl, discr), (view, name, context, renderer), discriminator=discr, introspectables=(intr, ))) return view
def uiaction(context, id, title, description='', action='', condition=None, permission=None, category='', sort_weight=1.0, **kw): """ Register ui action """ kwargs = { 'id': id, 'title': title, 'description': description, 'category': category, 'condition': condition, 'permission': permission, 'sort_weight': sort_weight, 'data': kw } if callable(action): kwargs['action_factory'] = action else: kwargs['action'] = action ac = Action(**kwargs) info = config.DirectiveInfo() discr = (ID_UIACTION, id, context, category) intr = ptah.config.Introspectable(ID_UIACTION, discr, title, 'ptah-uiaction') intr['action'] = ac intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda cfg, id, category, context, ac: \ cfg.registry.registerAdapter(\ ac, (context,), IAction, '%s-%s'%(category, id)), (id, category, context, ac,), discriminator = discr, introspectables = (intr,)) )
def wrapper(func): discr = (ID_CMS_REST, name, context) intr = config.Introspectable(ID_CMS_REST, discr, name, ID_CMS_REST) intr['name'] = name intr['context'] = context intr['permission'] = permission intr['callable'] = func def _register(cfg, callable, name, context, permission): ac = Action(callable, name, permission) cfg.registry.registerAdapter(ac, (IRestActionClassifier, context), IRestAction, name) info.attach( config.Action(_register, (func, name, context, permission), discriminator=discr, introspectables=(intr, ))) return func
def register_snippet(name, context=None, view=None, renderer=None, layer=''): info = config.DirectiveInfo() discr = (SNIPPET_ID, name, context, layer) intr = config.Introspectable(SNIPPET_ID, discr, name, SNIPPET_ID) intr['name'] = name intr['view'] = view intr['context'] = context intr['renderer'] = renderer intr['layer'] = layer intr['module'] = info.module.__name__ intr['codeinfo'] = info.codeinfo info.attach( config.Action(config.LayerWrapper(register_snippet_impl, discr), (view, name, context, renderer), discriminator=discr, introspectables=(intr, )))
def __init__(self, id, title, description=''): self.id = id self.title = title self.description = description info = config.DirectiveInfo() discr = (ID_ACL, id) intr = config.Introspectable(ID_ACL, discr, title, 'ptah-aclmap') intr['acl'] = self intr['codeinfo'] = info.codeinfo info.attach( config.Action( lambda config, p: \ config.get_cfg_storage(ID_ACL).update({id: p}), (self,), discriminator=discr, introspectables=(intr,)) ) self.directiveInfo = info