예제 #1
0
def create_behaviors_factory(proto_name, proto_definition):

    if proto_definition.get('for', None) is None:
        raise Exception('We need a for interface')
    else:
        for_ = import_class(proto_definition.get('for'))

    if for_ is None:
        raise Exception('Wrong for interface')

    parent_class = import_class(
        proto_definition.get(
            'inherited_class',
            'guillotina.behaviors.instance.AnnotationBehavior'))

    schema_fields, tags = get_fields(
        properties=proto_definition.get('properties'))

    base_interface = proto_definition.get('base_interface', None)
    if base_interface is None:
        base_interface = Interface

    class_interface = InterfaceClass('I' + proto_name, (base_interface, ),
                                     schema_fields,
                                     __module__='guillotina_cms.interfaces')

    for field_id, tag in tags.items():
        for tag_id, tag_metadata in tag.items():
            if tag_id in SUPPORTED_DIRECTIVES:
                SUPPORTED_DIRECTIVES[tag_id].apply(class_interface, field_id,
                                                   tag_metadata)

    klass = type(proto_name, (parent_class, ), {})

    klass.__module__ = 'guillotina_cms.behaviors'

    behavior = {
        'for_': for_,
        'provides': class_interface,
        'data_key': proto_definition.get('data_key', 'default'),
        'auto_serialize': proto_definition.get('auto_serialize', True),
        'name': proto_name,
        'name_only': proto_definition.get('name_only', False),
        'title': proto_definition.get('title', ''),
        'marker': proto_definition.get('marker', None),
        'description': proto_definition.get('description', '')
    }

    configure.register_configuration(klass, behavior, 'behavior')

    root = get_utility(IApplication, name='root')
    configure.load_configuration(root.app.config, 'guillotina_cms.behaviors',
                                 'behavior')
    root.app.config.execute_actions()
    configure.clear()
    load_cached_schema()

    # Verify its created
    interface_name = 'guillotina_cms.interfaces.I' + proto_name
    utility = get_utility(IBehavior, name=interface_name)
    interface_name = 'guillotina_cms.interfaces.I' + proto_name
    utility2 = get_utility(IBehavior, name=proto_name)
    assert BEHAVIOR_CACHE[interface_name] == class_interface
    utility.interface == class_interface
    utility2.interface == class_interface
예제 #2
0
def make_app(config_file=None, settings=None, loop=None, server_app=None):
    app_settings.update(_delayed_default_settings)

    if loop is None:
        loop = asyncio.get_event_loop()

    loop.set_task_factory(aiotask_context.task_factory)

    if config_file is not None:
        with open(config_file, 'r') as config:
            settings = json.load(config)
    elif settings is None:
        raise Exception('Neither configuration or settings')

    # Create root Application
    root = ApplicationRoot(config_file)
    provide_utility(root, IApplication, 'root')

    # Initialize global (threadlocal) ZCA configuration
    config = root.config = ConfigurationMachine()

    import guillotina
    import guillotina.db.factory
    import guillotina.db.writer
    import guillotina.db.db
    configure.scan('guillotina.translation')
    configure.scan('guillotina.renderers')
    configure.scan('guillotina.api')
    configure.scan('guillotina.content')
    configure.scan('guillotina.registry')
    configure.scan('guillotina.auth')
    configure.scan('guillotina.json')
    configure.scan('guillotina.behaviors')
    configure.scan('guillotina.languages')
    configure.scan('guillotina.permissions')
    configure.scan('guillotina.security.security_local')
    configure.scan('guillotina.security.policy')
    configure.scan('guillotina.auth.participation')
    configure.scan('guillotina.catalog.index')
    configure.scan('guillotina.catalog.catalog')
    configure.scan('guillotina.framing')
    configure.scan('guillotina.files')
    configure.scan('guillotina.annotations')
    configure.scan('guillotina.constraintypes')
    configure.scan('guillotina.subscribers')
    configure.scan('guillotina.db.strategies')
    configure.scan('guillotina.db.cache')
    load_application(guillotina, root, settings)
    config.execute_actions()
    config.commit()

    for module_name in settings.get('applications', []):
        config.begin(module_name)
        load_application(resolve_dotted_name(module_name), root, settings)
        config.execute_actions()
        config.commit()

    # XXX we clear now to save some memory
    # it's unclear to me if this is necesary or not but it seems to me that
    # we don't need things registered in both components AND here.
    configure.clear()

    # update *after* plugins loaded
    update_app_settings(settings)

    if 'logging' in app_settings:
        logging.config.dictConfig(app_settings['logging'])

    # Make and initialize aiohttp app
    if server_app is None:
        server_app = make_aiohttp_application()
    root.app = server_app
    server_app.root = root
    server_app.config = config

    content_type = ContentNegotiatorUtility('content_type',
                                            app_settings['renderers'].keys())
    language = ContentNegotiatorUtility('language',
                                        app_settings['languages'].keys())

    provide_utility(content_type, IContentNegotiation, 'content_type')
    provide_utility(language, IContentNegotiation, 'language')

    for database in app_settings['databases']:
        for key, dbconfig in database.items():
            factory = get_utility(IDatabaseConfigurationFactory,
                                  name=dbconfig['storage'])
            if asyncio.iscoroutinefunction(factory):
                future = asyncio.ensure_future(factory(key, dbconfig,
                                                       server_app),
                                               loop=loop)

                loop.run_until_complete(future)
                root[key] = future.result()
            else:
                root[key] = factory(key, dbconfig)

    for key, file_path in list_or_dict_items(app_settings['static']):
        path = resolve_path(file_path).resolve()
        if not path.exists():
            raise Exception('Invalid static directory {}'.format(file_path))
        if path.is_dir():
            root[key] = StaticDirectory(path)
        else:
            root[key] = StaticFile(path)
    for key, file_path in list_or_dict_items(app_settings['jsapps']):
        path = resolve_path(file_path).resolve()
        if not path.exists() or not path.is_dir():
            raise Exception('Invalid jsapps directory {}'.format(file_path))
        root[key] = JavaScriptApplication(path)

    root.set_root_user(app_settings['root_user'])

    if RSA is not None and not app_settings.get('rsa'):
        key = RSA.generate(2048)
        pub_jwk = {'k': key.publickey().exportKey('PEM')}
        priv_jwk = {'k': key.exportKey('PEM')}
        app_settings['rsa'] = {'pub': pub_jwk, 'priv': priv_jwk}

    # Set router root
    server_app.router.set_root(root)

    for utility in get_all_utilities_registered_for(IAsyncUtility):
        # In case there is Utilties that are registered
        if hasattr(utility, 'initialize'):
            task = asyncio.ensure_future(lazy_apply(utility.initialize,
                                                    app=server_app),
                                         loop=loop)
            root.add_async_task(utility, task, {})
        else:
            logger.warn(f'No initialize method found on {utility} object')

    server_app.on_cleanup.append(close_utilities)

    for util in app_settings['utilities']:
        root.add_async_utility(util, loop=loop)

    # Load cached Schemas
    load_cached_schema()

    optimize_settings(app_settings)

    return server_app
예제 #3
0
def create_content_factory(proto_name, proto_definition):
    parent_interface = import_class(
        proto_definition.get('inherited_interface',
                             'guillotina.interfaces.content.IFolder'))
    parent_class = import_class(
        proto_definition.get('inherited_class', 'guillotina.content.Folder'))

    schema_fields, tags = get_fields(
        properties=proto_definition.get('properties'))

    for fieldset_id, fieldset_list in proto_definition.get('fieldsets',
                                                           {}).items():
        for field_id in fieldset_list:
            tags.setdefault(field_id, {})['fieldset'] = fieldset_id

    class_interface = InterfaceClass('I' + proto_name, (parent_interface, ),
                                     schema_fields,
                                     __module__='guillotina_cms.interfaces')

    for field_id, tag in tags.items():
        for tag_id, tag_metadata in tag.items():
            if tag_id in SUPPORTED_DIRECTIVES:
                if tag_metadata is None:
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id)
                elif isinstance(tag_metadata, dict):
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id,
                                                       **tag_metadata)
                elif isinstance(tag_metadata, list):
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id, *tag_metadata)
                elif tag_id == 'fieldset':
                    SUPPORTED_DIRECTIVES[tag_id].apply(class_interface,
                                                       field_id, tag_metadata)
                elif isinstance(tag_metadata, str):
                    SUPPORTED_DIRECTIVES[tag_id].apply(
                        class_interface, **{field_id: tag_metadata})

    klass = type(proto_name, (parent_class, ), {})

    klass.__module__ = 'guillotina_cms.dyncontent'
    setattr(dyncontent, proto_name, klass)

    behaviors = []
    for bhr in proto_definition.get('behaviors', []):
        if bhr in BEHAVIOR_CACHE:
            behaviors.append(BEHAVIOR_CACHE[bhr])
        else:
            raise Exception(f"Behavior not found {bhr}")

    contenttype = {
        'schema':
        class_interface,
        'type_name':
        proto_name,
        'allowed_types':
        proto_definition.get('allowed_types', []),
        'add_permission':
        proto_definition.get('add_permission', 'guillotina.AddContent'),
        'behaviors':
        behaviors
    }

    utility = query_utility(IResourceFactory, name=proto_name)
    if utility is not None:
        sm = get_global_components()
        sm.unregisterUtility(utility, IResourceFactory, proto_name)

    configure.register_configuration(klass, contenttype, 'contenttype')

    root = get_utility(IApplication, name='root')
    configure.load_configuration(root.app.config, 'guillotina_cms.dyncontent',
                                 'contenttype')
    root.app.config.execute_actions()
    configure.clear()
    load_cached_schema()

    # Verify its created
    if proto_name in FACTORY_CACHE:
        del FACTORY_CACHE[proto_name]
    get_cached_factory(proto_name)