192 lines
6.5 KiB
Python
192 lines
6.5 KiB
Python
# combo - content management system
|
|
# Copyright (C) 2014 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import urllib
|
|
import urlparse
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import logout as auth_logout
|
|
from django.contrib.auth import views as auth_views
|
|
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
|
from django.http import (Http404, HttpResponse, HttpResponseRedirect,
|
|
HttpResponsePermanentRedirect)
|
|
from django.shortcuts import render, resolve_url
|
|
from django.template import RequestContext
|
|
|
|
try:
|
|
from mellon.utils import get_idps
|
|
except ImportError:
|
|
get_idps = lambda: []
|
|
|
|
from combo.data.models import CellBase, Page
|
|
|
|
|
|
def login(request, *args, **kwargs):
|
|
if any(get_idps()):
|
|
if not 'next' in request.GET:
|
|
return HttpResponseRedirect(resolve_url('mellon_login'))
|
|
return HttpResponseRedirect(resolve_url('mellon_login') + '?next='
|
|
+ urllib.quote(request.GET.get('next')))
|
|
return auth_views.login(request, *args, **kwargs)
|
|
|
|
def logout(request, next_page=None):
|
|
if any(get_idps()):
|
|
return HttpResponseRedirect(resolve_url('mellon_logout'))
|
|
auth_logout(request)
|
|
if next_page is not None:
|
|
next_page = resolve_url(next_page)
|
|
else:
|
|
next_page = '/'
|
|
return HttpResponseRedirect(next_page)
|
|
|
|
def ajax_page_cell(request, page_pk, cell_reference):
|
|
try:
|
|
page = Page.objects.get(id=page_pk)
|
|
except Page.DoesNotExist:
|
|
raise Http404()
|
|
if not page.is_visible(request.user):
|
|
raise PermissionDenied()
|
|
try:
|
|
cell = CellBase.get_cell(cell_reference, page_id=page_pk)
|
|
except ObjectDoesNotExist:
|
|
raise Http404()
|
|
|
|
context = RequestContext(request, {
|
|
'page': page,
|
|
'request': request,
|
|
'ajax': True,
|
|
'site_base': request.build_absolute_uri('/')[:-1],
|
|
})
|
|
|
|
return HttpResponse(cell.render(context), content_type='text/html')
|
|
|
|
|
|
def extend_with_locked_placeholders_cells(cells, page, pages):
|
|
locked_placeholders = page.get_locked_placeholders(cells)
|
|
|
|
if locked_placeholders:
|
|
# there are some acquired placeholders, look in parent pages for
|
|
# appropriate content.
|
|
try:
|
|
# add the site index page as ultimate parent
|
|
pages.insert(0, Page.objects.get(slug='index'))
|
|
except Page.DoesNotExist:
|
|
pass
|
|
unlocker_cells = CellBase.get_cells(page_id__in=[x.id for x in pages])
|
|
found_placeholders = {}
|
|
for parent_page in reversed(pages[:-1]):
|
|
for placeholder in parent_page.get_unlocked_placeholders(unlocker_cells):
|
|
if not placeholder in locked_placeholders:
|
|
continue
|
|
if not placeholder in found_placeholders:
|
|
found_placeholders[placeholder] = parent_page.id
|
|
if len(found_placeholders) == len(locked_placeholders):
|
|
break
|
|
|
|
# add found cells to the page cells
|
|
for placeholder_key, page_id in found_placeholders.items():
|
|
cells.extend([x for x in unlocker_cells if x.page_id == page_id and
|
|
x.placeholder == placeholder_key])
|
|
|
|
|
|
def skeleton(request):
|
|
source = request.GET['source']
|
|
selected_page = None
|
|
|
|
# look in redirect pages after the best match for the source
|
|
redirect_pages = Page.objects.exclude(redirect_url__isnull=True).exclude(redirect_url='')
|
|
for page in redirect_pages:
|
|
if source.startswith(page.redirect_url):
|
|
if selected_page is None or len(page.redirect_url) > len(selected_page.redirect_url):
|
|
selected_page = page
|
|
|
|
if selected_page is None:
|
|
# if there was no page found, look for a domain match
|
|
netloc = urlparse.urlparse(source).netloc
|
|
for page in redirect_pages:
|
|
if urlparse.urlparse(page.redirect_url).netloc == netloc:
|
|
selected_page = page
|
|
break
|
|
else:
|
|
raise PermissionDenied()
|
|
|
|
pages = list(page.get_parents_and_self())
|
|
cells = CellBase.get_cells(page_id=page.id)
|
|
extend_with_locked_placeholders_cells(cells, page, pages)
|
|
|
|
combo_template = settings.COMBO_PUBLIC_TEMPLATES[page.template_name]
|
|
|
|
ctx = {
|
|
'page': selected_page,
|
|
'page_cells': cells,
|
|
'request': request,
|
|
'render_skeleton': True,
|
|
'site_base': request.build_absolute_uri('/')[:-1],
|
|
}
|
|
|
|
template_name = combo_template['template']
|
|
return render(request, template_name, ctx)
|
|
|
|
|
|
def empty_site(request):
|
|
return render(request, 'combo/empty_site.html', {})
|
|
|
|
|
|
def page(request):
|
|
url = request.path_info
|
|
parts = [x for x in request.path_info.strip('/').split('/') if x]
|
|
if not parts:
|
|
parts = ['index']
|
|
try:
|
|
pages = [Page.objects.get(slug=x) for x in parts]
|
|
except Page.DoesNotExist:
|
|
if not url.endswith('/') and settings.APPEND_SLASH:
|
|
return HttpResponsePermanentRedirect(url + '/')
|
|
if Page.objects.count() == 0 and parts == ['index']:
|
|
return empty_site(request)
|
|
else:
|
|
raise Http404()
|
|
|
|
for i, page in enumerate(pages[1:]):
|
|
if page.parent_id != pages[i].id:
|
|
raise Http404()
|
|
|
|
page = pages[-1]
|
|
|
|
if not page.is_visible(request.user):
|
|
if not request.user.is_authenticated():
|
|
from django.contrib.auth.views import redirect_to_login
|
|
return redirect_to_login(request.path)
|
|
raise PermissionDenied()
|
|
|
|
if page.redirect_url:
|
|
return HttpResponseRedirect(page.redirect_url)
|
|
|
|
combo_template = settings.COMBO_PUBLIC_TEMPLATES[page.template_name]
|
|
|
|
cells = CellBase.get_cells(page_id=page.id)
|
|
extend_with_locked_placeholders_cells(cells, page, pages)
|
|
cells = [x for x in cells if x.is_visible(user=request.user)]
|
|
|
|
ctx = {
|
|
'page': page,
|
|
'page_cells': cells,
|
|
'request': request,
|
|
}
|
|
|
|
template_name = combo_template['template']
|
|
return render(request, template_name, ctx)
|