working UGC content upload with multi-upload support

This commit is contained in:
JakeBreath
2026-08-03 21:05:12 -05:00
parent 473b3c811b
commit 87b0d46232
18 changed files with 563 additions and 490 deletions
+57 -23
View File
@@ -27,7 +27,7 @@ from .models import (
Version,
slugify_tag,
)
from .storage import delete_file_index, move_file_index, store_file, store_temp_file
from .storage import delete_file_index, move_file_index, store_temp_file
def _open_indexed_file(file_index):
@@ -345,11 +345,11 @@ def _form_values(*forms):
@login_required
def project_create(request):
project_form = ProjectForm()
version_form = VersionForm(required_file=False)
version_form = VersionForm()
if request.method == 'POST':
project_form = ProjectForm(request.POST)
version_form = VersionForm(request.POST, required_file=False)
version_form = VersionForm(request.POST)
if project_form.is_valid() and version_form.is_valid():
data = project_form.cleaned_data
version_file = _latest_pending(request.user, 'version')
@@ -408,7 +408,6 @@ def project_create(request):
initial={
k: initial[k] for k in ('version_name', 'changelog') if k in initial
},
required_file=False,
)
return render(request, 'library/project_create.html', {
@@ -416,6 +415,7 @@ def project_create(request):
'version_form': version_form,
'draft_uploads': [_serialize_temp(u) for u in _pending_uploads(request.user)],
'draft_data': _form_values(project_form, version_form),
'tag_categories': list(TagCategory.objects.order_by('slug').values('slug', 'color')),
})
@@ -426,19 +426,21 @@ def project_edit(request, slug):
return HttpResponseForbidden('You do not have permission to edit this project.')
if request.method == 'POST':
form = ProjectForm(request.POST, request.FILES)
form = ProjectForm(request.POST)
if form.is_valid():
data = form.cleaned_data
project.title = data['title']
project.summary = data['summary']
project.description = data['description']
project.category = data['category']
thumbnail = data.get('thumbnail')
if thumbnail:
thumb = _latest_pending(request.user, 'thumbnail')
if thumb is not None:
delete_file_index(project.thumbnail)
project.thumbnail = store_file(
request.user, 'thumbnail', thumbnail, project.pk, subdir='',
)
project.thumbnail = _adopt_temp(thumb, project.pk, '', 'thumbnail')
thumb.status = 'used'
thumb.save(update_fields=['status'])
project.save()
_apply_tags(project, data['tags'], request.user)
project.sync_creator_tags(actor=request.user)
@@ -452,9 +454,27 @@ def project_edit(request, slug):
'category': project.category,
'tags': _current_tags(project),
})
thumb = _latest_pending(request.user, 'thumbnail')
if thumb is not None:
pending_uploads = [_serialize_temp(thumb)]
elif project.thumbnail_id:
pending_uploads = [{
'uuid': str(project.thumbnail.uuid),
'kind': 'thumbnail',
'filename': project.thumbnail.original_filename,
'content_type': project.thumbnail.content_type,
'url': project.thumbnail_url,
'removable': False,
}]
else:
pending_uploads = []
return render(request, 'library/project_edit.html', {
'project': project,
'project_form': form,
'pending_uploads': pending_uploads,
'tag_categories': list(TagCategory.objects.order_by('slug').values('slug', 'color')),
})
@@ -485,23 +505,29 @@ def version_upload(request, slug):
form = VersionForm()
if request.method == 'POST':
form = VersionForm(request.POST, request.FILES)
form = VersionForm(request.POST)
if form.is_valid():
index = store_file(
request.user, 'version', form.cleaned_data['file'],
project.pk, subdir='versions',
)
Version.objects.create(
project=project,
version_name=form.cleaned_data['version_name'],
file=index,
changelog=form.cleaned_data['changelog'],
)
messages.success(request, f'Version {form.cleaned_data["version_name"]} uploaded.')
return redirect('library:project_detail', slug=project.slug)
version_file = _latest_pending(request.user, 'version')
if version_file is None:
form.add_error('version_name', 'Upload the version file before uploading.')
else:
index = _adopt_temp(version_file, project.pk, 'versions', 'version')
version_file.status = 'used'
version_file.save(update_fields=['status'])
Version.objects.create(
project=project,
version_name=form.cleaned_data['version_name'],
file=index,
changelog=form.cleaned_data['changelog'],
)
messages.success(request, f'Version {form.cleaned_data["version_name"]} uploaded.')
return redirect('library:project_detail', slug=project.slug)
version_file = _latest_pending(request.user, 'version')
return render(request, 'library/version_upload.html', {
'project': project,
'version_form': form,
'pending_uploads': [_serialize_temp(version_file)] if version_file else [],
})
@@ -556,8 +582,16 @@ def asset_delete(request, slug, asset_id):
asset = get_object_or_404(ProjectAsset, pk=asset_id, project=project)
if not project.can_edit(request.user):
return HttpResponseForbidden('You do not have permission to delete media.')
if request.method != 'POST':
return HttpResponse(status=405)
delete_file_index(asset.file)
asset.delete()
accept = request.META.get('HTTP_ACCEPT', '')
if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or 'application/json' in accept:
return JsonResponse({'success': True})
messages.success(request, 'Media deleted.')
return redirect('library:project_detail', slug=project.slug)