<commit_before>##
# Copyright (c) 2012 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


"""This module defines necessary abstractions to simplify work with resources,
such as defining them, managing, publishing etc.
"""


import os
import shutil
import collections

from semantix.exceptions import SemantixError
from semantix.utils import config
from semantix.utils.datastructures import OrderedSet
from semantix.utils.debug import timeit


class ResourceError(SemantixError):
    """Any error occurred during resource creation or manipulation"""


class ResourcePublisherError(SemantixError):
    """An error occurred during resource publishing"""


class Resource:
    """Resource is an abstract concept of a piece of information.  It may be
    some code, some image of video file etc."""

    def __init__(self):
        self.__sx_resource_deps__ = collections.OrderedDict()
        self.__sx_resource_parent__ = None

    def __sx_add_required_resource__(self, dependency, weak=False):
        """Make ``resource`` dependent on ``dependency``.  ``weak`` means that the
        ``dependency`` must be loaded with ``resource`` but the loading order is
        not important.

        :param Resource resource: Resource to add dependency to.
        :param Resource dependency: A resource required for ``resource`` to work.
        :param bool weak:
        """

        if not isinstance(dependency, Resource):
            raise ResourceError('an instance of Resource expected, got {!r}'.format(dependency))

        try:
            cur = self.__sx_resource_deps__[dependency]
        except KeyError:
            self.__sx_resource_deps__[dependency] = weak
        else:
            if cur and not weak:
                self.__sx_resource_deps__[dependency] = False

    @classmethod
    def _list_resources(cls, resource):
        """Builds the full list of resources that current resource depends on.
        The list includes the resource itself."""

        def _collect_deps(resource, collected, visited, to_import):
            visited.add(resource)

            parent = resource.__sx_resource_parent__
            if parent is not None and parent not in visited:
                _collect_deps(parent, collected, visited, to_import)

            for mod, weak in resource.__sx_resource_deps__.items():
                if weak:
                    to_import.add(mod)
                else:
                    if mod not in visited:
                        _collect_deps(mod, collected, visited, to_import)

            collected.add(resource)

        visited = set()
        collected = OrderedSet()

        to_import = OrderedSet((resource,))
        while to_import:
            mod = to_import.pop()
            _collect_deps(mod, collected, visited, to_import)
            to_import -= collected

        return tuple(collected)


class AbstractFileResource(Resource):<commit_msg>rendering.media: Expose all images as VirtualFile resources<commit_after>##
# Copyright (c) 2012 Sprymix Inc.
# All rights reserved.
#
# See LICENSE for details.
##


"""This module defines necessary abstractions to simplify work with resources,
such as defining them, managing, publishing etc.
"""


import os
import shutil
import collections

from semantix.exceptions import SemantixError
from semantix.utils import config
from semantix.utils.datastructures import OrderedSet
from semantix.utils.debug import timeit


class ResourceError(SemantixError):
    """Any error occurred during resource creation or manipulation"""


class ResourcePublisherError(SemantixError):
    """An error occurred during resource publishing"""


class Resource:
    """Resource is an abstract concept of a piece of information.  It may be
    some code, some image of video file etc."""

    def __init__(self):
        self.__sx_resource_deps__ = collections.OrderedDict()
        self.__sx_resource_parent__ = None

    def __sx_add_required_resource__(self, dependency, weak=False):
        """Make ``resource`` dependent on ``dependency``.  ``weak`` means that the
        ``dependency`` must be loaded with ``resource`` but the loading order is
        not important.

        :param Resource resource: Resource to add dependency to.
        :param Resource dependency: A resource required for ``resource`` to work.
        :param bool weak:
        """

        if not isinstance(dependency, Resource):
            raise ResourceError('an instance of Resource expected, got {!r}'.format(dependency))

        try:
            cur = self.__sx_resource_deps__[dependency]
        except KeyError:
            self.__sx_resource_deps__[dependency] = weak
        else:
            if cur and not weak:
                self.__sx_resource_deps__[dependency] = False

    @classmethod
    def _list_resources(cls, resource):
        """Builds the full list of resources that current resource depends on.
        The list includes the resource itself."""

        def _collect_deps(resource, collected, visited, to_import):
            visited.add(resource)

            parent = resource.__sx_resource_parent__
            if parent is not None and parent not in visited:
                _collect_deps(parent, collected, visited, to_import)

            for mod, weak in resource.__sx_resource_deps__.items():
                if weak:
                    to_import.add(mod)
                else:
                    if mod not in visited:
                        _collect_deps(mod, collected, visited, to_import)

            collected.add(resource)

        visited = set()
        collected = OrderedSet()

        to_import = OrderedSet((resource,))
        while to_import:
            mod = to_import.pop()
            _collect_deps(mod, collected, visited, to_import)
            to_import -= collected

        return tuple(collected)


class ResourceContainer(Resource):
    pass


class AbstractFileResource(Resource):
{'fraction_non_alphanumeric': 0.07706576728499157, 'fraction_numerical': 0.0013490725126475548, 'mean_word_length': 2.645359557467732, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1996515', 'n_tokens_mistral': 1563, 'n_tokens_neox': 1469, 'n_words': 518}