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,10 +755,13 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
permissions.append({'slug': slug, 'reason': reason, 'name': all_permission_names[slug]}) permissions.append({'slug': slug, 'reason': reason, 'name': all_permission_names[slug]})
return permissions return permissions
def _get_download_name(self) -> str: def _get_download_name(self, platform=None) -> str:
"""Return a file name for downloads.""" """Return a file name for downloads."""
replace_char = f'{self}'.replace('.', '-') 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.
return f'{utils.slugify(replace_char)}.zip' 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: def get_download_url(self, platform=None, append_repository_and_compatibility=True) -> str:
filename = f'{self.extension.type_slug_singular}-{self.extension.slug}-v{self.version}.zip' filename = f'{self.extension.type_slug_singular}-{self.extension.slug}-v{self.version}.zip'
@ -802,9 +805,9 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
file = files[0] file = files[0]
return [ return [
{ {
'name': self._get_download_name(), 'name': self._get_download_name(platform=None),
'url': self.get_download_url(platform=None),
'size': file.size_bytes, 'size': file.size_bytes,
'url': self.get_download_url(platform=None),
} }
] ]
platform2file = {} platform2file = {}
@ -819,14 +822,31 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
platform2file[platform] = file platform2file[platform] = file
return [ return [
{ {
'name': self._get_download_name(platform=p),
'platform': p, 'platform': p,
'name': self._get_download_name(),
'url': self.get_download_url(platform=p),
'size': file.size_bytes, 'size': file.size_bytes,
'url': self.get_download_url(platform=p),
} }
for p, file in platform2file.items() 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: def get_delete_url(self) -> str:
return reverse( return reverse(
'extensions:version-delete', 'extensions:version-delete',

View File

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

View File

@ -111,10 +111,14 @@
</section> </section>
<div class="btn-col"> <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> <i class="i-download"></i>
<span>{% trans 'Download' %} v{{ version.version }}</span> <span>{% trans 'Download' %} v{{ version.version }} {{ download_item.platform }}</span>
</a> </a>
{% endfor %}
{% endwith %}
{% if is_maintainer %} {% if is_maintainer %}
<a href="{{ version.update_url }}" class="btn"> <a href="{{ version.update_url }}" class="btn">
<i class="i-edit"></i><span>Edit</span> <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_hash': matching_file.original_hash,
'archive_size': matching_file.size_bytes, 'archive_size': matching_file.size_bytes,
'archive_url': self.request.build_absolute_uri( 'archive_url': self.request.build_absolute_uri(
matching_version.download_url( matching_version.get_download_url(
platform=self.platform, platform=self.platform,
append_repository_and_compatibility=False, append_repository_and_compatibility=False,
) )

View File

@ -180,12 +180,16 @@
<strong>Try at your own risk.</strong> <strong>Try at your own risk.</strong>
</p> </p>
<div class="btn-col"> <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> <i class="i-download"></i>
<span> <span>
{% trans 'Download' %} v{{ extension.latest_version.version }} {% trans 'Download' %} v{{ extension.latest_version.version }} {{ build.platforms|join:", " }}
</span> </span>
</a> </a>
{% endfor %}
{% endwith %}
</div> </div>
</div> </div>
{% endif %} {% endif %}

View File

@ -82,7 +82,7 @@ class TestTasks(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
response = self.client.get(version.extension.get_versions_url()) response = self.client.get(version.extension.get_versions_url())
self.assertEqual(response.status_code, 200) 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.status_code, 302)
self.assertEqual( self.assertEqual(
response['Location'], response['Location'],