示例#1
0
    def sort_fields(self, value):
        """Sorted fields are stored in internal presentation."""

        parsed = OrderedDict()
        fields = Parser.format_list(value, sort_=False)
        for field in fields:
            match = re.match(
                r'''
            (?P<direction>-?)   # Catch sort direction sign (+/-).
            (?P<field>\S+)      # Catch fields.
            ''', field, re.IGNORECASE | re.VERBOSE)
            if match.group('field') and match.group(
                    'field') in self.ATTRIBUTES:
                parsed[match.group('field')] = 'DESC' if match.group(
                    'direction') == '-' else 'ASC'
            else:
                Cause.push(
                    Cause.HTTP_BAD_REQUEST,
                    'sort option validation failed for non existent field={}'.
                    format(field))
        self._logger.debug(
            '{}: content attribute sort order from user: {}'.format(
                self._derived, fields))
        self._logger.debug(
            '{}: content attribute internal sort structure: {}'.format(
                self._derived, parsed))
        self._sort_fields = parsed  # pylint: disable=attribute-defined-outside-init
示例#2
0
    def scat(self, value):
        """Store content categories.

        The ``scat`` option defines the content category or categories for
        the operation. If operation is ``create``, there must be only one
        category. If the operation is ``search`` or the operation requires
        searching content, there can be multiple values.

        The keywords are stored in tuple with one keywords per element.

        If any of the given categories is incorrect, an error is set. This
        is a simple error handling that fails the operation instead of trying
        to recover it. An unknown value is set to the ``scat`` option in case
        of a failure because it minimizes the search results in the error
        scenario. If all categories would be searched with errors, it could
        lead to a large search results sets in case of failures.
        """

        scat = Parser.format_search_keywords(value)
        if not scat:
            scat = (Const.SNIPPET, )
        if Const.ALL_CATEGORIES in scat:
            scat = Const.CATEGORIES

        if not set(scat).issubset(Const.CATEGORIES):
            Cause.push(Cause.HTTP_BAD_REQUEST, 'content categories: {} :are not a subset of: {}'.format(self._format_scat(scat), Const.CATEGORIES))  # noqa pylint: disable=line-too-long
            scat = (Const.UNKNOWN_CATEGORY, )

        if self.operation == self.CREATE and (Const.UNKNOWN_CATEGORY in scat
                                              or len(scat) != 1):
            Cause.push(Cause.HTTP_BAD_REQUEST, 'content category must be unique when content is created: {}'.format(self._format_scat(scat)))  # noqa pylint: disable=line-too-long

        self._scat = scat  # pylint: disable=attribute-defined-outside-init
示例#3
0
    def sgrp(self, value):
        """Store 'search groups' keywords.

        The keywords are stored in tuple with one keywords per element.
        """

        self._sgrp = Parser.format_search_keywords(value)  # pylint: disable=attribute-defined-outside-init
示例#4
0
    def filename(self, value):
        """Convert content filename to utf-8 encoded unicode string."""

        if value is None:
            self._reset_fields['filename'] = 'filename'

        self._filename = Parser.format_string(value)  # pylint: disable=attribute-defined-outside-init
示例#5
0
    def versions(self, value):
        """Convert content versions to tuple of utf-8 encoded unicode strings."""

        if value is None:
            self._reset_fields['versions'] = 'versions'

        self._versions = Parser.format_versions(value)  # pylint: disable=attribute-defined-outside-init
示例#6
0
    def languages(self, value):
        """Convert content languages to tuple of utf-8 encoded unicode strings."""

        if value is None:
            self._reset_fields['languages'] = 'languages'

        self._languages = Parser.format_list(value)  # pylint: disable=attribute-defined-outside-init
示例#7
0
    def brief(self, value):
        """Convert content brief to utf-8 encoded unicode string."""

        if value is None:
            self._reset_fields['brief'] = 'brief'

        self._brief = Parser.format_string(value)  # pylint: disable=attribute-defined-outside-init
示例#8
0
    def description(self, value):
        """Convert content description to utf-8 encoded unicode string."""

        if value is None:
            self._reset_fields['description'] = 'description'

        self._description = Parser.format_string(value)  # pylint: disable=attribute-defined-outside-init
示例#9
0
    def load_text(self, timestamp, text):
        """Load content from Markdown file.

        Args:
           text (str): Text formatted string.
        """

        Parser(Const.CONTENT_FORMAT_TEXT, timestamp, text, self).read()
示例#10
0
    def load_mkdn(self, timestamp, mkdn):
        """Load content from Markdown file.

        Args:
           mkdn (str): Markdown formatted string.
        """

        Parser(Const.CONTENT_FORMAT_MKDN, timestamp, mkdn, self).read()
示例#11
0
    def data(self, value):
        """Resource data is stored as a tuple with one line per element.

        The value must be formatted only if it contains a value. If an empty
        string or a tuple would be passed to format_data, the result would be
        tuple that contains one empty string. The reason is that empty data is
        considered valid byte the formatter.
        """

        if not value:
            value = None

        self._data = Parser.format_data(self.category, value)
示例#12
0
    def category(self, value):
        """Set content or field category.

        The content category is important when content is created. In case of
        the ``create`` operation, there must be only one category.
        """

        value = Parser.format_list(value)
        if len(value) == 1 and set(value).issubset(Const.CATEGORIES) or set(value).issubset(Const.FIELD_CATEGORIES):
            value = value[0]
        else:
            value = Const.UNKNOWN_CATEGORY

        self._category = value  # pylint: disable=attribute-defined-outside-init
示例#13
0
    def read(cls, timestamp, template_format, template, collection):
        """Read content from editor.

        Args:
            timestamp (str): IS8601 timestamp to be used with created collection.
            template_format (str): Template format.
            template (str): Default template for editor.
            collection (Collection()): Collection to store parsed content.
        """

        text = cls._call_editor(template)
        Parser(template_format, timestamp, text, collection).read()
        if not collection:
            Cause.push(Cause.HTTP_BAD_REQUEST, 'edited: {} :content could not be read - please keep template tags in place'.format(template_format))  # noqa pylint: disable=line-too-long
示例#14
0
    def data(self, value):
        """Convert content data to tuple of utf-8 encoded unicode strings.

        The tool must be able to idenfity if the value was given at all. This
        case is idenfigied with value None. With empty value from user, there
        will be a single element in tuple which is empty string. By doing this,
        there is no need to check value None each time when accessed.
        """

        if value is not None:
            data = Parser.format_data(self.category, value)
        else:
            data = ()

        self._data = data  # pylint: disable=attribute-defined-outside-init
示例#15
0
    def identity(self, value):
        """Convert content identity to utf-8 encoded unicode string.

        The identity attribute is used when the content identity type is not
        known. The identity can be either a message digest or UUID.

        There is no failure proof way to tell if the identity string is a
        Digest or UUID. By creating a third identity field for unidentidied
        identity type, it quarantees that the digest and UUID attributes
        always have correctly matching identity against the type.
        """

        if value is None:
            self._identity = None  # pylint: disable=attribute-defined-outside-init
        else:
            self._identity = Parser.format_string(value)  # pylint: disable=attribute-defined-outside-init
示例#16
0
    def select_distinct(self, column, scat, sall, stag, sgrp):
        """Select unique values from the given column.

        Because the database stores list attributes as a string where values
        are separated with delimiters, a conversion is needed. This method
        returns a dictionaty where each key is an unique value in requested
        column. The values in the returned dictionary are the counts for
        each distinct column value.

        Args:
            column (str): column name.
            scat (tuple): Search category keyword list.
            sall (tuple): Search all keyword list.
            stag (tuple): Search tag keyword list.
            sgrp (tuple): Search group keyword list.

        Returns:
            dict: Dictionary of unique values with counts.
        """

        uniques = {}
        if column not in self._columns:
            self._logger.security('unidentified column name cannot be accepted: %s', column)

            return uniques

        if self._connection:
            self._logger.debug('select distinct values from columns: %s', column)
            query, qargs = self._get_query(column, scat, sall, stag, sgrp, None, None, None, None, Database.QUERY_TYPE_FIELD)
            try:
                with closing(self._connection.cursor()) as cursor:
                    cursor.execute(query, qargs)
                    values = cursor.fetchall()
            except (sqlite3.Error, psycopg2.Error) as error:
                Cause.push(Cause.HTTP_500, 'selecting all from database failed with exception {}'.format(error))
        else:
            Cause.push(Cause.HTTP_500, 'internal error prevented selecting all content from database')

        for value in values:
            for tag in Parser.format_list(value[0]):
                if tag in uniques:
                    uniques[tag] = uniques[tag] + value[1]
                else:
                    uniques[tag] = value[1]

        return uniques
示例#17
0
    def remove_fields(self, value):
        """Store 'removed fields'.

        The removed fields are presented as tuple and they are converted from
        requested 'fields' parameter."""

        remove_fields = ()
        requested_fields = Parser.format_list(value)
        valid = True
        for field in requested_fields:
            if field not in self.ATTRIBUTES:
                valid = False
                Cause.push(Cause.HTTP_BAD_REQUEST, 'resource field does not exist: {}'.format(field))

        if valid:
            remove_fields = tuple(set(self.ATTRIBUTES) - set(requested_fields))  # pylint: disable=attribute-defined-outside-init

        self._logger.debug('{}: content attributes that are removed: {}'.format(self._derived, remove_fields))
        self._remove_fields = remove_fields  # pylint: disable=attribute-defined-outside-init
示例#18
0
    def load_dict(self, timestamp, dictionary):
        """Convert dictionary to collection."""

        Parser(Const.CONTENT_FORMAT_DICT, timestamp, dictionary, self).read()
示例#19
0
    def languages(self, value):
        """Resource languages."""

        self._languages = Parser.format_list(value)
示例#20
0
    def versions(self, value):
        """Resource versions."""

        self._versions = Parser.format_list(value)
示例#21
0
    def filename(self, value):
        """Resource filename."""

        self._filename = Parser.format_string(value)
示例#22
0
    def links(self, value):
        """Resource links."""

        self._links = Parser.format_links(value)
示例#23
0
    def source(self, value):
        """Resource source."""

        self._source = Parser.format_string(value)
示例#24
0
    def tags(self, value):
        """Resource tags."""

        self._tags = Parser.format_list(value)
示例#25
0
    def groups(self, value):
        """Resource groups."""

        self._groups = Parser.format_list(value)
示例#26
0
    def description(self, value):
        """Resource description."""

        self._description = Parser.format_string(value)
示例#27
0
    def brief(self, value):
        """Resource brief."""

        self._brief = Parser.format_string(value)
示例#28
0
    def operation_file(self, value):
        """Convert operation filename to utf-8 encoded unicode string."""

        self._operation_file = Parser.format_string(value)  # pylint: disable=attribute-defined-outside-init