Multi-platform: support multiple files per version #201

Merged
Oleg-Komarov merged 43 commits from multi-os into main 2024-07-09 16:27:46 +02:00
6 changed files with 52 additions and 21 deletions
Showing only changes of commit 19e7e11347 - Show all commits

View File

@ -755,9 +755,12 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
permissions.append({'slug': slug, 'reason': reason, 'name': all_permission_names[slug]})
return permissions
def _get_download_name(self) -> str:
def _get_download_name(self, platform=None) -> str:
"""Return a file name for downloads."""
replace_char = f'{self}'.replace('.', '-')
Oleg-Komarov marked this conversation as resolved Outdated

The filename below
filename = f'{self.extension.type_slug_singular}-{self.extension.slug}-v{self.version}.zip'

looks like a better name: doesn't rely on self.__str__.

It also looks like these file names should be the same in both places.

The `filename` below `filename = f'{self.extension.type_slug_singular}-{self.extension.slug}-v{self.version}.zip'` looks like a better name: doesn't rely on `self.__str__`. It also looks like these file names should be the same in both places.
if platform:
return f'{utils.slugify(replace_char)}.{platform}.zip'
Oleg-Komarov marked this conversation as resolved Outdated

to avoid making platform into file ext, maybe -?

to avoid making platform into file ext, maybe `-`?
else:
return f'{utils.slugify(replace_char)}.zip'
def get_download_url(self, platform=None, append_repository_and_compatibility=True) -> str:
@ -802,9 +805,9 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
file = files[0]
return [
{
'name': self._get_download_name(),
'url': self.get_download_url(platform=None),
'name': self._get_download_name(platform=None),
'size': file.size_bytes,
'url': self.get_download_url(platform=None),
}
]
platform2file = {}
@ -819,14 +822,31 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
platform2file[platform] = file
return [
{
'name': self._get_download_name(platform=p),
'platform': p,
'name': self._get_download_name(),
'url': self.get_download_url(platform=p),
'size': file.size_bytes,
'url': self.get_download_url(platform=p),
}
for p, file in platform2file.items()
]
def get_build_list(self) -> List[dict]:
build_list = []
for file in self.files.all():
platforms = file.platforms() or []
platform = len(platforms) and platforms[0] or None
# if file has multiple platforms, picking the first one should still produce a correct
# download_url
build_list.append(
{
'name': self._get_download_name(platform=platform),
'platforms': platforms,
'size': file.size_bytes,
'url': self.get_download_url(platform=platform),
}
)
return build_list
def get_delete_url(self) -> str:
return reverse(
'extensions:version-delete',

View File

@ -36,23 +36,26 @@
{% endif %}
</section>
<section class="card p-3 mt-4">
{% with version_files=form.instance.files.all %}
{% trans 'Files' %}:
<ul>
{% for file in version_files %}
<li>{{ file }} {% trans 'for platforms:' %} {{ file.platforms|join:", " }}</li>
{% trans 'Builds' %}:
{% with build_list=form.instance.get_build_list %}
<div class="btn-col">
{% for build in build_list %}
<a href="{{ build.url }}" download="{{ build.name }}" class="btn btn-danger btn-block">
<i class="i-download"></i>
<span>
{% trans 'Download' %} v{{ form.instance.version }} {{ build.platforms|join:", " }}
</span>
</a>
{% endfor %}
</ul>
{% endwith %}
{% if form.instance.can_upload_more_files %}
<div>
<a href="{{ form.instance.get_version_upload_url }}" class="btn btn-primary">
<i class="i-upload"></i>
{% trans 'Upload files for other platforms' %}
</a>
{% endif %}
</div>
</section>
{% endif %}
</div>
<div class="col-md-4">
<div class="is-sticky">

View File

@ -111,10 +111,14 @@
</section>
<div class="btn-col">
<a href="{{ version.download_url }}" download="{{ version.download_name }}" class="btn btn-primary btn-block">
{% with download_list=version.get_download_list %}
{% for download_item in download_list %}
<a href="{{ download_item.url }}" download="{{ download_item.name }}" class="btn btn-primary btn-block">
<i class="i-download"></i>
<span>{% trans 'Download' %} v{{ version.version }}</span>
<span>{% trans 'Download' %} v{{ version.version }} {{ download_item.platform }}</span>
</a>
{% endfor %}
{% endwith %}
{% if is_maintainer %}
<a href="{{ version.update_url }}" class="btn">
<i class="i-edit"></i><span>Edit</span>

View File

@ -92,7 +92,7 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
'archive_hash': matching_file.original_hash,
'archive_size': matching_file.size_bytes,
'archive_url': self.request.build_absolute_uri(
matching_version.download_url(
matching_version.get_download_url(
platform=self.platform,
append_repository_and_compatibility=False,
)

View File

@ -180,12 +180,16 @@
<strong>Try at your own risk.</strong>
</p>
<div class="btn-col">
<a href="{{ extension.latest_version.download_url }}" download="{{ extension.latest_version.download_name }}" class="btn btn-danger btn-block">
{% with build_list=extension.latest_version.get_build_list %}
{% for build in build_list %}
<a href="{{ build.url }}" download="{{ build.name }}" class="btn btn-danger btn-block">
<i class="i-download"></i>
<span>
{% trans 'Download' %} v{{ extension.latest_version.version }}
{% trans 'Download' %} v{{ extension.latest_version.version }} {{ build.platforms|join:", " }}
</span>
</a>
{% endfor %}
{% endwith %}
</div>
</div>
{% endif %}

View File

@ -82,7 +82,7 @@ class TestTasks(TestCase):
self.assertEqual(response.status_code, 200)
response = self.client.get(version.extension.get_versions_url())
self.assertEqual(response.status_code, 200)
response = self.client.get(version.download_url())
response = self.client.get(version.get_download_url())
self.assertEqual(response.status_code, 302)
self.assertEqual(
response['Location'],