<commit_before>"""Resource type configuration and default factory."""
from pyramid.path import DottedNameResolver
from pyramid.threadlocal import get_current_registry
from pyramid.config import Configurator
from substanced.content import add_content_type
from zope.interface import directlyProvides
from zope.interface import alsoProvides

from adhocracy.interfaces import ResourceMetadata
from adhocracy.events import ResourceCreatedAndAdded
from adhocracy.sheets.name import IName
from adhocracy.utils import get_sheet


def add_resource_type_to_registry(metadata: ResourceMetadata,
                                  config: Configurator):
    """Add the `resource` type specified in metadata to the content registry.

    As generic factory the :class:`ResourceFactory` is used.

    """
    assert hasattr(config.registry, 'content')
    iresource = metadata.iresource
    name = metadata.content_name or iresource.__identifier__
    meta = {'content_name': name,
            'resource_metadata': metadata}
    add_content_type(config, iresource.__identifier__,
                     ResourceFactory(metadata),
                     factory_type=iresource.__identifier__, **meta)


class ResourceFactory:

    """Basic resource factory."""

    name_identifier = IName.__identifier__

    def __init__(self, metadata: ResourceMetadata):
        self.meta = metadata

    def _add(self, parent, resource, appstructs):
        """Add resource to context folder.

        Returns:
            name (String)
        Raises:
            substanced.folder.FolderKeyError
            ValueError

        """
        # TODO use seperated factory for IVersionables
        name = ''
        if self.name_identifier in appstructs:
            name = appstructs[self.name_identifier]['name']
        if self.meta.use_autonaming:
            prefix = self.meta.autonaming_prefix
            name = parent.next_name(resource, prefix=prefix)
        if name in parent:
            raise KeyError
        if name == '':
            raise KeyError
        parent.add(name, resource, send_events=False)

    def _notify_new_resource_created_and_added(self, resource, registry):
        has_parent = resource.__parent__ is not None
        if has_parent and registry is not None:
            event = ResourceCreatedAndAdded(object=resource,
                                            parent=resource.__parent__,
                                            registry=registry)
            registry.notify(event)

    def __call__(self,
                 parent=None,
                 appstructs={},
                 run_after_creation=True,
                 **kwargs
                 ):
        """Triggered when a ResourceFactory instance is called.

        Args:
            parent (IPool or None): Add the new resource to this pool.
                                    None value is allowed to create non
                                    persistent Resources (without OID/parent).
            appstructs (dict): Key/Values of sheet appstruct data.
                               Key is anidentifier of a sheet interface.
                               Value is the data to set.
            after_creation (bool): Whether to invoke after_creation hooks,
                                   Default is True.
                                   If parent is None you should set this False
            **kwargs: Arbitary keyword arguments. Will be passed along to
                after_creation hooks as 3rd argument 'options'.

        Returns:
            object (IResource): the newly created resource

        Raises:
            KeyError: if self.metadata.use_autonaming is False and the
                      `resource name` is not given or already used in the
                      `parent` pool.
                      You can set the `resource name` with appstruct data
                      for the name sheet (:mod:`adhocracy.sheets.name`).
            ComponentLookupError: if `appstructs` contains sheet data
                                  for non existing sheets.
        """
        resource = self.meta.content_class()
        directlyProvides(resource, self.meta.iresource)
        isheets = self.meta.basic_sheets + self.meta.extended_sheets
        alsoProvides(resource, isheets)

        if parent is not None:
            self._add(parent, resource, appstructs)
        else:
            resource.__parent__ = None
            resource.__name__ = ''

        if appstructs:
            for key, struct in appstructs.items():
                isheet = DottedNameResolver().maybe_resolve(key)
                sheet = get_sheet(resource, isheet)
                if sheet.meta.creatable:
                    sheet.set(struct, send_event=False)

        registry = get_current_registry()
        if run_after_creation:
            for call in self.meta.after_creation:
                call(resource, registry, options=kwargs)

        self._notify_new_resource_created_and_added(resource, registry)
        return resource
<commit_msg>gardening: remove not needed fixme<commit_after>"""Resource type configuration and default factory."""
from pyramid.path import DottedNameResolver
from pyramid.threadlocal import get_current_registry
from pyramid.config import Configurator
from substanced.content import add_content_type
from zope.interface import directlyProvides
from zope.interface import alsoProvides

from adhocracy.interfaces import ResourceMetadata
from adhocracy.interfaces import IPool
from adhocracy.events import ResourceCreatedAndAdded
from adhocracy.sheets.name import IName
from adhocracy.utils import get_sheet


def add_resource_type_to_registry(metadata: ResourceMetadata,
                                  config: Configurator):
    """Add the `resource` type specified in metadata to the content registry.

    As generic factory the :class:`ResourceFactory` is used.

    """
    assert hasattr(config.registry, 'content')
    iresource = metadata.iresource
    name = metadata.content_name or iresource.__identifier__
    meta = {'content_name': name,
            'resource_metadata': metadata}
    add_content_type(config, iresource.__identifier__,
                     ResourceFactory(metadata),
                     factory_type=iresource.__identifier__, **meta)


class ResourceFactory:

    """Basic resource factory."""

    name_identifier = IName.__identifier__

    def __init__(self, metadata: ResourceMetadata):
        self.meta = metadata

    def _add(self, parent: IPool, resource: object, appstructs: dict) -> str:
        """Add resource to parent pool.

        :raises substanced.folder.FolderKeyError:
        :raises ValueError:
        """
        name = ''
        if self.name_identifier in appstructs:
            name = appstructs[self.name_identifier]['name']
        if self.meta.use_autonaming:
            prefix = self.meta.autonaming_prefix
            name = parent.next_name(resource, prefix=prefix)
        if name in parent:
            raise KeyError
        if name == '':
            raise KeyError
        parent.add(name, resource, send_events=False)

    def _notify_new_resource_created_and_added(self, resource, registry):
        has_parent = resource.__parent__ is not None
        if has_parent and registry is not None:
            event = ResourceCreatedAndAdded(object=resource,
                                            parent=resource.__parent__,
                                            registry=registry)
            registry.notify(event)

    def __call__(self,
                 parent=None,
                 appstructs={},
                 run_after_creation=True,
                 **kwargs
                 ):
        """Triggered when a ResourceFactory instance is called.

        Args:
            parent (IPool or None): Add the new resource to this pool.
                                    None value is allowed to create non
                                    persistent Resources (without OID/parent).
            appstructs (dict): Key/Values of sheet appstruct data.
                               Key is identifier of a sheet interface.
                               Value is the data to set.
            after_creation (bool): Whether to invoke after_creation hooks,
                                   Default is True.
                                   If parent is None you should set this False
            **kwargs: Arbitary keyword arguments. Will be passed along to
                after_creation hooks as 3rd argument 'options'.

        Returns:
            object (IResource): the newly created resource

        Raises:
            KeyError: if self.metadata.use_autonaming is False and the
                      `resource name` is not given or already used in the
                      `parent` pool.
                      You can set the `resource name` with appstruct data
                      for the name sheet (:mod:`adhocracy.sheets.name`).
            ComponentLookupError: if `appstructs` contains sheet data
                                  for non existing sheets.
        """
        resource = self.meta.content_class()
        directlyProvides(resource, self.meta.iresource)
        isheets = self.meta.basic_sheets + self.meta.extended_sheets
        alsoProvides(resource, isheets)

        if parent is not None:
            self._add(parent, resource, appstructs)
        else:
            resource.__parent__ = None
            resource.__name__ = ''

        if appstructs:
            for key, struct in appstructs.items():
                isheet = DottedNameResolver().maybe_resolve(key)
                sheet = get_sheet(resource, isheet)
                if sheet.meta.creatable:
                    sheet.set(struct, send_event=False)

        registry = get_current_registry()
        if run_after_creation:
            for call in self.meta.after_creation:
                call(resource, registry, options=kwargs)

        self._notify_new_resource_created_and_added(resource, registry)
        return resource

{'fraction_non_alphanumeric': 0.06388059701492538, 'fraction_numerical': 0.0001990049751243781, 'mean_word_length': 1.9286130536130537, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7650751', 'n_tokens_mistral': 2429, 'n_tokens_neox': 2317, 'n_words': 732}