示例#1
0
def create_content(artifact_sha256, filename):
    """
    Creates PythonPackageContent from artifact.

    Args:
        artifact_sha256: validated artifact
        filename: file name
    Returns:
        queryset of the new created content
    """
    artifact = Artifact.objects.get(sha256=artifact_sha256)
    metadata = get_project_metadata_from_artifact(filename, artifact)

    data = parse_project_metadata(vars(metadata))
    data['packagetype'] = metadata.packagetype
    data['version'] = metadata.version
    data['filename'] = filename
    data['sha256'] = artifact.sha256

    @transaction.atomic()
    def create():
        content = PythonPackageContent.objects.create(**data)
        ContentArtifact.objects.create(artifact=artifact,
                                       content=content,
                                       relative_path=filename)
        return content

    new_content = create()
    resource = CreatedResource(content_object=new_content)
    resource.save()

    return PythonPackageContent.objects.filter(pk=new_content.pk)
示例#2
0
    def create(self, request):
        """
        Create a new PythonPackageContent from a request.
        """
        try:
            artifact = self.get_resource(request.data['_artifact'], Artifact)
        except KeyError:
            raise serializers.ValidationError(
                detail={'_artifact': _('This field is required')})

        try:
            filename = request.data['filename']
        except KeyError:
            raise serializers.ValidationError(
                detail={'filename': _('This field is required')})

        # iterate through extensions since splitext does not support things like .tar.gz
        for ext, packagetype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):

                # Copy file to a temp directory under the user provided filename, we do this
                # because pkginfo validates that the filename has a valid extension before
                # reading it
                with tempfile.TemporaryDirectory() as td:
                    temp_path = os.path.join(td, filename)
                    shutil.copy2(artifact.file.path, temp_path)
                    metadata = DIST_TYPES[packagetype](temp_path)
                    metadata.packagetype = packagetype
                    break
        else:
            raise serializers.ValidationError(
                _("Extension on {} is not a valid python extension "
                  "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(
                      filename))

        data = parse_project_metadata(vars(metadata))
        data['classifiers'] = [{
            'name': classifier
        } for classifier in metadata.classifiers]
        data['packagetype'] = metadata.packagetype
        data['version'] = metadata.version
        data['filename'] = filename
        data['_artifact'] = request.data['_artifact']

        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.validated_data.pop('_artifact')
        content = serializer.save()

        if content.pk:
            ContentArtifact.objects.create(artifact=artifact,
                                           content=content,
                                           relative_path=filename)

        headers = self.get_success_headers(request.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)
示例#3
0
    def create(self, request):
        """
        <!-- User-facing documentation, rendered as html-->
        This endpoint is part of the <a href="workflows/upload.html">Upload workflow.</a> Create
        a PythonPackageContent here by specifying an uploaded Artifact. `pulp-python` will inspect
        parse the metadata directly from the file.

        """
        try:
            artifact = self.get_resource(request.data['_artifact'], Artifact)
        except KeyError:
            raise serializers.ValidationError(detail={'_artifact': _('This field is required')})

        try:
            filename = request.data['filename']
        except KeyError:
            raise serializers.ValidationError(detail={'filename': _('This field is required')})

        # iterate through extensions since splitext does not support things like .tar.gz
        for ext, packagetype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):

                # Copy file to a temp directory under the user provided filename, we do this
                # because pkginfo validates that the filename has a valid extension before
                # reading it
                with tempfile.TemporaryDirectory() as td:
                    temp_path = os.path.join(td, filename)
                    shutil.copy2(artifact.file.path, temp_path)
                    metadata = DIST_TYPES[packagetype](temp_path)
                    metadata.packagetype = packagetype
                    break
        else:
            raise serializers.ValidationError(_(
                "Extension on {} is not a valid python extension "
                "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(filename)
            )

        data = parse_project_metadata(vars(metadata))
        data['classifiers'] = [{'name': classifier} for classifier in metadata.classifiers]
        data['packagetype'] = metadata.packagetype
        data['version'] = metadata.version
        data['filename'] = filename
        data['_artifact'] = request.data['_artifact']
        data['_relative_path'] = filename

        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        headers = self.get_success_headers(request.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
示例#4
0
    def deferred_validate(self, data):
        """
        Validate the python package data.

        Args:
            data (dict): Data to be validated

        Returns:
            dict: Data that has been validated

        """
        data = super().deferred_validate(data)

        try:
            filename = data["relative_path"]
        except KeyError:
            raise serializers.ValidationError(
                detail={"relative_path": _('This field is required')})

        artifact = data["artifact"]
        try:
            metadata = get_project_metadata_from_artifact(filename, artifact)
        except ValueError:
            raise serializers.ValidationError(
                _("Extension on {} is not a valid python extension "
                  "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(
                      filename))

        if data.get("sha256") and data["sha256"] != artifact.sha256:
            raise serializers.ValidationError(
                detail={
                    "sha256":
                    _("The uploaded artifact's sha256 checksum does not match the one provided"
                      )
                })
        sha256 = artifact.sha256
        if sha256 and python_models.PythonPackageContent.objects.filter(
                sha256=sha256).exists():
            raise serializers.ValidationError(
                detail={"sha256": _('This field must be unique')})

        _data = parse_project_metadata(vars(metadata))
        _data['packagetype'] = metadata.packagetype
        _data['version'] = metadata.version
        _data['filename'] = filename
        _data['sha256'] = sha256

        data.update(_data)

        return data
示例#5
0
def one_shot_upload(artifact_pk, filename, repository_pk=None):
    """
    One shot upload for pulp_python

    Args:
        artifact_pk: validated artifact
        filename: file name
        repository_pk: optional repository to add Content to
    """
    # iterate through extensions since splitext does not support things like .tar.gz
    for ext, packagetype in DIST_EXTENSIONS.items():
        if filename.endswith(ext):
            # Copy file to a temp directory under the user provided filename, we do this
            # because pkginfo validates that the filename has a valid extension before
            # reading it
            with tempfile.TemporaryDirectory() as td:
                temp_path = os.path.join(td, filename)
                artifact = Artifact.objects.get(pk=artifact_pk)
                shutil.copy2(artifact.file.path, temp_path)
                metadata = DIST_TYPES[packagetype](temp_path)
                metadata.packagetype = packagetype
                break
    else:
        raise serializers.ValidationError(
            _("Extension on {} is not a valid python extension "
              "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(filename))
    data = parse_project_metadata(vars(metadata))
    data['classifiers'] = [{
        'name': classifier
    } for classifier in metadata.classifiers]
    data['packagetype'] = metadata.packagetype
    data['version'] = metadata.version
    data['filename'] = filename
    data['_relative_path'] = filename

    new_content = PythonPackageContent.objects.create(
        filename=filename,
        packagetype=metadata.packagetype,
        name=data['classifiers'],
        version=data['version'])

    queryset = PythonPackageContent.objects.filter(pk=new_content.pk)

    if repository_pk:
        repository = Repository.objects.get(pk=repository_pk)
        with RepositoryVersion.create(repository) as new_version:
            new_version.add_content(queryset)

    resource = CreatedResource(content_object=new_content)
    resource.save()
示例#6
0
def create_content(artifact_sha256, filename):
    """
    Creates PythonPackageContent from artifact.

    Args:
        artifact_sha256: validated artifact
        filename: file name
    Returns:
        queryset of the new created content
    """
    # iterate through extensions since splitext does not support things like .tar.gz
    extensions = list(DIST_EXTENSIONS.keys())
    pkg_type_index = [filename.endswith(ext) for ext in extensions].index(True)
    packagetype = DIST_EXTENSIONS[extensions[pkg_type_index]]
    # Copy file to a temp directory under the user provided filename, we do this
    # because pkginfo validates that the filename has a valid extension before
    # reading it
    artifact = Artifact.objects.get(sha256=artifact_sha256)
    artifact_file = storage.open(artifact.file.name)
    with tempfile.NamedTemporaryFile('wb', suffix=filename) as temp_file:
        shutil.copyfileobj(artifact_file, temp_file)
        temp_file.flush()
        metadata = DIST_TYPES[packagetype](temp_file.name)
        metadata.packagetype = packagetype

    data = parse_project_metadata(vars(metadata))
    data['packagetype'] = metadata.packagetype
    data['version'] = metadata.version
    data['filename'] = filename
    data['sha256'] = artifact.sha256

    @transaction.atomic()
    def create():
        content = PythonPackageContent.objects.create(**data)
        ContentArtifact.objects.create(artifact=artifact,
                                       content=content,
                                       relative_path=filename)
        return content

    new_content = create()
    resource = CreatedResource(content_object=new_content)
    resource.save()

    return PythonPackageContent.objects.filter(pk=new_content.pk)
示例#7
0
    def deferred_validate(self, data):
        """
        Validate the python package data.

        Args:
            data (dict): Data to be validated

        Returns:
            dict: Data that has been validated

        """
        data = super().deferred_validate(data)

        try:
            filename = data["relative_path"]
        except KeyError:
            raise serializers.ValidationError(
                detail={"relative_path": _('This field is required')})

        if python_models.PythonPackageContent.objects.filter(
                filename=filename):
            raise serializers.ValidationError(
                detail={"relative_path": _('This field must be unique')})

        # iterate through extensions since splitext does not support things like .tar.gz
        for ext, packagetype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                # Copy file to a temp directory under the user provided filename, we do this
                # because pkginfo validates that the filename has a valid extension before
                # reading it
                with tempfile.TemporaryDirectory() as td:
                    temp_path = os.path.join(td, filename)
                    artifact = data["artifact"]
                    shutil.copy2(artifact.file.path, temp_path)
                    metadata = DIST_TYPES[packagetype](temp_path)
                    metadata.packagetype = packagetype
                    break
        else:
            raise serializers.ValidationError(
                _("Extension on {} is not a valid python extension "
                  "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(
                      filename))
        _data = parse_project_metadata(vars(metadata))
        _data['packagetype'] = metadata.packagetype
        _data['version'] = metadata.version
        _data['filename'] = filename

        data.update(_data)

        new_content = python_models.PythonPackageContent.objects.filter(
            filename=data['filename'],
            packagetype=data['packagetype'],
            name=data['name'],
            version=data['version'])

        if new_content.exists():
            raise serializers.ValidationError(
                _("There is already a python package with relative path '{path}'."
                  ).format(path=data["relative_path"]))

        return data
示例#8
0
    def deferred_validate(self, data):
        """
        Validate the python package data.

        Args:
            data (dict): Data to be validated

        Returns:
            dict: Data that has been validated

        """
        data = super().deferred_validate(data)

        try:
            filename = data["relative_path"]
        except KeyError:
            raise serializers.ValidationError(
                detail={"relative_path": _('This field is required')})

        # iterate through extensions since splitext does not support things like .tar.gz
        for ext, packagetype in DIST_EXTENSIONS.items():
            if filename.endswith(ext):
                # Copy file to a temp directory under the user provided filename, we do this
                # because pkginfo validates that the filename has a valid extension before
                # reading it
                with tempfile.NamedTemporaryFile('wb',
                                                 suffix=filename) as temp_file:
                    artifact = data["artifact"]
                    artifact_file = storage.open(artifact.file.name)
                    shutil.copyfileobj(artifact_file, temp_file)
                    temp_file.flush()
                    metadata = DIST_TYPES[packagetype](temp_file.name)
                    metadata.packagetype = packagetype
                    break
        else:
            raise serializers.ValidationError(
                _("Extension on {} is not a valid python extension "
                  "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format(
                      filename))
        if data.get("sha256") and data["sha256"] != artifact.sha256:
            raise serializers.ValidationError(
                detail={
                    "sha256":
                    _("The uploaded artifact's sha256 checksum does not match the one provided"
                      )
                })
        sha256 = artifact.sha256
        if sha256 and python_models.PythonPackageContent.objects.filter(
                sha256=sha256).exists():
            raise serializers.ValidationError(
                detail={"sha256": _('This field must be unique')})

        _data = parse_project_metadata(vars(metadata))
        _data['packagetype'] = metadata.packagetype
        _data['version'] = metadata.version
        _data['filename'] = filename
        _data['sha256'] = sha256

        data.update(_data)

        return data