combo/combo/manager/views.py

334 lines
11 KiB
Python
Raw Normal View History

# 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/>.
2014-12-07 15:35:07 +01:00
import json
import ckeditor
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.files.storage import default_storage
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
2015-02-18 15:48:44 +01:00
from django.core.urlresolvers import reverse, reverse_lazy
2014-12-08 15:32:30 +01:00
from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import force_text
from django.views.decorators.csrf import requires_csrf_token
from django.views.generic import (TemplateView, RedirectView, DetailView,
2015-02-18 15:48:44 +01:00
CreateView, UpdateView, ListView, DeleteView, FormView)
from combo.data.models import Page, CellBase, UnlockMarkerCell
from combo import plugins
2015-02-18 15:48:44 +01:00
from .forms import PageForm, PageEditForm, PageVisibilityForm, SiteImportForm
2014-12-08 10:37:26 +01:00
class HomepageView(ListView):
model = Page
template_name = 'combo/manager_home.html'
def get_context_data(self, **kwargs):
self.object_list = Page.get_as_reordered_flat_hierarchy(self.object_list)
context = super(HomepageView, self).get_context_data(**kwargs)
context['extra_actions'] = plugins.get_extra_manager_actions()
return context
homepage = HomepageView.as_view()
2015-02-18 14:15:31 +01:00
class SiteExportView(ListView):
model = Page
def render_to_response(self, context, **response_kwargs):
response = HttpResponse(content_type='application/json')
json.dump([x.get_serialized_page() for x in self.object_list],
response, indent=2)
return response
site_export = SiteExportView.as_view()
2015-02-18 15:48:44 +01:00
class SiteImportView(FormView):
form_class = SiteImportForm
template_name = 'combo/site_import.html'
success_url = reverse_lazy('combo-manager-homepage')
def form_valid(self, form):
json_site = json.load(self.request.FILES['site_json'])
Page.load_serialized_pages(json_site)
return super(SiteImportView, self).form_valid(form)
site_import = SiteImportView.as_view()
class PageAddView(CreateView):
model = Page
template_name = 'combo/page_add.html'
2014-12-08 10:37:26 +01:00
form_class = PageForm
def get_initial(self):
initial = super(PageAddView, self).get_initial()
if Page.objects.count() == 0:
# first page
initial['title'] = _('Home')
initial['slug'] = 'index'
return initial
2014-12-08 10:37:26 +01:00
def get_success_url(self):
return reverse('combo-manager-page-view', kwargs={'pk': self.object.id})
page_add = PageAddView.as_view()
2014-12-08 10:37:26 +01:00
class PageEditView(UpdateView):
model = Page
template_name = 'combo/page_add.html'
form_class = PageEditForm
2014-12-08 10:37:26 +01:00
def get_success_url(self):
return reverse('combo-manager-page-view', kwargs={'pk': self.object.id})
page_edit = PageEditView.as_view()
class PageVisibilityView(PageEditView):
form_class = PageVisibilityForm
page_visibility = PageVisibilityView.as_view()
2014-12-08 10:37:26 +01:00
class PageView(DetailView):
model = Page
template_name = 'combo/page_view.html'
def get_context_data(self, **kwargs):
context = super(PageView, self).get_context_data(**kwargs)
context['cell_types'] = CellBase.get_cell_content_types()
cells = CellBase.get_cells(page_id=self.object.id)
2014-12-08 10:37:26 +01:00
template = self.object.template_name
placeholders = []
extra_placeholders = []
combo_template = settings.COMBO_PUBLIC_TEMPLATES.get(template)
unlocked_placeholders = self.object.get_unlocked_placeholders(cells)
for placeholder_key, placeholder in combo_template['placeholders'].items():
placeholder_dict = {
'key': placeholder_key,
'name': placeholder['name'],
}
if placeholder.get('acquired') and not placeholder_key in unlocked_placeholders:
extra_placeholders.append(placeholder_dict)
else:
placeholder_dict['cells'] = [x for x in cells if (
x.placeholder == placeholder_key)]
placeholders.append(placeholder_dict)
context['unlock'] = UnlockMarkerCell.get_content_types()[0]
context['placeholders'] = placeholders
context['extra_placeholders'] = extra_placeholders
return context
page_view = requires_csrf_token(PageView.as_view())
2015-01-12 13:28:11 +01:00
class PageDeleteView(DeleteView):
model = Page
template_name = 'combo/generic_confirm_delete.html'
def get_success_url(self):
return reverse('combo-manager-homepage')
page_delete = PageDeleteView.as_view()
class PageExportView(DetailView):
model = Page
def render_to_response(self, context, **response_kwargs):
response = HttpResponse(content_type='application/json')
2015-02-18 14:15:31 +01:00
json.dump(self.object.get_serialized_page(), response, indent=2)
return response
page_export = PageExportView.as_view()
class PageAddCellView(RedirectView):
permanent = False
2014-12-13 11:25:53 +01:00
def get_redirect_url(self, page_pk, cell_type, variant, ph_key):
cell_class = ContentType.objects.get(id=cell_type).model_class()
cell = cell_class(page_id=page_pk, placeholder=ph_key)
2014-12-13 11:25:53 +01:00
cell.set_variant(variant)
orders = [x.order for x in CellBase.get_cells(page_id=page_pk)]
if orders:
cell.order = max(orders)+1
else:
cell.order = 1
cell.save()
return reverse('combo-manager-page-view', kwargs={'pk': page_pk})
page_add_cell = PageAddCellView.as_view()
class PageEditCellView(UpdateView):
def get_object(self, queryset=None):
page_pk = self.kwargs.get('page_pk')
cell_reference = self.kwargs.get('cell_reference')
try:
return CellBase.get_cell(cell_reference, page_id=page_pk)
except ObjectDoesNotExist:
raise Http404()
def get_prefix(self):
return 'c%s' % self.kwargs.get('cell_reference')
def get_form_class(self):
return self.object.get_default_form_class()
def get_success_url(self):
return reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')})
page_edit_cell = PageEditCellView.as_view()
2014-12-08 15:32:30 +01:00
2014-12-08 16:55:13 +01:00
class PageDeleteCellView(DeleteView):
template_name = 'combo/generic_confirm_delete.html'
def get_object(self, queryset=None):
page_pk = self.kwargs.get('page_pk')
cell_reference = self.kwargs.get('cell_reference')
2014-12-08 16:55:13 +01:00
try:
return CellBase.get_cell(cell_reference, page_id=page_pk)
except ObjectDoesNotExist:
2014-12-08 16:55:13 +01:00
raise Http404()
def get_success_url(self):
return reverse('combo-manager-page-view', kwargs={'pk': self.kwargs.get('page_pk')})
page_delete_cell = PageDeleteCellView.as_view()
class PageCellVisibilityView(PageEditCellView):
template_name = 'combo/cell_visibility.html'
def get_form_class(self):
return self.object.get_visibility_form_class()
page_cell_visibility = PageCellVisibilityView.as_view()
class PageCellOptionsView(PageEditCellView):
template_name = 'combo/cell_options.html'
def get_form_class(self):
return self.object.get_options_form_class()
page_cell_options = PageCellOptionsView.as_view()
2014-12-08 15:32:30 +01:00
def cell_order(request, page_pk):
for cell in CellBase.get_cells(page_id=page_pk):
2014-12-08 15:32:30 +01:00
old_order = cell.order
old_placeholder = cell.placeholder
key_suffix = cell.get_reference()
try:
new_order = int(request.GET.get('pos_' + key_suffix))
except TypeError:
# the cell is not present in the query string, most probably
# because it's in a different placeholder
continue
new_placeholder = request.GET.get('ph_' + key_suffix)
2014-12-08 15:32:30 +01:00
if new_order != old_order or new_placeholder != old_placeholder:
cell.order = new_order
cell.placeholder = new_placeholder
cell.save()
return HttpResponse(status=206)
def page_order(request):
new_order = [int(x) for x in request.GET['new-order'].split(',')]
2015-01-17 14:13:58 +01:00
moved_page = Page.objects.get(id=request.GET['moved-page-id'])
if request.GET['moved-page-new-parent']:
2015-01-17 14:13:58 +01:00
moved_page.parent_id = request.GET['moved-page-new-parent']
else:
moved_page.parent_id = None
moved_page.save()
for page in Page.objects.filter(parent_id=moved_page.parent_id):
page.order = new_order.index(page.id)+1
page.save()
return redirect(reverse('combo-manager-homepage'))
def page_get_additional_label(request, page_pk, cell_reference):
cell = CellBase.get_cell(cell_reference, page_id=page_pk)
response = HttpResponse(content_type='application/json')
json.dump({'label': cell.get_additional_label() or ''}, response)
return response
class Assets(TemplateView):
template_name = 'combo/manager_assets.html'
def get_context_data(self, **kwargs):
context = super(Assets, self).get_context_data(**kwargs)
context['files'] = []
for filename in ckeditor.views.get_image_files(self.request.user):
src = ckeditor.utils.get_media_url(filename)
if getattr(settings, 'CKEDITOR_IMAGE_BACKEND', None):
thumb = ckeditor.utils.get_media_url(
ckeditor.utils.get_thumb_filename(filename))
else:
thumb = src
context['files'].append({
'thumb': thumb,
'src': src,
'is_image': ckeditor.views.is_image(src),
'orig': filename,
})
return context
assets = Assets.as_view()
def asset_delete(request):
img_orig = request.GET['img_orig']
if '..' in img_orig:
raise PermissionDenied() # better safe than sorry
base_path = settings.CKEDITOR_UPLOAD_PATH
if getattr(settings, 'CKEDITOR_RESTRICT_BY_USER', False):
base_path = os.path.join(base_path, user.username)
if not img_orig.startswith(base_path):
raise PermissionDenied()
2015-05-20 20:15:58 +02:00
default_storage.delete(img_orig)
return HttpResponse(status=204)
def menu_json(request):
response = HttpResponse(content_type='application/json')
if getattr(settings, 'TEMPLATE_VARS', {}).get('site_title'):
label = _('Editing %(site_title)s') % getattr(settings, 'TEMPLATE_VARS')
else:
label = _('Content Management')
json_str = json.dumps([{'label': force_text(label),
'slug': 'portal',
'url': request.build_absolute_uri(reverse('combo-manager-homepage'))
}])
for variable in ('jsonpCallback', 'callback'):
if variable in request.GET:
json_str = '%s(%s);' % (request.GET[variable], json_str)
break
response.write(json_str)
return response