public: move page resolve code to utils (#57672)

This commit is contained in:
Valentin Deniaud 2021-10-11 14:53:15 +02:00
parent 0b33600a00
commit 18fcc5a35d
2 changed files with 66 additions and 49 deletions

View File

@ -27,7 +27,11 @@ from django.utils.translation import ugettext_lazy as _
from combo.apps.assets.models import Asset
from combo.apps.assets.utils import add_tar_content, clean_assets_files, tar_assets_files, untar_assets_files
from .models import Page
from .models import Page, extract_context_from_sub_slug
class MissingSubSlug(Exception):
pass
class ImportSiteError(Exception):
@ -196,3 +200,56 @@ def import_site_tar(fd, if_empty=False, clean=False, overwrite=False, request=No
data.update(untar_assets_files(tar, overwrite=overwrite))
pages = import_site(data, if_empty=if_empty, clean=clean, request=request)
return pages
def get_page_from_url_parts(parts, request=None):
pages = {}
for page in Page.objects.filter(slug__in=parts):
if not page.slug in pages:
pages[page.slug] = []
pages[page.slug].append(page)
if not pages:
return
i = 0
hierarchy_ids = [None]
while i < len(parts):
slug_pages = pages.get(parts[i])
if slug_pages is None or len(slug_pages) == 0:
page = None
break
if len(slug_pages) == 1:
page = slug_pages[0]
else:
# multiple pages with same slugs
try:
page = [x for x in slug_pages if x.parent_id == hierarchy_ids[-1]][0]
except IndexError:
page = None
break
if page.parent_id != hierarchy_ids[-1]:
if i == 0:
# root page should be at root but maybe the page is a child of
# /index/, and as /index/ is silent the page would appear
# directly under /; this is not a suggested practice.
if page.parent.slug != 'index' and page.parent.parent_id is not None:
page = None
break
else:
page = None
break
if page.sub_slug:
if parts[i + 1 :] == []:
raise MissingSubSlug
extra = extract_context_from_sub_slug(page.sub_slug, parts[i + 1])
if extra is None:
page = None
break
if request:
request.extra_context_data.update(extra)
parts = parts[: i + 1] + parts[i + 2 :] # skip variable component
i += 1
hierarchy_ids.append(page.id)
return page

View File

@ -55,8 +55,8 @@ from combo.data.models import (
PostException,
Redirect,
TextCell,
extract_context_from_sub_slug,
)
from combo.data.utils import MissingSubSlug, get_page_from_url_parts
from combo.profile.models import Profile
from combo.profile.utils import get_user_from_name_id
@ -481,56 +481,16 @@ def page(request):
request.session['visited'] = True
return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH)
pages = {}
for page in Page.objects.filter(slug__in=parts):
if not page.slug in pages:
pages[page.slug] = []
pages[page.slug].append(page)
try:
page = get_page_from_url_parts(parts, request)
except MissingSubSlug:
# a sub slug is expected but was not found; redirect to parent
# page as a mitigation.
return HttpResponseRedirect('..')
if pages == {} and parts == ['index'] and Page.objects.count() == 0:
if page is None and parts == ['index'] and Page.objects.count() == 0:
return empty_site(request)
i = 0
hierarchy_ids = [None]
while i < len(parts):
slug_pages = pages.get(parts[i])
if slug_pages is None or len(slug_pages) == 0:
page = None
break
if len(slug_pages) == 1:
page = slug_pages[0]
else:
# multiple pages with same slugs
try:
page = [x for x in slug_pages if x.parent_id == hierarchy_ids[-1]][0]
except IndexError:
page = None
break
if page.parent_id != hierarchy_ids[-1]:
if i == 0:
# root page should be at root but maybe the page is a child of
# /index/, and as /index/ is silent the page would appear
# directly under /; this is not a suggested practice.
if page.parent.slug != 'index' and page.parent.parent_id is not None:
page = None
break
else:
page = None
break
if page.sub_slug:
if parts[i + 1 :] == []:
# a sub slug is expected but was not found; redirect to parent
# page as a mitigation.
return HttpResponseRedirect('..')
extra = extract_context_from_sub_slug(page.sub_slug, parts[i + 1])
if extra is None:
page = None
break
request.extra_context_data.update(extra)
parts = parts[: i + 1] + parts[i + 2 :] # skip variable component
i += 1
hierarchy_ids.append(page.id)
if not url.endswith('/') and settings.APPEND_SLASH:
# this is useful to allow /login, /manage, and other non-page URLs to
# work. re.sub is used to replace repeated slashes by single ones,