extensions-website/extensions/views/submit.py
Anna Sirota b0bb4905b2 Reuse files as previews, icons or featured images (#161)
Now it should be be possible to:

* upload the same image as a preview or featured image on different extensions;
* upload the same image as an icon on different extensions;
* select the same video/image multiple times while adding previews on Draft or Edit page: first one will be saved, the rest of the duplicates will be ignored.

If all extensions referencing the file in any way are deleted, the file remains in the database: no thumbnail generating or scanning will happen if/when the file gets re-uploaded as a preview or featured image.

In all cases of re-upload `File.user` will not change: this shouldn't be a problem because currently there's no code relying on image ownership.

Version files will remain the only exception from this changed behaviour: it will only be possible to re-upload a version file once the version itself is deleted (which also deletes its file).

As a consequence of this change `File.extension_id` is dropped, because it is no longer possible to choose which extension should be saved there.

Should take care of #157

Reviewed-on: #161
Reviewed-by: Oleg-Komarov <oleg-komarov@noreply.localhost>
2024-06-04 12:23:25 +02:00

72 lines
2.4 KiB
Python

import logging
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import transaction
from django.views.generic.edit import CreateView
from extensions.models import Version, Extension
from files.forms import FileForm
from files.models import File
logger = logging.getLogger(__name__)
class UploadFileView(LoginRequiredMixin, CreateView):
model = File
template_name = 'extensions/submit.html'
form_class = FileForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
drafts = Extension.objects.authored_by(self.request.user).filter(
status=Extension.STATUSES.DRAFT
)
context['drafts'] = drafts
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_success_url(self):
return self.extension.get_draft_url()
@transaction.atomic
def form_valid(self, form):
"""Create an extension and a version already, associated with the user."""
self.file = form.instance
parsed_extension_fields = self.file.parsed_extension_fields
if parsed_extension_fields:
# Try to look up extension by the same author and file info
extension = (
Extension.objects.authored_by(self.request.user)
.filter(type=self.file.type, **parsed_extension_fields)
.first()
)
if extension:
logger.warning(
'Found existing extension pk=%s for file pk=%s',
extension.pk,
self.file.pk,
)
return False
# Make sure an extension has a user associated to it from the beginning, otherwise
# it will prevent it from being re-uploaded and yet not show on My Extensions.
self.extension = Extension.objects.update_or_create(
type=self.file.type, **parsed_extension_fields
)[0]
self.extension.authors.add(self.request.user)
self.extension.save()
# Need to save the form to be able to use the file to create the version.
self.object = self.file = form.save()
Version.objects.update_or_create(
extension=self.extension, file=self.file, **self.file.parsed_version_fields
)[0]
return super().form_valid(form)