#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2010-2011 Étienne Loks # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # See the file COPYING for details. """ Furnitures views """ import csv import json import datetime from django.http import HttpResponse, Http404 from django.template import RequestContext from django.shortcuts import render_to_response, redirect from django.utils.translation import ugettext, ugettext_lazy as _ from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q from django.core import serializers from ishtar import settings from menus import menu import forms as ishtar_forms import models CSV_OPTIONS = {'delimiter':';', 'quotechar':'"', 'quoting':csv.QUOTE_ALL} ENCODING = settings.ENCODING or 'utf-8' def index(request): """ Main page """ dct = {} return render_to_response('index.html', dct, context_instance=RequestContext(request)) def update_current_item(request): if not request.is_ajax() and not request.method == 'POST': raise Http404 if 'value' in request.POST and 'item' in request.POST: request.session[request.POST['item']] = request.POST['value'] return HttpResponse('ok') def check_permission(request, action_slug, obj_id=None): if obj_id: return menu.items[action_slug].is_available(request.user, obj_id) return menu.items[action_slug].can_be_available(request.user) def autocomplete_person(request, person_type=None): if not request.user.has_perm('furnitures.view_person', models.Person) and \ not request.user.has_perm('furnitures.view_own_person', models.Person) : return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') q = request.GET.get('term') limit = request.GET.get('limit', 15) try: limit = int(limit) except ValueError: return HttpResponseBadRequest() query = Q() for q in q.split(' '): query = query & (Q(name__istartswith=q) | Q(surname__istartswith=q) | \ Q(email__icontains=q)) if person_type: try: typs = [int(tp) for tp in person_type.split('_') if tp] typ = models.PersonType.objects.filter(pk__in=typs).all() query = query & Q(person_type__in=typ) except (ValueError, ObjectDoesNotExist): pass limit = 15 persons = models.Person.objects.filter(query)[:limit] data = json.dumps([{'id':person.pk, 'value':unicode(person)} for person in persons if person]) return HttpResponse(data, mimetype='text/plain') def autocomplete_town(request): if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): extra = Q(name__icontains=q) if settings.COUNTRY == 'fr': extra = (extra | Q(numero_insee__istartswith=q) | \ Q(departement__label__istartswith=q)) query = query & extra limit = 15 towns = models.Town.objects.filter(query)[:limit] data = json.dumps([{'id':town.pk, 'value':unicode(town)} for town in towns]) return HttpResponse(data, mimetype='text/plain') def autocomplete_file(request): if not request.user.has_perm('furnitures.view_file', models.File) and \ not request.user.has_perm('furnitures.view_own_file', models.File) : return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): extra = Q(internal_reference__icontains=q) | \ Q(towns__name__icontains=q) try: value = int(q) extra = extra | Q(year=q) | Q(numeric_reference=q) except ValueError: pass query = query & extra limit = 15 files = models.File.objects.filter(query)[:limit] data = json.dumps([{'id':file.pk, 'value':unicode(file)} for file in files]) return HttpResponse(data, mimetype='text/plain') def get_item(model, func_name, default_name, extra_request_keys=[]): """ Generic treatment of tables """ def func(request, data_type='json', **dct): if not data_type: data_type = 'json' fields = [model._meta.get_field_by_name(k)[0] for k in model._meta.get_all_field_names()] request_keys = dict([(field.name, field.name + (hasattr(field, 'rel') and field.rel and '__pk' or '')) for field in fields]) request_keys.update(extra_request_keys) dct = {} for k in request_keys: q = request.GET.get(k) if not q: continue dct[request_keys[k]] = q if not dct and 'submited' not in request.GET: if default_name in request.session: dct = {"pk":request.session[default_name]} elif func_name in request.session: dct = request.session[func_name] if not dct: return HttpResponse(mimetype='text/plain') else: request.session[func_name] = dct query = Q(**dct) items = model.objects.filter(query) q = request.GET.get('sidx') if q and q in request_keys: k = request_keys[q] if k.endswith("__pk"): k = k[:-len("__pk")] + "__label" q = request.GET.get('sord') sign = q and q == u'desc' and "-" or '' items = items.order_by(sign + k) datas = [] for item in items: data = [item.pk] for k in model.TABLE_COLS: val = item for ky in k.split('.'): if val: val = getattr(val, ky) if hasattr(val, 'all'): # manage related objects data.append(", ".join([v and unicode(v) or u"" for v in getattr(val, 'all')()])) else: data.append(val and unicode(val) or u"") datas.append(data) if data_type == "json": rows = [] for data in datas: res = {'id':data[0]} for idx, value in enumerate(data[1:]): if value: res[model.TABLE_COLS[idx].split('.')[-1]] = value rows.append(res) data = json.dumps({ "records":len(items), "rows":rows }) return HttpResponse(data, mimetype='text/plain') elif data_type == "csv": response = HttpResponse(mimetype='text/csv') n = datetime.datetime.now() filename = u'%s_%s.csv' % (default_name, n.strftime('%Y%m%d-%H%M%S')) response['Content-Disposition'] = 'attachment; filename=%s'%filename writer = csv.writer(response, **CSV_OPTIONS) col_names = [] for field_name in model.TABLE_COLS: try: field = model._meta.get_field(field_name) except: col_names.append(u"".encode(ENCODING)) continue col_names.append(unicode(field.verbose_name).encode(ENCODING)) writer.writerow(col_names) for data in datas: writer.writerow([val.encode(ENCODING) for val in data[1:]]) return response return HttpResponse(None, mimetype='text/plain') return func get_file = get_item(models.File, 'get_file', 'file') def autocomplete_operation(request, non_closed=True): if not request.user.has_perm('furnitures.view_operation', models.Operation)\ and not request.user.has_perm('furnitures.view_own_operation', models.Operation): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): extra = Q(towns__name__icontains=q) try: value = int(q) extra = extra | Q(year=q) | Q(operation_code=q) except ValueError: pass query = query & extra if non_closed: query = query & Q(end_date__isnull=True) limit = 15 operations = models.Operation.objects.filter(query)[:limit] data = json.dumps([{'id':operation.pk, 'value':unicode(operation)} for operation in operations]) return HttpResponse(data, mimetype='text/plain') get_operation = get_item(models.Operation, 'get_operation', 'operation') get_administrativeact = get_item(models.AdministrativeAct, 'get_administrativeact', 'administrativeact', extra_request_keys={'associated_file__towns':'associated_file__towns__pk', 'operation__towns':'operation__towns__pk'}) def autocomplete_organization(request, orga_type=None): if not request.user.has_perm('furnitures.view_organization', models.Organization) and \ not request.user.has_perm('furnitures.view_own_organization', models.Organization): return HttpResponse(mimetype='text/plain') if not request.GET.get('term'): return HttpResponse(mimetype='text/plain') q = request.GET.get('term') query = Q() for q in q.split(' '): extra = Q(name__icontains=q) query = query & extra if orga_type: try: typs = [int(tp) for tp in orga_type.split('_') if tp] typ = models.OrganizationType.objects.filter(pk__in=typs).all() query = query & Q(organization_type__in=typ) except (ValueError, ObjectDoesNotExist): pass limit = 15 organizations = models.Organization.objects.filter(query)[:limit] data = json.dumps([{'id':org.pk, 'value':unicode(org)} for org in organizations]) return HttpResponse(data, mimetype='text/plain') def action(request, action_slug, obj_id=None, *args, **kwargs): """ Action management """ if not check_permission(request, action_slug, obj_id): not_permitted_msg = ugettext(u"Operation not permitted.") return HttpResponse(not_permitted_msg) request.session['CURRENT_ACTION'] = action_slug associated_wizard = action_slug + '_wizard' dct = {} globals_dct = globals() if action_slug in globals_dct: return globals_dct[action_slug](request, dct, obj_id, *args, **kwargs) elif hasattr(ishtar_forms, action_slug + "_wizard"): return getattr(ishtar_forms, action_slug+"_wizard")(request, *args, **kwargs) return render_to_response('index.html', dct, context_instance=RequestContext(request))