Multi-platform: support multiple files per version #201
@ -682,6 +682,13 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
|
||||
return len(self.get_remaining_platforms()) > 0
|
||||
Oleg-Komarov marked this conversation as resolved
Outdated
|
||||
|
||||
def add_file(self, file: File):
|
||||
current_platforms = set([p.slug for p in self.platforms.all()])
|
||||
file_platforms = set(file.get_platforms() or [])
|
||||
if overlap := current_platforms & file_platforms:
|
||||
raise ValueError(
|
||||
f'add_file failed: File pk={file.pk} and Version pk={self.pk} have '
|
||||
f'overlapping platforms: {overlap}'
|
||||
)
|
||||
self.files.add(file)
|
||||
self.update_platforms()
|
||||
|
||||
@ -716,6 +723,16 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
|
||||
all_platforms -= set(platforms)
|
||||
return all_platforms
|
||||
|
||||
def get_file_for_platform(self, platform):
|
||||
for file in self.files.all():
|
||||
platforms = file.get_platforms()
|
||||
# not platform-specific, matches all platforms
|
||||
if not platforms:
|
||||
return file
|
||||
if platform is None or platform in platforms:
|
||||
return file
|
||||
return None
|
||||
|
||||
@property
|
||||
def is_listed(self):
|
||||
# To be public, at least one version file must have a public status.
|
||||
|
@ -125,6 +125,29 @@ class VersionTest(TestCase):
|
||||
Platform.objects.filter(slug__in=['linux-x64']).order_by('slug'),
|
||||
)
|
||||
|
||||
def test_add_file(self):
|
||||
version = create_version(metadata__platforms=['linux-x64'])
|
||||
file = FileFactory(metadata__platforms=['linux-x64'])
|
||||
with self.assertRaises(ValueError):
|
||||
version.add_file(file)
|
||||
|
||||
def test_get_file_for_platform(self):
|
||||
version = create_version(metadata__platforms=['linux-x64'])
|
||||
file = FileFactory(metadata__platforms=['windows-x64'])
|
||||
version.add_file(file)
|
||||
self.assertIsNotNone(version.get_file_for_platform(None))
|
||||
self.assertIsNotNone(version.get_file_for_platform('linux-x64'))
|
||||
self.assertIsNotNone(version.get_file_for_platform('windows-x64'))
|
||||
self.assertIsNone(version.get_file_for_platform('windows-arm64'))
|
||||
|
||||
file2 = FileFactory(metadata__platforms=['macos-x64', 'macos-arm64'])
|
||||
version.add_file(file2)
|
||||
self.assertIsNotNone(version.get_file_for_platform('macos-x64'))
|
||||
|
||||
version2 = create_version(metadata__platforms=[])
|
||||
self.assertIsNotNone(version2.get_file_for_platform(None))
|
||||
self.assertIsNotNone(version2.get_file_for_platform('macos-x64'))
|
||||
|
||||
|
||||
class UpdateMetadataTest(TestCase):
|
||||
fixtures = ['dev', 'licenses']
|
||||
|
@ -71,12 +71,7 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
|
||||
v.blender_version_max,
|
||||
):
|
||||
continue
|
||||
for file in v.files.all():
|
||||
# empty platforms field matches any platform filter
|
||||
# UNKNOWN_PLATFORM matches only empty platforms field
|
||||
platforms = file.get_platforms()
|
||||
if self.platform and (platforms and self.platform not in platforms):
|
||||
continue
|
||||
if file := v.get_file_for_platform(self.platform):
|
||||
return (file, v)
|
||||
|
||||
return (None, None)
|
||||
|
@ -73,11 +73,9 @@ def extension_version_platform_download(request, type_slug, slug, version, platf
|
||||
extension_version = get_object_or_404(Version, extension__slug=slug, version=version)
|
||||
ExtensionDownload.create_from_request(request, object_id=extension_version.extension_id)
|
||||
VersionDownload.create_from_request(request, object_id=extension_version.pk)
|
||||
for file in extension_version.files.all():
|
||||
platforms = file.get_platforms() or []
|
||||
if platform is None or platform in platforms:
|
||||
url = file.source.url
|
||||
return redirect(f'{url}?filename={filename}')
|
||||
if file := extension_version.get_file_for_platform(platform):
|
||||
url = file.source.url
|
||||
return redirect(f'{url}?filename={filename}')
|
||||
raise Http404()
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user
s/get_available_platforms/get_missing_platforms/
?