<commit_before>
from ..signals import (
    CONTENT_BLOCK_CREATED, INBOX_MESSAGE_CREATED,
    SUBSCRIPTION_CREATED
)
from ..taxii.converters import blob_to_service_entity


class PersistenceManager(object):
    '''Manager responsible for persisting and retrieving data.

    Manager uses API instance ``api`` for basic data CRUD operations and
    provides additional logic on top.

    :param `opentaxii.persistence.api.OpenTAXIIPersistenceAPI` api:
        instance of persistence API class
    '''

    def __init__(self, api):
        self.api = api

    # Methods only used in the CLI scripts provided with OpenTAXII.

    def create_service(self, entity):
        '''Create a service.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.create_service(entity)

    def attach_collection_to_services(self, collection_id, service_ids):
        '''Attach collection to the services.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.attach_collection_to_services(collection_id, service_ids)

    def create_collection(self, entity):
        '''Create a collection.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.create_collection(entity)

    def create_services_from_object(self, services_config):
        '''Create services from configuration object and persis them.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''

        for blob in services_config:
            self.create_service(blob_to_service_entity(blob))

    # =================================================================

    def get_services(self):
        '''Get configured services.

        Methods loads services entities via persistence API.

        :return: list of service entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.ServiceEntity`
        '''
        return self.api.get_services()

    def get_services_for_collection(self, collection):
        '''Get the services associated with a collection.

        :param `opentaxii.taxii.entities.CollectionEntity` collection:
            collection entity in question

        :return: list of service entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.ServiceEntity`
        '''

        return self.api.get_services(collection_id=collection.id)

    def get_collections(self, service_id):
        '''Get the collections associated with a service.

        :param str service_id: ID of the service in question

        :return: list of collection entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.CollectionEntity`
        '''

        return self.api.get_collections(service_id)

    def get_collection(self, name, service_id):
        '''Get a collection by name and service ID.

        According to TAXII spec collection name is unique per service instance.
        Method retrieves collection entity using collection name ``name`` and service ID
        ``service_id`` as a composite key.

        :param str name: a collection name
        :param str service_id: ID of a service

        :return: collection entity
        :rtype: :py:class:`opentaxii.taxii.entities.CollectionEntity`
        '''
        return self.api.get_collection(name, service_id)


    def create_inbox_message(self, entity):
        '''Create an inbox message.

        Methods emits :py:const:`opentaxii.signals.INBOX_MESSAGE_CREATED` signal.

        :param `opentaxii.taxii.entities.InboxMessageEntity` entity:
            inbox message entity in question
        :return: updated inbox message entity
        :rtype: :py:class:`opentaxii.taxii.entities.InboxMessageEntity`
        '''

        created = self.api.create_inbox_message(entity)

        INBOX_MESSAGE_CREATED.send(self, inbox_message=created)

        return created

    def create_content(self, content, service_id=None, inbox_message=None,
            collections=None):
        '''Create a content block.

        Methods emits :py:const:`opentaxii.signals.CONTENT_BLOCK_CREATED` signal.

        :param `opentaxii.taxii.entities.ContentBlockEntity` entity:
                content block in question
        :param str service_id: ID of an inbox service via which content
                block was created
        :param `opentaxii.taxii.entities.InboxMessageEntity` inbox_message:
                inbox message that delivered the content block
        :param list collections: a list of destination collections as
                :py:class:`opentaxii.taxii.entities.CollectionEntity`
        :return: updated content block entity
        :rtype: :py:class:`opentaxii.taxii.entities.ContentBlockEntity`
        '''

        if inbox_message:
            if not inbox_message.id:
                inbox_message = self.api.create_inbox_message(inbox_message)
            content.inbox_message_id = inbox_message.id

        collections = collections or []
        collection_ids = [c.id for c in collections]
        content = self.api.create_content_block(content,
                collection_ids=collection_ids, service_id=service_id)

        CONTENT_BLOCK_CREATED.send(self, content_block=content,
                collection_ids=collection_ids, service_id=service_id)

        return content

    def get_content_blocks_count(self, collection_id, start_time=None, end_time=None,
            bindings=None):
        '''Get a count of the content blocks associated with a collection.

        :param str collection_id: ID fo a collection in question
        :param datetime start_time: start of a time frame
        :param datetime end_time: end of a time frame
        :param list bindings: list of
            :py:class:`opentaxii.taxii.entities.ContentBindingEntity`
            
        :return: content block count
        :rtype: int
        '''

        return self.api.get_content_blocks_count(
            collection_id = collection_id,
            start_time = start_time,
            end_time = end_time,
            bindings = bindings or [],
        )

    def get_content_blocks(self, collection_id, start_time=None, end_time=None,
            bindings=None, offset=0, limit=10):
        '''Get the content blocks associated with a collection.

        :param str collection_id: ID fo a collection in question
        :param datetime start_time: start of a time frame<commit_msg>no hardcoded default for limit<commit_after>
from ..signals import (
    CONTENT_BLOCK_CREATED, INBOX_MESSAGE_CREATED,
    SUBSCRIPTION_CREATED
)
from ..taxii.converters import blob_to_service_entity


class PersistenceManager(object):
    '''Manager responsible for persisting and retrieving data.

    Manager uses API instance ``api`` for basic data CRUD operations and
    provides additional logic on top.

    :param `opentaxii.persistence.api.OpenTAXIIPersistenceAPI` api:
        instance of persistence API class
    '''

    def __init__(self, api):
        self.api = api

    # Methods only used in the CLI scripts provided with OpenTAXII.

    def create_service(self, entity):
        '''Create a service.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.create_service(entity)

    def attach_collection_to_services(self, collection_id, service_ids):
        '''Attach collection to the services.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.attach_collection_to_services(collection_id, service_ids)

    def create_collection(self, entity):
        '''Create a collection.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''
        return self.api.create_collection(entity)

    def create_services_from_object(self, services_config):
        '''Create services from configuration object and persis them.

        NOTE: Additional method that is only used in the helper scripts
        shipped with OpenTAXII.
        '''

        for blob in services_config:
            self.create_service(blob_to_service_entity(blob))

    # =================================================================

    def get_services(self):
        '''Get configured services.

        Methods loads services entities via persistence API.

        :return: list of service entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.ServiceEntity`
        '''
        return self.api.get_services()

    def get_services_for_collection(self, collection):
        '''Get the services associated with a collection.

        :param `opentaxii.taxii.entities.CollectionEntity` collection:
            collection entity in question

        :return: list of service entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.ServiceEntity`
        '''

        return self.api.get_services(collection_id=collection.id)

    def get_collections(self, service_id):
        '''Get the collections associated with a service.

        :param str service_id: ID of the service in question

        :return: list of collection entities.
        :rtype: list of :py:class:`opentaxii.taxii.entities.CollectionEntity`
        '''

        return self.api.get_collections(service_id)

    def get_collection(self, name, service_id):
        '''Get a collection by name and service ID.

        According to TAXII spec collection name is unique per service instance.
        Method retrieves collection entity using collection name ``name`` and service ID
        ``service_id`` as a composite key.

        :param str name: a collection name
        :param str service_id: ID of a service

        :return: collection entity
        :rtype: :py:class:`opentaxii.taxii.entities.CollectionEntity`
        '''
        return self.api.get_collection(name, service_id)


    def create_inbox_message(self, entity):
        '''Create an inbox message.

        Methods emits :py:const:`opentaxii.signals.INBOX_MESSAGE_CREATED` signal.

        :param `opentaxii.taxii.entities.InboxMessageEntity` entity:
            inbox message entity in question
        :return: updated inbox message entity
        :rtype: :py:class:`opentaxii.taxii.entities.InboxMessageEntity`
        '''

        created = self.api.create_inbox_message(entity)

        INBOX_MESSAGE_CREATED.send(self, inbox_message=created)

        return created

    def create_content(self, content, service_id=None, inbox_message=None,
            collections=None):
        '''Create a content block.

        Methods emits :py:const:`opentaxii.signals.CONTENT_BLOCK_CREATED` signal.

        :param `opentaxii.taxii.entities.ContentBlockEntity` entity:
                content block in question
        :param str service_id: ID of an inbox service via which content
                block was created
        :param `opentaxii.taxii.entities.InboxMessageEntity` inbox_message:
                inbox message that delivered the content block
        :param list collections: a list of destination collections as
                :py:class:`opentaxii.taxii.entities.CollectionEntity`
        :return: updated content block entity
        :rtype: :py:class:`opentaxii.taxii.entities.ContentBlockEntity`
        '''

        if inbox_message:
            if not inbox_message.id:
                inbox_message = self.api.create_inbox_message(inbox_message)
            content.inbox_message_id = inbox_message.id

        collections = collections or []
        collection_ids = [c.id for c in collections]
        content = self.api.create_content_block(content,
                collection_ids=collection_ids, service_id=service_id)

        CONTENT_BLOCK_CREATED.send(self, content_block=content,
                collection_ids=collection_ids, service_id=service_id)

        return content

    def get_content_blocks_count(self, collection_id, start_time=None, end_time=None,
            bindings=None):
        '''Get a count of the content blocks associated with a collection.

        :param str collection_id: ID fo a collection in question
        :param datetime start_time: start of a time frame
        :param datetime end_time: end of a time frame
        :param list bindings: list of
            :py:class:`opentaxii.taxii.entities.ContentBindingEntity`
            
        :return: content block count
        :rtype: int
        '''

        return self.api.get_content_blocks_count(
            collection_id = collection_id,
            start_time = start_time,
            end_time = end_time,
            bindings = bindings or [],
        )

    def get_content_blocks(self, collection_id, start_time=None, end_time=None,
            bindings=None, offset=0, limit=None):
        '''Get the content blocks associated with a collection.

        :param str collection_id: ID fo a collection in question
        :param datetime start_time: start of a time frame
{'fraction_non_alphanumeric': 0.08168222880133606, 'fraction_numerical': 0.0003036514081834055, 'mean_word_length': 2.7141246123484635, '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': '7637548', 'n_tokens_mistral': 3560, 'n_tokens_neox': 3435, 'n_words': 1043}