temporal upload. parcial Phase 2 implementation

This commit is contained in:
JakeBreath
2026-08-03 23:49:19 -05:00
parent f09acedbcf
commit a81e31bf1a
11 changed files with 555 additions and 8 deletions
+62 -1
View File
@@ -13,6 +13,7 @@ from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.text import slugify
from common.markdown import render_markdown
from .forms import ContributorForm, ProjectForm, VersionForm
from .models import (
FileIndex,
@@ -29,6 +30,7 @@ from .models import (
slugify_tag,
)
from .storage import delete_file_index, move_file_index, store_temp_file
from .zips import parse_mods_manifest, read_pack_mcmeta
def _open_indexed_file(file_index):
@@ -312,16 +314,43 @@ def project_detail(request, slug):
assets = project.assets.select_related('file').all()
tags = project.tag_links.select_related('tag__category').all()
can_edit = project.can_edit(request.user)
guide_docs = []
if project.category == 'guide':
latest = versions.first()
if latest is not None:
guide_docs = [vf for vf in latest.files.all() if vf.is_markdown]
context = {
'project': project,
'versions': versions,
'assets': assets,
'tags': tags,
'can_edit': can_edit,
'guide_docs': guide_docs,
}
return render(request, 'library/project_detail.html', context)
def guide_doc(request, slug, version_id, file_uuid):
"""Render one markdown guide document server-side (used by the switcher)."""
version = get_object_or_404(
Version.objects.select_related('project'),
pk=version_id, project__slug=slug,
)
vf = get_object_or_404(
version.files.select_related('file'), file__uuid=file_uuid,
)
if not vf.is_markdown:
raise Http404
fh = _open_indexed_file(vf.file)
try:
text = fh.read().decode('utf-8', 'replace')
finally:
fh.close()
return HttpResponse(render_markdown(text), content_type='text/html; charset=utf-8')
DRAFT_KEYS = (
'title', 'summary', 'category', 'description',
'tags', 'version_name', 'changelog',
@@ -376,13 +405,23 @@ def _classify_version_file(file_index, category):
return 'release'
def _stored_path(file_index):
"""Resolve an indexed file's stored_path to an absolute filesystem path."""
return Path(settings.MEDIA_ROOT) / file_index.stored_path
def _finalize_version(project, version_name, changelog, temp_uploads):
"""Adopt pending 'version' temp uploads into a new Version as VersionFiles."""
"""Adopt pending 'version' temp uploads into a new Version as VersionFiles,
capturing category-specific metadata (pack.mcmeta / mods manifest)."""
version = Version.objects.create(
project=project,
version_name=version_name,
changelog=changelog,
)
pack_format = None
pack_description = ''
mods_manifest = {}
for temp in temp_uploads:
index = _adopt_temp(temp, project.pk, 'versions', 'version')
VersionFile.objects.create(
@@ -392,6 +431,28 @@ def _finalize_version(project, version_name, changelog, temp_uploads):
)
temp.status = 'used'
temp.save(update_fields=['status'])
is_zip = (index.original_filename or '').lower().endswith('.zip')
if project.category == 'non_pack' and is_zip and pack_format is None:
fmt, desc = read_pack_mcmeta(_stored_path(index))
if fmt is not None:
pack_format = fmt
pack_description = desc
elif project.category == 'modpack' and is_zip and not mods_manifest:
manifest = parse_mods_manifest(_stored_path(index), index.original_filename)
if manifest.get('files'):
mods_manifest = manifest
update_fields = []
if pack_format is not None:
version.pack_format = pack_format
version.pack_description = pack_description
update_fields += ['pack_format', 'pack_description']
if mods_manifest:
version.mods_manifest = mods_manifest
update_fields.append('mods_manifest')
if update_fields:
version.save(update_fields=update_fields)
return version