-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathpublish.py
More file actions
127 lines (101 loc) · 4.23 KB
/
publish.py
File metadata and controls
127 lines (101 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
from gettext import gettext as _
import logging
import os
from django.core.files import File
from packaging.utils import canonicalize_name
from pulpcore.plugin import models
from pulpcore.plugin.util import get_domain
from pulp_python.app import models as python_models
from pulp_python.app.serializers import PythonPublicationSerializer
from pulp_python.app.utils import write_simple_index, write_simple_detail
log = logging.getLogger(__name__)
def publish(repository_version_pk):
"""
Create a Publication based on a RepositoryVersion.
Args:
repository_version_pk (str): Create a Publication from this RepositoryVersion.
"""
repository_version = models.RepositoryVersion.objects.get(pk=repository_version_pk)
log.info(
_("Publishing: repository={repo}, version={version}").format(
repo=repository_version.repository.name,
version=repository_version.number,
)
)
with python_models.PythonPublication.create(repository_version, pass_through=True) as pub:
write_simple_api(pub)
log.info(_("Publication: {pk} created").format(pk=pub.pk))
pub = PythonPublicationSerializer(instance=pub, context={"request": None}).data
return pub
def write_simple_api(publication):
"""
Write metadata for the simple API.
Writes metadata mimicking the simple api of PyPI for all python packages
in the repository version.
https://wiki.python.org/moin/PyPISimple
Args:
publication (pulpcore.plugin.models.Publication): A publication to generate metadata for
"""
domain = get_domain()
simple_dir = "simple/"
os.mkdir(simple_dir)
project_names = (
python_models.PythonPackageContent.objects.filter(
pk__in=publication.repository_version.content, _pulp_domain=domain
)
.order_by("name__normalize")
.values_list("name", flat=True)
.distinct("name__normalize")
)
# 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:
index.write(write_simple_index(project_names))
index_metadata = models.PublishedMetadata.create_from_file(
relative_path=index_path, publication=publication, file=File(open(index_path, "rb"))
)
index_metadata.save()
if len(project_names) == 0:
return
packages = python_models.PythonPackageContent.objects.filter(
pk__in=publication.repository_version.content, _pulp_domain=domain
)
releases = packages.order_by("name__normalize").values("name", "filename", "sha256")
ind = 0
current_name = canonicalize_name(project_names[ind])
package_releases = []
for release in releases.iterator():
if canonicalize_name(release["name"]) != current_name:
write_project_page(
name=current_name,
simple_dir=simple_dir,
package_releases=package_releases,
publication=publication,
)
package_releases = []
ind += 1
current_name = canonicalize_name(project_names[ind])
relative_path = release["filename"]
path = f"../../{relative_path}"
checksum = release["sha256"]
package_releases.append({"filename": relative_path, "url": path, "sha256": checksum})
# Write the final project's page
write_project_page(
name=canonicalize_name(current_name),
simple_dir=simple_dir,
package_releases=package_releases,
publication=publication,
)
def write_project_page(name, simple_dir, package_releases, publication):
"""Writes a project's simple page."""
project_dir = f"{simple_dir}{name}/"
os.mkdir(project_dir)
metadata_relative_path = f"{project_dir}index.html"
with open(metadata_relative_path, "w") as simple_metadata:
simple_metadata.write(write_simple_detail(name, package_releases))
project_metadata = models.PublishedMetadata.create_from_file(
relative_path=metadata_relative_path,
publication=publication,
file=File(open(metadata_relative_path, "rb")),
)
project_metadata.save() # change to bulk create when multi-table supported