# combo - content management system # Copyright (C) 2014-2017 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 . import json from django.conf import settings from django.contrib.contenttypes.models import ContentType from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.db.models import Max, Min from django.http import Http404, HttpResponse, HttpResponseRedirect from django.utils.encoding import force_text from django.views.decorators.csrf import csrf_exempt from django.views.generic import View from combo.data.models import CellBase, ConfigJsonCell from combo.data.library import get_cell_class from combo.public.views import render_cell from .models import DashboardCell, Tile from .templatetags.dashboard import get_cell_data def dashboard_success(request, dashboard, cell_data): dashboard_url = dashboard.page.get_online_url() if request.is_ajax(): return HttpResponse( json.dumps({ 'err': 0, 'url': request.build_absolute_uri(dashboard_url), 'cell_data': cell_data}), content_type='application/json') return HttpResponseRedirect(dashboard_url) class DashboardAddTileView(View): def get(self, request, *args, **kwargs): if not request.user.is_authenticated(): raise PermissionDenied() dashboard = DashboardCell.objects.all()[0] cell = CellBase.get_cell(kwargs['cell_reference']) if not cell.page.is_visible(request.user): raise PermissionDenied() if not cell.is_visible(request.user): raise PermissionDenied() cell.pk = None cell.page = dashboard.page cell.placeholder = '_dashboard' cell.save() tile = Tile(dashboard=dashboard, cell=cell, user=request.user, order=0) if settings.COMBO_DASHBOARD_NEW_TILE_POSITION == 'first': order = Tile.objects.filter(dashboard=dashboard, user=request.user).aggregate(Min('order')).get('order__min') tile.order = order - 1 if order is not None else 0 elif settings.COMBO_DASHBOARD_NEW_TILE_POSITION == 'last': order = Tile.objects.filter(dashboard=dashboard, user=request.user).aggregate(Max('order')).get('order_max') tile.order = order + 1 if order is not None else 0 tile.save() cell_data = get_cell_data(cell) cell_data['remove_url'] = reverse( 'combo-dashboard-remove-tile', kwargs={'cell_reference': cell.get_reference()}) return dashboard_success(request, dashboard, cell_data) dashboard_add_tile = DashboardAddTileView.as_view() class DashboardRemoveTileView(View): def get(self, request, *args, **kwargs): cell = CellBase.get_cell(kwargs['cell_reference']) try: tile = Tile.get_by_cell(cell) except Tile.DoesNotExist: raise Http404() if tile.user != request.user: raise PermissionDenied() dashboard = tile.dashboard cell_data = get_cell_data(cell) tile.delete() # do not remove cell so it can directly be added back cell_data['add_url'] = reverse( 'combo-dashboard-add-tile', kwargs={'cell_reference': cell.get_reference()}) return dashboard_success(request, dashboard, cell_data) dashboard_remove_tile = DashboardRemoveTileView.as_view() @csrf_exempt def dashboard_auto_tile(request, *args, **kwargs): dashboard = DashboardCell.objects.all()[0] cell = ConfigJsonCell(key=kwargs.get('key'), order=1, page_id=dashboard.page_id, placeholder='_auto_tile') # only keep parameters that are actually defined for this cell type. cell_form_keys = [x['varname'] for x in settings.JSON_CELL_TYPES[cell.key].get('form') or {}] cell.parameters = {} request_body = json.loads(force_text(request.body)) for key in cell_form_keys: cell.parameters[key] = request_body.get(key) # save cell so it can be reused later, for example to be added to # dashboard, or to be used as reference in another page, etc. cell.save() response = render_cell(request, cell=cell) response['x-add-to-dashboard-url'] = reverse( 'combo-dashboard-add-tile', kwargs={'cell_reference': cell.get_reference()}) return response def dashboard_reorder_tiles(request, *args, **kwargs): dashboard = DashboardCell.objects.all()[0] new_order = request.GET['order'].split(',') tiles = dict((str(x.id), x) for x in Tile.objects.filter(id__in=new_order)) for i, tile_id in enumerate(new_order): tile = tiles.get(tile_id) if tile.user != request.user: raise PermissionDenied() if tile: tile.order = i for tile in tiles.values(): tile.save() return HttpResponse(status=204)