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
5 changed files with 44 additions and 1 deletions
Showing only changes of commit ef122d6427 - Show all commits

View File

@ -681,6 +681,31 @@ class Version(CreatedModifiedMixin, TrackChangesMixin, models.Model):
def can_upload_more_files(self): def can_upload_more_files(self):
return len(self.get_available_platforms()) > 0 return len(self.get_available_platforms()) > 0
def add_file(self, file: File):
self.files.add(file)
self.update_platforms()
@transaction.atomic
def update_platforms(self):
current_platforms = set([p.slug for p in self.platforms.all()])
files_platforms = set()
for file in self.files.all():
if file_platforms := file.platforms():
files_platforms.update(file_platforms)
else:
# we have a cross-platform file - version must not specify platforms
# other files should not exist (validation takes care of that),
# but here we won't double-check it (?)
if len(current_platforms):
self.platforms.delete()
return
if to_create := files_platforms - current_platforms:
for p in to_create:
self.platforms.add(Platform.objects.get(slug=p))
if to_delete := current_platforms - files_platforms:
for p in to_delete:
self.platforms.remove(Platform.objects.get(slug=p))
def get_available_platforms(self): def get_available_platforms(self):
all_platforms = set(p.slug for p in Platform.objects.all()) all_platforms = set(p.slug for p in Platform.objects.all())
for file in self.files.all(): for file in self.files.all():

View File

@ -43,6 +43,8 @@ def _delete_versionfiles_file(
logger.info('Deleting File pk=%s of VersionFile pk=%s', file.pk, instance.pk) logger.info('Deleting File pk=%s of VersionFile pk=%s', file.pk, instance.pk)
file.delete() file.delete()
instance.version.update_platforms()
# this code is already quite convoluted # this code is already quite convoluted
# TODO? maybe find some way to have a predictable order of deletion # TODO? maybe find some way to have a predictable order of deletion
try: try:

View File

@ -110,6 +110,21 @@ class VersionTest(TestCase):
) )
self.assertFalse(version_platforms_all.can_upload_more_files) self.assertFalse(version_platforms_all.can_upload_more_files)
def test_collect_platforms_across_files(self):
version = create_version(metadata__platforms=['linux-x64'])
file = FileFactory(metadata__platforms=['windows-x64'])
version.add_file(file)
self.assertQuerysetEqual(
version.platforms.order_by('slug'),
Platform.objects.filter(slug__in=['linux-x64', 'windows-x64']).order_by('slug'),
)
file.delete()
version.refresh_from_db()
self.assertQuerysetEqual(
version.platforms.order_by('slug'),
Platform.objects.filter(slug__in=['linux-x64']).order_by('slug'),
)
class UpdateMetadataTest(TestCase): class UpdateMetadataTest(TestCase):
fixtures = ['dev', 'licenses'] fixtures = ['dev', 'licenses']

View File

@ -218,6 +218,7 @@ class UploadExtensionVersionView(APIView):
file_instance.user = user file_instance.user = user
file_instance.save() file_instance.save()
# FIXME check if version already exists, then append file and update release_notes
version = extension.create_version_from_file( version = extension.create_version_from_file(
file=file_instance, file=file_instance,
release_notes=release_notes, release_notes=release_notes,

View File

@ -307,7 +307,7 @@ class UploadVersionFileView(
@transaction.atomic @transaction.atomic
def form_valid(self, form): def form_valid(self, form):
response = super().form_valid(form) response = super().form_valid(form)
self.version.files.add(self.object) self.version.add_file(self.object)
return response return response
def get_success_url(self): def get_success_url(self):