Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pulp_python/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ class PythonPackageContentSerializer(core_serializers.SingleArtifactContentUploa
help_text=_('The packages version number.'),
read_only=True,
)
sha256 = serializers.CharField(
help_text=_('The SHA256 digest of this package.'),
read_only=True,
)
metadata_version = serializers.CharField(
help_text=_('Version of the file format'),
read_only=True,
Expand Down Expand Up @@ -232,7 +236,7 @@ def deferred_validate(self, data):

class Meta:
fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
'filename', 'packagetype', 'name', 'version', 'metadata_version', 'summary',
'filename', 'packagetype', 'name', 'version', 'sha256', 'metadata_version', 'summary',
'description', 'keywords', 'home_page', 'download_url', 'author', 'author_email',
'maintainer', 'maintainer_email', 'license', 'requires_python', 'project_url',
'platform', 'supported_platform', 'requires_dist', 'provides_dist',
Expand All @@ -248,7 +252,7 @@ class MinimalPythonPackageContentSerializer(PythonPackageContentSerializer):

class Meta:
fields = core_serializers.SingleArtifactContentUploadSerializer.Meta.fields + (
'filename', 'packagetype', 'name', 'version',
'filename', 'packagetype', 'name', 'version', 'sha256',
)
model = python_models.PythonPackageContent

Expand Down
57 changes: 9 additions & 48 deletions pulp_python/app/tasks/publish.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,47 +3,17 @@
import os
import tempfile

from packaging.utils import canonicalize_name
from django.core.files import File
from django.template import Context, Template
from packaging.utils import canonicalize_name

from pulpcore.plugin import models

from pulp_python.app import models as python_models
from pulp_python.app.utils import write_simple_index, write_simple_detail


log = logging.getLogger(__name__)

simple_index_template = """<!DOCTYPE html>
<html>
<head>
<title>Simple Index</title>
<meta name="api-version" value="2" />
</head>
<body>
{% for name, canonical_name in projects %}
<a href="{{ canonical_name }}/">{{ name }}</a><br/>
{% endfor %}
</body>
</html>
"""


simple_detail_template = """<!DOCTYPE html>
<html>
<head>
<title>Links for {{ project_name }}</title>
<meta name="api-version" value="2" />
</head>
<body>
<h1>Links for {{ project_name }}</h1>
{% for name, path, sha256 in project_packages %}
<a href="{{ path }}#sha256={{ sha256 }}" rel="internal">{{ name }}</a><br/>
{% endfor %}
</body>
</html>
"""


def publish(repository_version_pk):
"""
Expand Down Expand Up @@ -92,14 +62,10 @@ def write_simple_api(publication):
.distinct()
)

index_names = [(name, canonicalize_name(name)) for name in project_names]

# write the root index, which lists all of the projects for which there is a package available
index_path = '{simple_dir}index.html'.format(simple_dir=simple_dir)
with open(index_path, 'w') as index:
context = Context({'projects': index_names})
template = Template(simple_index_template)
index.write(template.render(context))
index.write(write_simple_index(project_names))

index_metadata = models.PublishedMetadata.create_from_file(
relative_path=index_path,
Expand All @@ -108,7 +74,7 @@ def write_simple_api(publication):
)
index_metadata.save()

if len(index_names) == 0:
if len(project_names) == 0:
return

packages = python_models.PythonPackageContent.objects.filter(
Expand All @@ -117,26 +83,26 @@ def write_simple_api(publication):
releases = packages.order_by("name").values("name", "filename", "sha256")

ind = 0
current_name = index_names[ind][0]
current_name = project_names[ind]
package_releases = []
for release in releases.iterator():
if release['name'] != current_name:
write_project_page(
name=index_names[ind][1],
name=canonicalize_name(current_name),
simple_dir=simple_dir,
package_releases=package_releases,
publication=publication
)
package_releases = []
ind += 1
current_name = index_names[ind][0]
current_name = project_names[ind]
relative_path = release['filename']
path = f"../../{relative_path}"
checksum = release['sha256']
package_releases.append((relative_path, path, checksum))
# Write the final project's page
write_project_page(
name=index_names[ind][1],
name=canonicalize_name(current_name),
simple_dir=simple_dir,
package_releases=package_releases,
publication=publication
Expand All @@ -150,12 +116,7 @@ def write_project_page(name, simple_dir, package_releases, publication):
metadata_relative_path = f'{project_dir}index.html'

with open(metadata_relative_path, 'w') as simple_metadata:
context = Context({
'project_name': name,
'project_packages': package_releases
})
template = Template(simple_detail_template)
simple_metadata.write(template.render(context))
simple_metadata.write(write_simple_detail(name, package_releases))

project_metadata = models.PublishedMetadata.create_from_file(
relative_path=metadata_relative_path,
Expand Down
45 changes: 45 additions & 0 deletions pulp_python/app/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,43 @@
import json
from collections import defaultdict
from django.conf import settings
from jinja2 import Template
from packaging.utils import canonicalize_name
from packaging.version import parse

PYPI_LAST_SERIAL = "X-PYPI-LAST-SERIAL"
"""TODO This serial constant is temporary until Python repositories implements serials"""
PYPI_SERIAL_CONSTANT = 1000000000

simple_index_template = """<!DOCTYPE html>
<html>
<head>
<title>Simple Index</title>
<meta name="api-version" value="2" />
</head>
<body>
{% for name, canonical_name in projects %}
<a href="{{ canonical_name }}/">{{ name }}</a><br/>
{% endfor %}
</body>
</html>
"""

simple_detail_template = """<!DOCTYPE html>
<html>
<head>
<title>Links for {{ project_name }}</title>
<meta name="api-version" value="2" />
</head>
<body>
<h1>Links for {{ project_name }}</h1>
{% for name, path, sha256 in project_packages %}
<a href="{{ path }}#sha256={{ sha256 }}" rel="internal">{{ name }}</a><br/>
{% endfor %}
</body>
</html>
"""


def parse_project_metadata(project):
"""
Expand Down Expand Up @@ -198,3 +229,17 @@ def find_artifact():
"yanked": False,
"yanked_reason": None
}


def write_simple_index(project_names, streamed=False):
"""Writes the simple index."""
simple = Template(simple_index_template)
context = {"projects": ((x, canonicalize_name(x)) for x in project_names)}
return simple.stream(**context) if streamed else simple.render(**context)


def write_simple_detail(project_name, project_packages, streamed=False):
"""Writes the simple detail page of a package."""
detail = Template(simple_detail_template)
context = {"project_name": project_name, "project_packages": project_packages}
return detail.stream(**context) if streamed else detail.render(**context)