def toargs(context, schema, data): """Marshal data to an argument dictionary using a schema Names that are python keywords have an underscore added as a suffix in the schema and in the argument list, but are used without the underscore in the data. The fields in the schema must all implement IFromUnicode. All of the items in the data must have corresponding fields in the schema unless the schema has a true tagged value named 'keyword_arguments'. """ data = dict(data) args = {} for name, field in schema.namesAndDescriptions(True): field = field.bind(context) n = name if n.endswith('_') and iskeyword(n[:-1]): n = n[:-1] s = data.get(n, data) if s is not data: s = text_type(s) del data[n] try: args[str(name)] = field.fromUnicode(s) except ValidationError as v: reraise(ConfigurationError("Invalid value for", n, str(v)), None, sys.exc_info()[2]) elif field.required: # if the default is valid, we can use that: default = field.default try: field.validate(default) except ValidationError: raise ConfigurationError("Missing parameter:", n) args[str(name)] = default if data: # we had data left over try: keyword_arguments = schema.getTaggedValue('keyword_arguments') except KeyError: keyword_arguments = False if not keyword_arguments: raise ConfigurationError("Unrecognized parameters:", *data) for name in data: args[str(name)] = data[name] return args
def page(self, _context, name, attribute=None, template=None): if template: template = os.path.abspath(_context.path(template)) if not os.path.isfile(template): raise ConfigurationError("No such file", template) else: if not attribute: raise ConfigurationError( "Must specify either a template or an attribute name") self.pages.append((name, attribute, template)) return ()
def tile(_context, name, title=None, description=None, icon=None, add_permission=None, edit_permission=None, delete_permission=None, schema=None, for_=None, layer=None, class_=None, template=None, permission=None): """Implements the <plone:tile /> directive """ if (title is not None or description is not None or icon is not None or add_permission is not None or schema is not None): if title is None or add_permission is None: raise ConfigurationError( u"When configuring a new type of tile, 'title' and " u"'add_permission' are required") type_ = TileType(name, title, add_permission, edit_permission, delete_permission, description, icon, schema) utility(_context, provides=ITileType, component=type_, name=name) if (for_ is not None or layer is not None or class_ is not None or template is not None or permission is not None): if class_ is None and template is None: raise ConfigurationError( u"'class' or 'template' must be given when configuring a tile." ) if permission is None: raise ConfigurationError( u"When configuring a tile, 'permission' is required") if for_ is None: for_ = Interface if layer is None: layer = IDefaultBrowserLayer if class_ is None: class_ = Tile page(_context, name=name, permission=permission, for_=for_, layer=layer, template=template, class_=class_)
def behaviorDirective(_context, title, provides, description=None, marker=None, factory=None, for_=None): if marker is None and factory is None: marker = provides if factory is None and marker is not None and marker is not provides: raise ConfigurationError( u"You cannot specify a different 'marker' and 'provides' if " u"there is no adapter factory for the provided interface.") # Instantiate the real factory if it's the schema-aware type. We do # this here so that the for_ interface may take this into account. if factory is not None and ISchemaAwareFactory.providedBy(factory): factory = factory(provides) # Attempt to guess the factory's adapted interface and use it as the for_ if for_ is None and factory is not None: adapts = getattr(factory, '__component_adapts__', None) if adapts: if len(adapts) != 1: raise ConfigurationError( u"The factory cannot be declared a multi-adapter.") for_ = adapts[0] else: for_ = Interface elif for_ is None: for_ = Interface registration = BehaviorRegistration(title=title, description=description, interface=provides, marker=marker, factory=factory) adapter_factory = BehaviorAdapterFactory(registration) utility(_context, provides=IBehavior, name=provides.__identifier__, component=registration) if factory is not None: adapter(_context, factory=(adapter_factory, ), provides=provides, for_=(for_, ))
def factory(self, context, name): r = self._registry.get(name) if r is None: # Try namespace-independent name ns, n = name r = self._registry.get(n) if r is None: raise ConfigurationError("Unknown directive", ns, n) f = r.lookup1(providedBy(context), Interface) if f is None: raise ConfigurationError( "The directive %s cannot be used in this context" % (name, )) return f
def icon(_context, name, for_, file=None, resource=None, layer=IDefaultBrowserLayer, title=None, width=16, height=16): iname = for_.getName() if title is None: title = iname if title.startswith('I'): title = title[1:] # Remove leading 'I' if file is not None and resource is not None: raise ConfigurationError( "Can't use more than one of file, and resource " "attributes for icon directives" ) elif file is not None: resource = '-'.join(for_.__module__.split('.')) resource = "%s-%s-%s" % (resource, iname, name) ext = os.path.splitext(file)[1] if ext: resource += ext # give this module another name, so we can use the "resource" directive # in it that won't conflict with our local variable with the same name. from zope.browserresource import metaconfigure metaconfigure.resource(_context, file=file, name=resource, layer=layer) elif resource is None: raise ConfigurationError( "At least one of the file, and resource " "attributes for resource directives must be specified" ) vfactory = IconViewFactory(resource, title, width, height) _context.action( discriminator = ('view', name, vfactory, layer), callable = handler, args = ('registerAdapter', vfactory, (for_, layer), Interface, name, _context.info) ) _context.action( discriminator = None, callable = provideInterface, args = (for_.__module__+'.'+for_.getName(), for_) )
def installSiteHook(_context, class_, site_class=None): if site_class is None: if not IPossibleSite.implementedBy(class_): # This is not a possible site, we need to monkey-patch it so that # it is. site_class = FiveSite else: if not IPossibleSite.implementedBy(site_class): raise ConfigurationError('Site class does not implement ' 'IPossibleClass: %s' % site_class) # only install the hook once already = getattr(class_, '_localsite_marker', False) if site_class is not None and not already: class_._localsite_marker = True _context.action( discriminator = (class_,), callable = classSiteHook, args=(class_, site_class) ) _context.action( discriminator = (class_, IPossibleSite), callable = classImplements, args=(class_, IPossibleSite) )
def registerGitRemoteResourceDirectory(_context, uri, branch='master', directory='', name=None, type=None): """ Register a new resource directory. The actual ZCA registrations are deferred so that conflicts can be resolved via zope.configuration's discriminator machinery. """ if name is None and _context.package: name = _context.package.__name__ if type: identifier = '++%s++%s' % (type, name or '') else: if _context.package: raise ConfigurationError('Resource directories in distributions ' 'must have a specified resource type.') identifier = name or '' directory = ResourceDirectory(uri, branch, directory, type, name) _context.action( discriminator=('plone:git-remote', identifier), callable=handler, args=('registerUtility', directory, IResourceDirectory, identifier), )
def __init__(self, **kwargs): if 'base' not in kwargs: raise ConfigurationError('A base svg is required') self.base = Image(filename=kwargs['base']) if 'logo' in kwargs: self.logo = Image(filename=kwargs['logo']) if 'mobile' in kwargs: self.mobile_logo = Image(filename=kwargs['mobile']) if 'favicon' in kwargs: self.favicon = Image(filename=kwargs['favicon']) if 'height' in kwargs: # Update by reference the transformer with the new height SCALES['LOGOS']['LOGO'] = make_transformer(height=kwargs['height']) if 'mobile_height' in kwargs: # Update by reference the transformer with the new height SCALES['LOGOS']['MOBILE_LOGO'] = make_transformer( height=kwargs['mobile_height']) self.cachekey = get_cachekey_from_blob( self.base.make_blob(), self.logo and self.logo.make_blob() or None, self.mobile_logo and self.mobile_logo.make_blob() or None, self.favicon and self.favicon.make_blob() or None, ) self.scales = {} self.collect_scales() self.set_primary_logo_scale(**kwargs)
def _normalize(self): if self.for_ is None: self.for_ = self.schema if self.class_ is None: self.bases = (self.view,) else: self.bases = (self.class_, self.view) if self.template is not None: self.template = os.path.abspath(str(self.template)) if not os.path.isfile(self.template): raise ConfigurationError("No such file", self.template) else: self.template = self.default_template self.names = getFieldNamesInOrder(self.schema) if self.fields: for name in self.fields: if name not in self.names: raise ValueError("Field name is not in schema", name, self.schema) else: self.fields = self.names
def __call__(self, require=None): if self.name is None: return if self.defaultLanguage not in self.__data: raise ConfigurationError( "A translation for the default language (%s) " "must be specified" % self.defaultLanguage) permission = self.permission factory = I18nFileResourceFactory(self.__data, self.defaultLanguage) if permission: if require is None: require = {} if permission == 'zope.Public': permission = CheckerPublic if require: checker = Checker(require) factory = self._proxyFactory(factory, checker) self._context.action(discriminator=('i18n-resource', self.name, self.type, self.layer), callable=handler, args=('registerAdapter', factory, (self.layer, ), Interface, self.name, self._context.info))
def register(self, method, mimetype, name, priority, factory): """Register a factory for method+mimetype """ # initialize the two-level deep nested datastructure if necessary if not self._d.has_key(method): self._d[method] = {} if not self._d[method].has_key(mimetype): self._d[method][mimetype] = [] l = self._d[method][mimetype] # Check if there is already a registered publisher factory (check by # name). If yes then it will be removed and replaced by a new # publisher. for pos, d in enumerate(l): if d['name'] == name: del l[pos] break # add the publisher factory + additional informations l.append({'name' : name, 'factory' : factory, 'priority' : priority}) # order by descending priority l.sort(lambda x,y: -cmp(x['priority'], y['priority'])) # check if the priorities are unique priorities = [item['priority'] for item in l] if len(sets.Set(priorities)) != len(l): raise ConfigurationError('All registered publishers for a given ' 'method+mimetype must have distinct ' 'priorities. Please check your ZCML ' 'configuration')
def __init__(self, context, controller, for_=None, name='', renderer=None, permission=None, containment=None, route_name=None, wrapper=None, form_id=None, method=None): self.context = context self.controller = controller self.for_ = for_ self.name = name self.renderer = renderer self.permission = permission self.containment = containment self.route_name = route_name self.wrapper = wrapper self.form_id = form_id method = method or 'POST' if method not in ('GET', 'POST'): raise ConfigurationError( 'method must be one of "GET" or "POST" (not "%s")' % method) self.method = method self._actions = [] # mutated by subdirectives
def __call__(self): (_context, name, for_, permission, layer, class_, allowed_interface, allowed_attributes) = self.args required = {} cdict = {} pages = {} for pname, attribute, template in self.pages: try: s = getGlobalService(Presentation) except ComponentLookupError, err: pass if template: cdict[pname] = ZopeTwoPageTemplateFile(template) if attribute and attribute != name: cdict[attribute] = cdict[pname] else: if not hasattr(class_, attribute): raise ConfigurationError("Undefined attribute", attribute) attribute = attribute or pname required[pname] = permission pages[pname] = attribute
def initialize(_context, component): if not callable(component): raise ConfigurationError("'component' should be callable") _context.action(discriminator="%s.%s" % (component.__module__, component.__name__), callable=component, args=())
def register(self, scheme, method, mimetype, name, priority, factory): """Register a factory for scheme + method + mimetype """ # initialize the three-level deep nested datastructure if necessary m = self._d.setdefault(scheme, {}) m = m.setdefault(method, {}) l = m.setdefault(mimetype, []) # Check if there is already a registered request factory (check by # name). If yes then it will be removed and replaced by a new # factory. for pos, d in enumerate(l): if d['name'] == name: del l[pos] break # add the publisher factory + additional informations l.append({'name': name, 'factory': factory, 'priority': priority}) # order by descending priority l.sort(lambda x, y: -cmp(x['priority'], y['priority'])) # check if the priorities are unique priorities = [item['priority'] for item in l] if len(set(priorities)) != len(l): raise ConfigurationError('All registered publishers for a given ' 'scheme+method+mimetype must have ' 'distinct priorities. Please check your ' 'configuration.')
def viewletManagerDirective( _context, name, permission, for_=Interface, layer=IDefaultBrowserLayer, view=IBrowserView, provides=interfaces.IViewletManager, class_=None, template=None, allowed_interface=None, allowed_attributes=None): # If class is not given we use the basic viewlet manager. if class_ is None: class_ = manager.ViewletManagerBase # Iterate over permissions if allowed_attributes is None: allowed_attributes = ['render', 'update'] if allowed_interface is not None: for interface in allowed_interface: allowed_attributes.extend(interface.names()) # Make sure that the template exists and that all low-level API methods # have the right permission. if template: template = os.path.abspath(str(_context.path(template))) if not os.path.isfile(template): raise ConfigurationError("No such file", template) allowed_attributes.append('__getitem__') # Create a new class based on the template and class. new_class = manager.ViewletManager( name, provides, template=template, bases=(class_, )) else: # Create a new class based on the class. new_class = manager.ViewletManager(name, provides, bases=(class_, )) # Register interfaces _handle_for(_context, for_) zcml.interface(_context, view) # register a viewlet manager _context.action( discriminator = ('viewletManager', for_, layer, view, name), callable = zcml.handler, args = ('registerAdapter', new_class, (for_, layer, view), provides, name, _context.info),) _context.action( discriminator = ('five:protectClass', new_class), callable = protectClass, args = (new_class, permission) ) if allowed_attributes: for attr in allowed_attributes: _context.action( discriminator = ('five:protectName', new_class, attr), callable = protectName, args = (new_class, attr, permission) ) _context.action( discriminator = ('five:initialize:class', new_class), callable = InitializeClass, args = (new_class,) )
def viewDirective(_context, view, name=u'', controller=zope.interface.Interface, layer=IDefaultBrowserLayer, provides=IModelTemplate, contentType='text/html', macro=None): # Make sure that the template exists view = os.path.abspath(str(_context.path(view))) if not os.path.isfile(view): raise ConfigurationError("No such file", view) factory = TemplateFactory(view, contentType, macro) zope.interface.directlyProvides(factory, provides) # register the view if name: zope.component.zcml.adapter(_context, (factory, ), provides, (controller, layer), name=name) else: zope.component.zcml.adapter(_context, (factory, ), provides, (controller, layer))
def __init__(self, _context, **kwargs): super(FormDirective, self).__init__(_context, **kwargs) attrs = self.class_.__dict__.keys() if 'template' not in kwargs.keys() and 'update' not in attrs and \ ('getData' not in attrs or 'setData' not in attrs): raise ConfigurationError( "You must specify a class that implements `getData()` " "and `setData()`, if you do not overwrite `update()`.")
def createDirectDelivery(): mailerObject = queryUtility(IMailer, mailer) if mailerObject is None: raise ConfigurationError("Mailer %r is not defined" % mailer) delivery = DirectMailDelivery(mailerObject) handler('registerUtility', delivery, IMailDelivery, name)
def IconDirective(_context, name, for_, file=None, resource=None, layer=IDefaultBrowserLayer, title=None, width=16, height=16): iname = for_.getName() if title is None: title = iname if IName.match(title): title = title[1:] # Remove leading 'I' if file is not None and resource is not None: raise ConfigurationError( "Can't use more than one of file, and resource " "attributes for icon directives") elif file is not None: resource = '-'.join(for_.__module__.split('.')) resource = "%s-%s-%s" % (resource, iname, name) ext = os.path.splitext(file)[1] if ext: resource += ext metaconfigure.resource(_context, image=file, name=resource, layer=layer) elif resource is None: raise ConfigurationError( "At least one of the file, and resource " "attributes for resource directives must be specified") vfactory = IconViewFactory(resource, title, width, height) _context.action(discriminator=('view', name, vfactory, layer), callable=handler, args=('registerAdapter', vfactory, (for_, layer), Interface, name, _context.info)) _context.action(discriminator=None, callable=provideInterface, args=(for_.__module__ + '.' + for_.getName(), for_))
def _checkViewFor(for_=None, layer=None, view_name=None): """Check if there is a view of that name registered for IAdding and IBrowserRequest. If not raise a ConfigurationError It will raise a ConfigurationError if : o view="" o if view_name is not registred """ if view_name is None: raise ConfigurationError( "Within a addMenuItem directive the view attribut" " is optional but can\'t be empty") gsm = getGlobalSiteManager() if gsm.adapters.lookup((for_, layer), Interface, view_name) is None: raise ConfigurationError("view name %s not found " % view_name)
def _handle_menu(_context, menu, title, for_, name, permission): if menu or title: if not (menu and title): raise ConfigurationError( "If either menu or title are specified, they must " "both be specified.") if len(for_) != 1: raise ConfigurationError( "Menus can be specified only for single-view, not for " "multi-views.") return menuItemDirective( _context, menu, for_[0], '@@' + str(name), title, permission=permission) return []
def resourceDirectory(_context, name, directory, layer=IDefaultBrowserLayer, permission='zope.Public'): if not os.path.isdir(directory): raise ConfigurationError("Directory %s does not exist" % directory) resource = DirectoryResourceFactory.resource f_cache = {} resource_factories = dict(resource.resource_factories) resource_factories['default'] = resource.default_factory for ext, factory in resource_factories.items(): if f_cache.get(factory) is not None: continue factory_info = _rd_map.get(factory) factory_info['count'] += 1 class_name = '%s%s' % (factory_info['prefix'], factory_info['count']) factory_name = '%s%s' % (factory.__name__, factory_info['count']) f_resource = type(class_name, (factory.resource, ), {}) f_cache[factory] = type(factory_name, (factory, ), {'resource': f_resource}) for ext, factory in resource_factories.items(): resource_factories[ext] = f_cache[factory] default_factory = resource_factories['default'] del resource_factories['default'] cdict = { 'resource_factories': resource_factories, 'default_factory': default_factory } factory_info = _rd_map.get(DirectoryResourceFactory) factory_info['count'] += 1 class_name = '%s%s' % (factory_info['prefix'], factory_info['count']) dir_factory = type(class_name, (resource, ), cdict) factory = DirectoryResourceFactory(name, directory, resource_factory=dir_factory) new_classes = [ dir_factory, ] + [f.resource for f in f_cache.values()] _context.action( discriminator=('resource', name, IBrowserRequest, layer), callable=handler, args=('registerAdapter', factory, (layer, ), Interface, name, _context.info), ) for new_class in new_classes: _context.action(discriminator=('five:protectClass', new_class), callable=protectClass, args=(new_class, permission)) _context.action(discriminator=('five:initialize:class', new_class), callable=InitializeClass, args=(new_class, ))
def hotspotDirective(_context, name, obj=None, interface=None, resource=[], considerparams=[]): if not obj and not interface and not resource: raise ConfigurationError(u"Du solltest dich entscheiden, Jonny!") hotspot = Hotspot(obj, interface, resource, considerparams) utility(_context, provides=IHotspot, component=hotspot, name=name)
def handler(name, dependencies, *provideAdapterArgs): if dependencies: for dep in dependencies: if dep not in library_info: raise ConfigurationError( 'Resource library "%s" has unsatisfied dependency on "%s".' % (name, dep)) zapi.getGlobalSiteManager().provideAdapter(*provideAdapterArgs)
def menuDirective(_context, id=None, class_=BrowserMenu, interface=None, title=u'', description=u''): """Registers a new browser menu.""" if id is None and interface is None: raise ConfigurationError( "You must specify the 'id' or 'interface' attribute.") if interface is None: if id in dir(menus): # reuse existing interfaces for the id, without this we are not # able to override menus. interface = getattr(menus, id) else: interface = InterfaceClass(id, (), __doc__='Menu Item Type: %s' %id, __module__='zope.app.menus') # Add the menu item type to the `menus` module. # Note: We have to do this immediately, so that directives using the # MenuField can find the menu item type. setattr(menus, id, interface) path = 'zope.app.menus.' + id else: path = interface.__module__ + '.' + interface.getName() # If an id was specified, make this menu available under this id. # Note that the menu will be still available under its path, since it # is an adapter, and the `MenuField` can resolve paths as well. if id is None: id = path else: # Make the interface available in the `zope.app.menus` module, so # that other directives can find the interface under the name # before the CA is setup. _context.action( discriminator = ('browser', 'MenuItemType', path), callable = provideInterface, args = (path, interface, IMenuItemType, _context.info) ) setattr(menus, id, interface) # Register the layer interface as an interface _context.action( discriminator = ('interface', path), callable = provideInterface, args = (path, interface), kw = {'info': _context.info} ) # Register the menu item type interface as an IMenuItemType _context.action( discriminator = ('browser', 'MenuItemType', id), callable = provideInterface, args = (id, interface, IMenuItemType, _context.info) ) # Register the menu as a utility utility(_context, IBrowserMenu, class_(id, title, description), name=id)
def handler(name, dependencies, required, provided, adapter_name, factory, info=''): if dependencies: for dep in dependencies: if dep not in library_info: raise ConfigurationError( 'Resource library "%s" has unsatisfied dependency on "%s".' % (name, dep)) getSiteManager().registerAdapter( factory, required, provided, adapter_name, info)
def checkDuplicate(self, filename): """Check for duplicate imports of the same file. Raises an exception if this file had been processed before. This is better than an unlimited number of conflict errors. """ path = self.path(filename) if path in self._seen_files: raise ConfigurationError('%r included more than once' % path) self._seen_files.add(path)
def resource_directory(_context, name, directory): if directory: directory = osPath(_context.path(directory)) if not directory.is_dir(): raise ConfigurationError('No such directory', directory) root = getUtility(IApplication, 'root') if name not in root: # prevent circular import from plone.server.content import StaticDirectory root[name] = StaticDirectory(directory)