<commit_before>import cgi
import datetime
from itertools import count

from dateutil.parser import parse as date_parser


import ckan.plugins as p
from ckan.model import MAX_TAG_LENGTH

# Reference some stuff from the toolkit
_ = p.toolkit._
Invalid = p.toolkit.Invalid
get_validator = p.toolkit.get_validator
get_converter = p.toolkit.get_converter


def unique_title_within_organization(key, data, errors, context):
    '''
    Checks if there is another dataset with the same title in the included
    organization.

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is another
        dataset with the same title

    '''
    value = data.get(key)

    org_id = data.get(('owner_org', ))
    if not org_id:
        raise Invalid(
            _('Please provide an organization for the dataset')
        )
    # We need to use title_string rather the title otherwise we cannot query
    # by exact match
    search_dict = {
        'q': 'title_string:"%s"' % value,
        'fq': 'owner_org:{0}'.format(org_id),
    }

    query = p.toolkit.get_action('package_search')({
        'ignore_auth': True}, search_dict)


    if query['count'] > 0:
        if (query['count'] == 1
                and len(query['results'])
                and (query['results'][0]['id'] == data.get(('id', )))
                or query['results'][0]['name'] == data.get(('id', ))):
            # If we are updating the dataset then having the same title is ok!
            pass
        else:
            raise Invalid(
                _('There is a dataset with the same title in this organization')
            )
    return value


def no_pending_dataset_with_same_name(value, context):
    '''
    Checks if there is a pending request for a dataset with the same name

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is a pending
        request with the same dataset name

    '''
    pending_task = p.toolkit.get_action('pending_task_for_dataset')({
        'ignore_auth': True}, {'name': value})

    if pending_task:
        raise Invalid(
            _('There is a pending request for a dataset with the same name')
        )
    return value


def no_pending_dataset_with_same_title_in_same_org(key, data, errors, context):
    '''
    Checks if there is a pending request for a dataset with the same title
    in the same organization as the one you are creating.

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is a pending
        request with the same dataset title in the same organization

    '''
    value = data.get(key)

    org_id = data.get(('owner_org', ))
    if not org_id:
        raise Invalid(
            _('Please provide an organization for the dataset')
        )
    from sqlalchemy import or_

    model = context.get('model')
    task = model.Session.query(model.TaskStatus) \
        .filter(model.TaskStatus.entity_type == 'dataset') \
        .filter(or_(model.TaskStatus.state == 'new',
                model.TaskStatus.state == 'sent')) \
        .filter(model.TaskStatus.value.like('%"owner_org": "{0}"%'.format(org_id))) \
        .filter(model.TaskStatus.value.like('%%\"title\": \"%s\"%%' % value))\
        .order_by(model.TaskStatus.last_updated.desc()) \
        .first()

    if task:
        raise Invalid(
            _('There is a pending request for a dataset with the same ' +
              'title in the same organization')
        )
    return value


def string_max_length(max_length):
    '''
    Checks if a string is longer than a certain length

    :raises: ckan.lib.navl.dictization_functions.Invalid if the string is<commit_msg>[#56] Fix unique title validators<commit_after>import cgi
import json
import datetime
from itertools import count

from dateutil.parser import parse as date_parser


import ckan.plugins as p
from ckan.model import MAX_TAG_LENGTH

# Reference some stuff from the toolkit
_ = p.toolkit._
Invalid = p.toolkit.Invalid
get_validator = p.toolkit.get_validator
get_converter = p.toolkit.get_converter


def unique_title_within_organization(key, data, errors, context):
    '''
    Checks if there is another dataset with the same title in the included
    organization.

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is another
        dataset with the same title

    '''
    value = data.get(key)

    org_id = data.get(('owner_org', ))
    if not org_id:
        raise Invalid(
            _('Please provide an organization for the dataset')
        )
    # We need to use title_string rather the title otherwise we cannot query
    # by exact match
    search_dict = {
        'q': 'title_string:"%s"' % value,
        'fq': 'owner_org:{0}'.format(org_id),
    }

    query = p.toolkit.get_action('package_search')({
        'ignore_auth': True}, search_dict)

    if query['count'] > 0:
        if (query['count'] == 1
                and len(query['results'])
                and (query['results'][0]['id'] == data.get(('id', ))
                     or query['results'][0]['name'] == data.get(('id', )))):
            # If we are updating the dataset then having the same title is ok!
            pass
        else:
            raise Invalid(
                _('There is a dataset with the same title in this organization')
            )
    return value


def no_pending_dataset_with_same_name(value, context):
    '''
    Checks if there is a pending request for a dataset with the same name

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is a pending
        request with the same dataset name

    '''
    pending_task = p.toolkit.get_action('pending_task_for_dataset')({
        'ignore_auth': True}, {'name': value})

    if pending_task:
        raise Invalid(
            _('There is a pending request for a dataset with the same name')
        )
    return value


def no_pending_dataset_with_same_title_in_same_org(key, data, errors, context):
    '''
    Checks if there is a pending request for a dataset with the same title
    in the same organization as the one you are creating.

    :raises: :py:exc:`~ckan.plugins.toolkit.Invalid` if there is a pending
        request with the same dataset title in the same organization

    '''
    value = data.get(key)

    org_id = data.get(('owner_org', ))
    if not org_id:
        raise Invalid(
            _('Please provide an organization for the dataset')
        )
    from sqlalchemy import or_

    model = context.get('model')
    task = model.Session.query(model.TaskStatus) \
        .filter(model.TaskStatus.entity_type == 'dataset') \
        .filter(or_(model.TaskStatus.state == 'new',
                model.TaskStatus.state == 'sent')) \
        .filter(model.TaskStatus.value.like('%"owner_org": "{0}"%'.format(org_id))) \
        .filter(model.TaskStatus.value.like('%%\"title\": \"%s\"%%' % value))\
        .order_by(model.TaskStatus.last_updated.desc()) \
        .first()

    if task:
        # We need this to ensure that validation is not applied to the same
        # dataset when being created by the harvesters
        task_value = json.loads(task.value)
        dataset_dict = task_value.get('data_dict')

        name_check = (data.get(('name', )) ==
                      task.key + '-' + dataset_dict['owner_org'][:4])
        if not name_check:
            raise Invalid(
                _('There is a pending request for a dataset with the same ' +
                  'title in the same organization')
            )
    return value


def string_max_length(max_length):
    '''
    Checks if a string is longer than a certain length

    :raises: ckan.lib.navl.dictization_functions.Invalid if the string is
{'fraction_non_alphanumeric': 0.10903141361256545, 'fraction_numerical': 0.001963350785340314, 'mean_word_length': 2.545707656612529, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 5, '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': '6066190', 'n_tokens_mistral': 2254, 'n_tokens_neox': 2197, 'n_words': 694}