Multi-platform: support multiple files per version #201
@ -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():
|
||||||
|
@ -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:
|
||||||
|
@ -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']
|
||||||
|
@ -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,
|
||||||
|
@ -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):
|
||||||
|
Loading…
Reference in New Issue
Block a user