Example #1
0
def ensure_release_exists(context, data_dict):
    """
    Ensure a release exists for the given `productId`.

    :param productId: The parent product ID.
    :type productId: str
    """
    product_id = _get_or_bust(data_dict, 'productId')
    stcndm_helpers.ensure_release_exists(product_id, context=context)
Example #2
0
def ensure_release_exists(context, data_dict):
    # noinspection PyUnresolvedReferences
    """
    Ensure a release exists for the given `productId`.

    :param productId: The parent product ID.
    :type productId: str
    """
    product_id = _get_or_bust(data_dict, 'productId')
    stcndm_helpers.ensure_release_exists(product_id, context=context)
Example #3
0
    def after_create(self, context, data):
        if 'model' in context:
            # We need to force a commit to get the metadata_modified
            # and metadata_created columns. It is *not* enough for us to
            # simply set these ourselves. This is caused by after_create
            # being called long before creation is actually complete.
            context['model'].repo.commit()

        try:
            helpers.ensure_release_exists(data, context=context)
        except helpers.NotValidProduct:
            pass
Example #4
0
def register_cube(context, data_dict):
    """
    Register a new cube.  Automatically populate
    subjectcode fields based on provided parameters.

    :param subjectCode: two-digit subject_code code (i.e. 13)
    :type subjectCode: str
    :param productTitleEnglish: english title
    :type productTitleEnglish: unicode
    :param productTitleFrench: french title
    :type productTitleFrench: unicode

    :return: new package
    :rtype: dict

    :raises: ValidationError
    """
    subject_code = _get_or_bust(data_dict, 'subjectCode')
    title_en = _get_or_bust(data_dict, 'productTitleEnglish')
    title_fr = _get_or_bust(data_dict, 'productTitleFrench')

    if not len(subject_code) == 2:
        raise ValidationError('subjectCode not valid')

    lc = ckanapi.LocalCKAN(context=context)

    product_type_dict = lc.action.GetProductType(
        productType=CUBE_PRODUCT_TYPE
    )

    product_id = lc.action.GetNextCubeId(**data_dict)

    lc.action.package_create(
        # Old method simply used the product_id, whereas the modern edit
        # form validator uses cube-{product_id}, so lets go with that.
        owner_org='statcan',
        type=u'cube',
        product_id_new=product_id,
        product_type_code=product_type_dict['product_type_code'],
        subject_codes=[subject_code],
        title={
            'en': title_en,
            'fr': title_fr,
        },
        # '02' is "Draft" status, according to the ndm_publish_status
        # preset.
        last_publish_status_code='02'
    )

    stcndm_helpers.ensure_release_exists(str(product_id))

    # Return our newly created package.
    return lc.action.GetCube(cubeId=product_id)
Example #5
0
    def after_create(self, context, data):
        if 'model' in context:
            # We need to force a commit to get the metadata_modified
            # and metadata_created columns. It is *not* enough for us to
            # simply set these ourselves. This is caused by after_create
            # being called long before creation is actually complete.
            context['model'].repo.commit()

        if context.get('__cloning'):
            # We don't want to call this while we're cloning, or we'll
            # end up with duplicate release records.
            return

        product_id_new = data.get('product_id_new')
        if data['type'] == 'format':
            product_id_new = data.get('format_id')

        if not product_id_new:
            return

        helpers.ensure_release_exists(product_id_new, context=context)
Example #6
0
    def after_create(self, context, data):
        if 'model' in context:
            # We need to force a commit to get the metadata_modified
            # and metadata_created columns. It is *not* enough for us to
            # simply set these ourselves. This is caused by after_create
            # being called long before creation is actually complete.
            context['model'].repo.commit()

        if context.get('__cloning'):
            # We don't want to call this while we're cloning, or we'll
            # end up with duplicate release records.
            return

        product_id_new = data.get('product_id_new')
        if data['type'] == 'format':
            product_id_new = data.get('format_id')

        if not product_id_new:
            return

        helpers.ensure_release_exists(product_id_new, context=context)
Example #7
0
def tv_register_product(context, data_dict):
    """
    Register a new product based on a given `parentProductId` (the 8-digit ID
    of a cube) and the desired `productTypeCode`. The new product's fields will
    be populated based on the cube record.

    .. note::

        If the cube is missing English and French titles, the cube will be
        updated.

    .. note::

        As the schemas for tables, indicators, charts, and maps do not
        yet exist, this method is not thoroughly tested.

    :param parentProductId: 8-digit cube id
    :type parentProductId: str
    :param productType: 2-digit product type code
    :type productType: str
    :param productTitle: EN/FR title dictionary
    :type productTitle: dict
    :return: newly-registered product id
    :rtype: dict
    """
    # These are the only product types that can be registered using
    # this method as these are the only "data products".
    # TODO: Can we pull this from somewhere? Presets.yaml does not
    #       necessarily have the exact schema name in ndm_product_type.
    VALID_DATA_TYPES = {
        u'11': 'view',
        u'12': 'indicator',
        u'13': 'chart',
        u'14': 'map'
    }
    CUBE_PRODUCT_TYPE = u'10'
    VIEW_PRODUCT_TYPE = u'11'

    cube_id = _get_or_bust(data_dict, 'parentProductId')
    title = _get_or_bust(data_dict, 'productTitle')
    product_type = _get_or_bust(data_dict, 'productType').zfill(2)

    if product_type == CUBE_PRODUCT_TYPE:
        raise _ValidationError(
            'Please use RegisterCube to register a cube'
        )
    elif product_type not in VALID_DATA_TYPES:
        raise _ValidationError(
            'Invalid data productType, only data products may be registered '
            'with this service'
        )

    lc = ckanapi.LocalCKAN(context=context)
    cube_dict = lc.action.GetCube(cubeId=cube_id)

    product_type_schema = lc.action.GetDatasetSchema(
        name=VALID_DATA_TYPES[product_type]
    )

    # Copy fields that overlap between the cubes and the destination
    # type.
    copied_fields = {}
    for field in product_type_schema['dataset_fields']:
        field_name = field['field_name']
        if field_name in cube_dict:
            copied_fields[field_name] = cube_dict[field_name]

    # FIXME: This is not atomic. If this API method is called quickly
    #        in parallel, this product ID could no longer be free.
    product_id = lc.action.GetNextProductId(
        parentProductId=cube_id,
        productType=product_type
    )
    # The following assumes there can be no more than 99 views
    if product_type == VIEW_PRODUCT_TYPE and product_id.endswith('01'):
        params = {
            "cubeId": cube_id,
            "defaultView": product_id,
        }
        result = views.update_default_view(context, params)

    # Overwrite/add some fields that we don't want to inherit
    # from the cube.
    copied_fields.update({
        'type': VALID_DATA_TYPES[product_type],
        'name': product_id,
        'owner_org': 'statcan',
        'product_id_new': product_id,
        'parent_product': cube_id,
        'title': title,
        'product_type_code': product_type
    })

    lc.action.package_create(**copied_fields)
    try:
        stcndm_helpers.ensure_release_exists(str(product_id))
    except ValueError:
        # We don't create releases for this type of product
        pass

    return {'product_id_new': product_id}