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
2 changed files with 39 additions and 12 deletions
Showing only changes of commit 3440c21548 - Show all commits

View File

@ -151,6 +151,31 @@ class FiltersTest(APITestCase):
).json()
self.assertEqual(len(json['data']), 1)
def test_platform_filter_same_extension(self):
version = create_approved_version(
metadata__platforms=['linux-x64'],
metadata__version='1.0.0',
)
extension = version.extension
version = create_approved_version(
extension=extension,
metadata__platforms=['windows-x64'],
metadata__version='1.0.1',
)
url = reverse('extensions:api')
json = self.client.get(
url + '?platform=linux-x64',
HTTP_ACCEPT='application/json',
).json()
self.assertEqual(len(json['data']), 1)
json = self.client.get(
url + '?platform=windows-x64',
HTTP_ACCEPT='application/json',
).json()
self.assertEqual(len(json['data']), 1)
def test_blender_version_filter_latest_not_max_version(self):
version = create_approved_version(metadata__blender_version_min='4.0.1')
date_created = version.date_created

View File

@ -54,14 +54,16 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
except Platform.DoesNotExist:
self.platform = self.UNKNOWN_PLATFORM
def to_representation(self, instance):
matching_file = None
matching_version = None
def find_matching_file_and_version(self, instance):
# avoid triggering additional db queries, reuse the prefetched queryset
versions = [v for v in instance.versions.all() if v.is_listed]
versions = sorted(
[v for v in instance.versions.all() if v.is_listed],
key=lambda v: v.date_created,
reverse=True,
)
if not versions:
return None
versions = sorted(versions, key=lambda v: v.date_created, reverse=True)
return (None, None)
for v in versions:
if self.blender_version and not is_in_version_range(
self.blender_version,
@ -75,14 +77,15 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
platforms = file.platforms()
if self.platform and (platforms and self.platform not in platforms):
continue
Oleg-Komarov marked this conversation as resolved Outdated

this looks shared with the logic in public view that selects which file to pick from storage, and should probable become a utility or method somewhere.

this looks shared with the logic in `public` view that selects which file to pick from storage, and should probable become a utility or method somewhere.
# TODO? return all matching files (when no self.platform is passed)?
matching_file = file
matching_version = v
break
return (file, v)
Oleg-Komarov marked this conversation as resolved Outdated

needs another break here

needs another `break` here
return (None, None)
def to_representation(self, instance):
# TODO? return all matching files (when no self.platform is passed)?
matching_file, matching_version = self.find_matching_file_and_version(instance)
if not matching_file:
return None
data = {
'id': instance.extension_id,
'schema_version': matching_version.schema_version,
@ -110,7 +113,6 @@ class ListedExtensionsSerializer(serializers.ModelSerializer):
# TODO: handle copyright
'tags': [str(tag) for tag in matching_version.tags.all()],
}
return clean_json_dictionary_from_optional_fields(data)